Byproduct Recovery Framework Tutorial#
The purpose of this tutorial is to introduce the byproduct recovery decision framework (hereafter referenced to as the framework), which is defined in determine_byproduct_recovery.py.The framework assesses the economic viability of converting waste streams into saleable byproducts based on a known viability criterion. This framework serves as a decision-support tool for determining whether specific byproducts should be recovered.
This tutorial gives an example of how to use the framework to determine if lithium and cobalt should be recovered from a diafiltration process. This framework can be generalized to other recoverable byproducts if appropriate pricing data is provided.
To evaluate byproduct recovery, annualized net benefit is assessed with the following equations:
Definitions of Variables:
material_productionₘ: Mass flow rate of recovered byproduct m (kg/yr).market_valueₘ: Market price of byproduct m (USD/kg).avoided_waste_disposal_costₘ: Avoided disposal cost for byproduct m (USD/kg).conversion_costₘ: Annualized cost (considering both CAPEX and OPEX) of the recovery process for byproduct m (USD/yr).conversion_possibleₘ: Binary indicator for whether conversion is required for byproduct m (1 = required, 0 = not required).added_process_costₘ: Annualized cost (considering both CAPEX and OPEX) of additional process units for recovering byproduct m (USD/yr).added_process_stepsₘ: Binary indicator for whether additional process units are required for recovering byproduct m (1 = required, 0 not required).
To use the byproduct recovery framework effectively, a byproduct recovery process with costing must already be constructed. To learn the basics of the REE Costing Framework, please refer to the tutorial on basic costing features in PrOMMiS. This is necessary to determine the annualized cost and annual revenue associated with recovery. Once the process model is built, users can import it—along with its corresponding cost and revenue—and apply the byproduct recovery framework to decide whether or not the byproduct should be recovered.
Learning Objectives: By the end of this tutorial, users will be able to:
Decide and import the necessary Python packages
Build a process flowsheet using a case study: lithium-cobalt recovery via diafiltration
Apply the byproduct recovery decision framework
Step 1: Import the Necessary Packages#
First, import the necessary Pyomo, IDAES, and PrOMMiS packages. These will be implemented at various stages throughout the tutorial.
Package Purposes:
Pyomo: Used for model construction and optimization.
IDAES: While not essential for this specific tutorial, IDAES models can support model testing and validation.
PrOMMiS:
prommis.nanofiltration.diafiltration: Used to build the lithium-cobalt diafiltration recovery process model.prommis.uky.costing.costing_dictionaries: Provides product pricing data.prommis.uky.costing.determine_byproduct_recovery: Implements the byproduct recovery decision framework.
For guidance on installing these packages, please refer to the Package Installation section at the end of the tutorial.
# Pyomo packages
from pyomo.environ import (
ConcreteModel,
Expression,
Param,
TransformationFactory,
Var,
value,
)
import pytest
# PrOMMiS packages
from prommis.nanofiltration.diafiltration import (
main,
add_costing,
add_objective,
add_product_constraints,
build_model,
initialize_model,
set_scaling,
solve_model,
unfix_opt_variables,
)
from prommis.uky.costing.costing_dictionaries import load_default_sale_prices
from prommis.uky.costing.determine_byproduct_recovery import (
ByproductRecovery,
)
Step 2: Building on the Pre-defined Diafiltration Process#
This section gives a brief introduction of how to build upon the pre-defined diafiltration process model. The lithium-cobalt diafiltration process is implemented in the file diafiltration.py, available in the PrOMMiS repository.
To construct a process flowsheet using this existing model, users can refer to the detailed walkthrough provided in the Multi_Stream Contactor Tutorial (Solution). This tutorial outlines the major steps for building the flowsheet.
To determine whether lithium and cobalt should be recovered, the user first needs to build the diafiltration process and access the cost and revenue.
Refer to the process model defined in diafiltration.py. Specifically, call the functions in the order specified within the main() function. Following this order is crucial because the diafiltration process consists of three membrane stages, and the model is built stage by stage.
During each stage of model building, initialization is performed with a set of variables fixed. When transitioning to the next stage, previously fixed variables must be unfixed, and new variables need to be fixed for the current stage. This sequential initialization ensures that the model is stable and properly configured at each membrane stage.
The production rates of lithium and cobalt from the diafiltration process are expressed in kilograms per hour (kg/hr). Assuming the plant operates 8,000 hours annually, the annual production of lithium and cobalt can be calculated by multiplying the hourly production rates by 8,000 hr/yr.
Note that the code may generate warnings related to volumetric flow being temporarily set to zero during initialization—values that fall outside the predefined variable bounds. These warnings do not affect model performance and can be safely ignored.
# Build and solve the model
m = build_model()
add_costing(m)
initialize_model(m)
solve_model(m)
unfix_opt_variables(m)
add_product_constraints(m, Li_recovery_bound=0.95, Co_recovery_bound=0.635)
add_objective(m)
set_scaling(m)
solve_model(m)
# Store results for later application in the framework
total_annualized_cost = value(m.fs.costing.total_annualized_cost)
# recovery mass flow rate annually: kg/hr * 8000 hr/yr
Li_recovery_mass = value(m.fs.stage3.permeate_outlet.flow_vol[0]) * value(
m.fs.stage3.permeate_outlet.conc_mass_solute[0, "Li"] * 8000
)
Co_recovery_mass = value(m.fs.stage1.retentate_outlet.flow_vol[0]) * value(
m.fs.stage1.retentate_outlet.conc_mass_solute[0, "Co"] * 8000
)
WARNING (W1002): Setting Var 'fs.stage1.permeate[0.0,1].flow_vol' to a numeric
value `0.0` outside the bounds (1e-08, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var 'fs.stage1.permeate[0.0,2].flow_vol' to a numeric
value `0.0` outside the bounds (1e-08, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var 'fs.stage1.permeate[0.0,3].flow_vol' to a numeric
value `0.0` outside the bounds (1e-08, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var 'fs.stage1.permeate[0.0,4].flow_vol' to a numeric
value `0.0` outside the bounds (1e-08, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var 'fs.stage1.permeate[0.0,5].flow_vol' to a numeric
value `0.0` outside the bounds (1e-08, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var 'fs.stage1.permeate[0.0,6].flow_vol' to a numeric
value `0.0` outside the bounds (1e-08, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var 'fs.stage1.permeate[0.0,7].flow_vol' to a numeric
value `0.0` outside the bounds (1e-08, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var 'fs.stage1.permeate[0.0,8].flow_vol' to a numeric
value `0.0` outside the bounds (1e-08, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var 'fs.stage1.permeate[0.0,9].flow_vol' to a numeric
value `0.0` outside the bounds (1e-08, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var 'fs.stage1.permeate[0.0,10].flow_vol' to a
numeric value `0.0` outside the bounds (1e-08, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
2025-12-08 13:25:09 [INFO] idaes.init.fs.stage1: Stream Initialization Completed.
2025-12-08 13:25:09 [INFO] idaes.init.fs.stage1: Initialization Completed, optimal - <undefined>
2025-12-08 13:25:10 [INFO] idaes.init.fs.mix1: Initialization Complete: optimal - <undefined>
WARNING (W1002): Setting Var 'fs.stage2.permeate[0.0,1].flow_vol' to a numeric
value `0.0` outside the bounds (1e-08, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var 'fs.stage2.permeate[0.0,2].flow_vol' to a numeric
value `0.0` outside the bounds (1e-08, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var 'fs.stage2.permeate[0.0,3].flow_vol' to a numeric
value `0.0` outside the bounds (1e-08, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var 'fs.stage2.permeate[0.0,4].flow_vol' to a numeric
value `0.0` outside the bounds (1e-08, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var 'fs.stage2.permeate[0.0,5].flow_vol' to a numeric
value `0.0` outside the bounds (1e-08, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var 'fs.stage2.permeate[0.0,6].flow_vol' to a numeric
value `0.0` outside the bounds (1e-08, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var 'fs.stage2.permeate[0.0,7].flow_vol' to a numeric
value `0.0` outside the bounds (1e-08, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var 'fs.stage2.permeate[0.0,8].flow_vol' to a numeric
value `0.0` outside the bounds (1e-08, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var 'fs.stage2.permeate[0.0,9].flow_vol' to a numeric
value `0.0` outside the bounds (1e-08, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var 'fs.stage2.permeate[0.0,10].flow_vol' to a
numeric value `0.0` outside the bounds (1e-08, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
2025-12-08 13:25:10 [INFO] idaes.init.fs.stage2: Stream Initialization Completed.
2025-12-08 13:25:10 [INFO] idaes.init.fs.stage2: Initialization Completed, optimal - <undefined>
2025-12-08 13:25:10 [INFO] idaes.init.fs.mix2: Initialization Complete: optimal - <undefined>
WARNING (W1002): Setting Var 'fs.stage3.permeate[0.0,1].flow_vol' to a numeric
value `0.0` outside the bounds (1e-08, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var 'fs.stage3.permeate[0.0,2].flow_vol' to a numeric
value `0.0` outside the bounds (1e-08, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var 'fs.stage3.permeate[0.0,3].flow_vol' to a numeric
value `0.0` outside the bounds (1e-08, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var 'fs.stage3.permeate[0.0,4].flow_vol' to a numeric
value `0.0` outside the bounds (1e-08, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var 'fs.stage3.permeate[0.0,5].flow_vol' to a numeric
value `0.0` outside the bounds (1e-08, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var 'fs.stage3.permeate[0.0,6].flow_vol' to a numeric
value `0.0` outside the bounds (1e-08, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var 'fs.stage3.permeate[0.0,7].flow_vol' to a numeric
value `0.0` outside the bounds (1e-08, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var 'fs.stage3.permeate[0.0,8].flow_vol' to a numeric
value `0.0` outside the bounds (1e-08, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var 'fs.stage3.permeate[0.0,9].flow_vol' to a numeric
value `0.0` outside the bounds (1e-08, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var 'fs.stage3.permeate[0.0,10].flow_vol' to a
numeric value `0.0` outside the bounds (1e-08, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
2025-12-08 13:25:10 [INFO] idaes.init.fs.stage3: Stream Initialization Completed.
2025-12-08 13:25:10 [INFO] idaes.init.fs.stage3: Initialization Completed, optimal - <undefined>
2025-12-08 13:25:10 [INFO] idaes.init.fs.stage3: Stream Initialization Completed.
2025-12-08 13:25:10 [INFO] idaes.init.fs.stage3: Initialization Completed, optimal - <undefined>
Ipopt 3.13.2: max_iter=3000
******************************************************************************
This program contains Ipopt, a library for large-scale nonlinear optimization.
Ipopt is released as open source code under the Eclipse Public License (EPL).
For more information visit http://projects.coin-or.org/Ipopt
This version of Ipopt was compiled from source code available at
https://github.com/IDAES/Ipopt as part of the Institute for the Design of
Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE
Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.
This version of Ipopt was compiled using HSL, a collection of Fortran codes
for large-scale scientific computation. All technical papers, sales and
publicity material resulting from use of the HSL codes within IPOPT must
contain the following acknowledgement:
HSL, a collection of Fortran codes for large-scale scientific
computation. See http://www.hsl.rl.ac.uk.
******************************************************************************
This is Ipopt version 3.13.2, running with linear solver ma27.
Number of nonzeros in equality constraint Jacobian...: 1154
Number of nonzeros in inequality constraint Jacobian.: 0
Number of nonzeros in Lagrangian Hessian.............: 239
Total number of variables............................: 320
variables with only lower bounds: 225
variables with lower and upper bounds: 0
variables with only upper bounds: 0
Total number of equality constraints.................: 320
Total number of inequality constraints...............: 0
inequality constraints with only lower bounds: 0
inequality constraints with lower and upper bounds: 0
inequality constraints with only upper bounds: 0
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
0 0.0000000e+00 3.00e+05 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0
1 0.0000000e+00 4.72e+03 3.23e+07 -1.0 1.43e+05 - 9.43e-05 9.90e-01f 1
2 0.0000000e+00 4.77e+01 3.12e+03 -1.0 5.76e+03 - 9.38e-01 9.90e-01h 1
3 0.0000000e+00 4.61e-01 1.82e+00 -1.0 5.81e+01 - 9.90e-01 9.90e-01h 1
4 0.0000000e+00 4.39e-09 5.09e+01 -1.0 5.61e-01 - 9.91e-01 1.00e+00h 1
Number of Iterations....: 4
(scaled) (unscaled)
Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00
Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00
Constraint violation....: 4.2942195345314488e-10 4.3946783989667892e-09
Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00
Overall NLP error.......: 4.2942195345314488e-10 4.3946783989667892e-09
Number of objective function evaluations = 5
Number of objective gradient evaluations = 5
Number of equality constraint evaluations = 5
Number of inequality constraint evaluations = 0
Number of equality constraint Jacobian evaluations = 5
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations = 4
Total CPU secs in IPOPT (w/o function evaluations) = 0.000
Total CPU secs in NLP function evaluations = 0.000
EXIT: Optimal Solution Found.
Ipopt 3.13.2: max_iter=3000
******************************************************************************
This program contains Ipopt, a library for large-scale nonlinear optimization.
Ipopt is released as open source code under the Eclipse Public License (EPL).
For more information visit http://projects.coin-or.org/Ipopt
This version of Ipopt was compiled from source code available at
https://github.com/IDAES/Ipopt as part of the Institute for the Design of
Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE
Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.
This version of Ipopt was compiled using HSL, a collection of Fortran codes
for large-scale scientific computation. All technical papers, sales and
publicity material resulting from use of the HSL codes within IPOPT must
contain the following acknowledgement:
HSL, a collection of Fortran codes for large-scale scientific
computation. See http://www.hsl.rl.ac.uk.
******************************************************************************
This is Ipopt version 3.13.2, running with linear solver ma27.
Number of nonzeros in equality constraint Jacobian...: 1187
Number of nonzeros in inequality constraint Jacobian.: 4
Number of nonzeros in Lagrangian Hessian.............: 240
Total number of variables............................: 323
variables with only lower bounds: 225
variables with lower and upper bounds: 0
variables with only upper bounds: 0
Total number of equality constraints.................: 320
Total number of inequality constraints...............: 2
inequality constraints with only lower bounds: 2
inequality constraints with lower and upper bounds: 0
inequality constraints with only upper bounds: 0
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
0 1.4888929e+05 3.41e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0
1 1.4887439e+05 3.37e+01 7.70e+01 -1.0 5.16e+03 - 7.35e-01 1.03e-02f 1
2 1.4887444e+05 3.37e+01 1.38e+05 -1.0 3.70e+03 - 1.89e-01 1.06e-04h 1
3 1.4921075e+05 1.11e+05 1.38e+05 -1.0 4.26e+05 - 3.45e-03 3.45e-03s 14
4 1.4642633e+05 1.11e+05 7.46e+05 -1.0 7.31e+06 - 2.90e-03 0.00e+00S 14
5 1.4642734e+05 1.11e+05 8.00e+05 -1.0 3.08e+06 - 1.89e-03 5.26e-05h 1
6 1.4647440e+05 1.11e+05 8.47e+05 -1.0 3.21e+06 - 1.87e-03 7.45e-05h 5
7 1.4654239e+05 1.11e+05 9.07e+05 -1.0 3.22e+06 - 2.52e-03 1.07e-04h 6
8 1.4660752e+05 1.11e+05 9.85e+05 -1.0 3.24e+06 - 3.44e-03 1.02e-04h 7
9 1.4666297e+05 1.11e+05 1.09e+06 -1.0 3.26e+06 - 4.98e-03 8.62e-05h 8
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
10 1.4670926e+05 1.11e+05 1.24e+06 -1.0 3.27e+06 - 8.18e-03 7.16e-05h 9
11 1.4679193e+05 1.11e+05 1.28e+06 -1.0 3.28e+06 - 3.18e-03 1.27e-04h 9
12 1.4683964e+05 1.11e+05 1.44e+06 -1.0 3.31e+06 - 1.28e-02 7.29e-05h 10
13 1.4688175e+05 1.11e+05 1.47e+06 -1.0 3.32e+06 - 2.99e-03 6.40e-05h 11
14 1.4692761e+05 1.11e+05 1.69e+06 -1.0 3.33e+06 - 2.99e-02 6.95e-05h 11
15 1.4489278e+05 1.11e+05 1.68e+06 -1.0 3.34e+06 - 1.64e-03 5.97e-04H 1
16 1.4506504e+05 1.11e+05 1.68e+06 -1.0 2.78e+06 - 3.14e-05 3.21e-04h 4
17 1.4530663e+05 1.11e+05 1.69e+06 -1.0 2.82e+06 - 1.40e-03 4.43e-04h 9
18 1.4551152e+05 1.11e+05 1.69e+06 -1.0 2.88e+06 - 1.15e-03 3.67e-04h 7
19 1.4576268e+05 1.11e+05 1.69e+06 -1.0 2.93e+06 - 6.58e-03 4.41e-04h 8
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
20 1.4599634e+05 1.11e+05 1.69e+06 -1.0 2.99e+06 - 1.83e-03 4.01e-04h 9
21 1.4632019e+05 1.11e+05 1.72e+06 -1.0 3.05e+06 - 3.46e-02 5.43e-04h 9
22 1.4479963e+05 1.11e+05 1.71e+06 -1.0 3.13e+06 - 2.05e-03 4.78e-04H 1
23 1.4484987e+05 1.11e+05 1.71e+06 -1.0 2.76e+06 - 5.56e-05 9.48e-05h 8
24 1.4488931e+05 1.11e+05 1.71e+06 -1.0 2.77e+06 - 4.91e-04 7.40e-05h 9
25 1.4489582e+05 1.11e+05 1.71e+06 -1.0 2.78e+06 - 2.84e-04 1.22e-05h 12
26 1.4613849e+05 1.11e+05 1.70e+06 -1.0 2.78e+06 - 2.32e-03 2.32e-03s 17
27 1.4823329e+05 1.10e+05 1.70e+06 -1.0 3.04e+06 - 3.53e-03 3.53e-03s 17
28 1.6057594e+05 1.08e+05 1.67e+06 -1.0 3.46e+06 - 1.80e-02 1.80e-02s 17
29 1.7357458e+05 1.06e+05 1.63e+06 -1.0 3.29e+06 - 2.05e-02 2.05e-02s 17
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
30 1.7369354e+05 1.06e+05 1.63e+06 -1.0 3.24e+06 - 1.94e-04 1.94e-04s 17
31r 1.7369354e+05 1.06e+05 1.00e+03 2.5 0.00e+00 - 0.00e+00 0.00e+00R 1
32r 1.7353106e+05 1.06e+05 2.91e+04 2.5 4.12e+05 - 6.33e-03 4.34e-03f 1
33r 1.7352190e+05 1.06e+05 2.90e+04 2.5 5.62e+03 - 1.05e-01 2.73e-03f 1
34r 1.7321001e+05 8.24e+04 2.58e+04 2.5 3.12e+03 - 1.37e-03 1.13e-01f 1
35r 1.7317652e+05 6.19e+03 2.48e+04 2.5 9.27e+03 - 2.35e-01 4.14e-02f 1
36r 1.7313413e+05 7.39e+03 2.42e+04 2.5 1.94e+03 - 3.79e-01 2.34e-02f 1
37r 1.7317813e+05 1.00e+04 3.74e+04 2.5 4.08e+02 - 1.00e+00 1.09e-01f 1
38r 1.7384384e+05 5.71e+03 2.10e+04 2.5 1.59e+03 - 2.85e-01 4.29e-01f 1
39r 1.7334485e+05 6.62e+01 3.53e+03 2.5 5.28e+02 - 1.00e+00 1.00e+00f 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
40r 1.7356518e+05 8.35e+00 1.75e+03 1.8 4.90e+02 - 1.00e+00 5.56e-01f 1
41r 1.7416704e+05 1.75e+01 2.62e+03 1.1 9.68e+02 - 1.00e+00 6.67e-01f 1
42r 1.7530786e+05 5.32e+00 5.71e+03 1.1 1.75e+03 - 1.00e+00 6.81e-01f 1
43r 1.7583931e+05 3.57e+00 4.60e+01 1.1 5.54e+02 - 1.00e+00 1.00e+00f 1
44r 1.7585805e+05 1.32e+00 2.36e+03 -0.3 4.29e+01 - 1.00e+00 6.90e-01f 1
45r 1.8185926e+05 6.12e+02 2.57e+03 -0.3 1.15e+04 - 7.75e-01 5.54e-01f 1
46r 1.8190967e+05 6.04e+02 4.36e+03 -0.3 4.29e+03 - 1.00e+00 1.26e-02f 1
47r 1.8160397e+05 2.33e+01 5.21e+01 -0.3 3.31e+02 - 1.00e+00 1.00e+00f 1
48 1.8159886e+05 2.33e+01 1.14e+03 -1.0 3.79e+04 - 6.08e-01 5.83e-04f 1
49 1.8162061e+05 8.95e+01 1.14e+03 -1.0 1.23e+05 - 7.41e-04 7.41e-04s 12
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
50 1.8242765e+05 1.06e+05 1.11e+03 -1.0 1.23e+05 - 3.01e-02 3.01e-02s 12
51 1.7462529e+05 1.06e+05 1.10e+03 -1.0 1.46e+06 - 5.88e-03 5.88e-03s 12
52r 1.7462529e+05 1.06e+05 1.00e+03 2.1 0.00e+00 - 0.00e+00 0.00e+00R 1
53r 1.7454386e+05 5.23e+04 5.80e+03 2.1 4.75e+03 - 8.11e-05 1.84e-02f 1
54r 1.7453172e+05 9.65e+01 6.79e+04 2.1 1.11e+04 - 4.12e-01 6.14e-03f 1
55r 1.7455216e+05 5.71e+02 7.93e+03 2.1 2.38e+02 - 9.92e-01 8.17e-02f 1
56r 1.7488245e+05 8.70e+01 1.17e+04 2.1 3.80e+02 - 6.54e-01 8.47e-01f 1
57r 1.7492871e+05 1.18e+01 1.22e+00 2.1 5.57e+01 - 1.00e+00 1.00e+00f 1
58r 1.7494729e+05 4.60e+00 2.86e+03 0.0 8.34e+01 - 9.95e-01 7.06e-01f 1
59r 1.7689159e+05 9.38e+00 1.09e+04 0.0 3.82e+03 - 9.06e-01 5.31e-01f 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
60r 1.7800875e+05 4.16e+00 6.18e+03 0.0 1.78e+03 - 1.00e+00 6.47e-01f 1
61r 1.7861669e+05 8.15e-01 4.62e+01 0.0 6.39e+02 - 1.00e+00 1.00e+00f 1
62 1.7850768e+05 1.01e+02 1.55e+02 -1.0 8.74e+04 - 5.27e-02 1.98e-03f 6
63 1.7840496e+05 2.01e+02 1.54e+02 -1.0 1.76e+05 - 1.65e-03 1.17e-03f 6
64 1.7835224e+05 2.26e+02 1.58e+02 -1.0 2.14e+05 - 3.31e-02 5.12e-04f 7
65 1.7829760e+05 2.51e+02 1.58e+02 -1.0 1.92e+05 - 4.48e-03 5.67e-04f 7
66 1.7824184e+05 2.76e+02 1.63e+02 -1.0 1.91e+05 - 4.24e-02 5.79e-04f 7
67 1.7444361e+05 1.02e+05 3.08e+02 -1.0 1.44e+05 - 8.61e-03 4.72e-02f 1
68 1.7087847e+05 1.01e+05 2.32e+02 -1.0 2.65e+05 - 7.36e-01 1.36e-02f 1
69 1.6787255e+05 9.88e+04 2.59e+03 -1.0 1.55e+05 - 9.90e-01 2.28e-02f 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
70 1.6784879e+05 9.88e+04 4.70e+05 -1.0 9.89e+04 - 8.76e-01 2.62e-04f 1
71 1.5444610e+05 8.87e+04 4.22e+05 -1.0 1.47e+06 - 6.12e-02 1.02e-01H 1
72 1.6328721e+05 8.12e+04 3.46e+05 -1.0 8.45e+05 - 1.61e-03 8.44e-02h 3
73 1.6573611e+05 7.99e+04 3.90e+05 -1.0 1.04e+06 - 1.46e-01 1.58e-02h 5
74 1.6697581e+05 7.93e+04 4.37e+05 -1.0 1.09e+06 - 1.63e-01 7.51e-03h 6
75 1.6758524e+05 7.91e+04 4.90e+05 -1.0 1.11e+06 - 2.00e-01 3.58e-03h 7
76 1.6773701e+05 7.90e+04 5.26e+05 -1.0 1.11e+06 - 1.63e-01 8.78e-04h 9
77 1.7166961e+05 7.73e+04 5.13e+05 -1.0 1.04e+06 - 8.50e-03 2.09e-02h 1
78 2.1078104e+05 6.12e+04 3.59e+05 -1.0 1.14e+06 - 1.71e-03 2.08e-01h 1
79 2.1262940e+05 6.07e+04 5.40e+05 -1.0 1.16e+06 - 3.34e-01 8.75e-03h 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
80 2.1272765e+05 6.07e+04 6.52e+05 -1.0 1.03e+06 - 1.04e-01 4.70e-04h 1
81 2.2415572e+05 5.73e+04 1.06e+06 -1.0 1.00e+06 - 4.40e-01 5.50e-02h 2
82 2.3463562e+05 5.45e+04 9.41e+05 -1.0 1.09e+06 - 1.94e-01 4.89e-02h 5
83 2.4825352e+05 5.11e+04 7.95e+05 -1.0 1.17e+06 - 3.09e-01 6.19e-02h 5
84 2.6876009e+05 4.89e+04 8.04e+05 -1.0 1.30e+06 - 1.11e-03 4.48e-02H 1
85 2.7743158e+05 4.70e+04 7.44e+05 -1.0 1.21e+06 - 1.67e-04 3.80e-02h 1
86 2.9957072e+05 4.25e+04 5.78e+05 -1.0 1.25e+06 - 8.33e-03 9.65e-02h 3
87 3.5341744e+05 3.10e+04 3.18e+05 -1.0 1.08e+06 - 3.61e-02 2.69e-01H 1
88 3.5845191e+05 2.65e+04 2.92e+05 -1.0 2.14e+05 - 1.97e-01 1.45e-01h 1
89 1.5088996e+05 1.12e+04 1.89e+06 -1.0 1.06e+06 - 1.31e-01 5.79e-01F 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
90 1.2557077e+05 1.04e+04 1.97e+06 -1.0 1.82e+06 - 4.03e-02 6.79e-02f 1
91 1.2509047e+05 1.04e+04 1.98e+06 -1.0 1.37e+06 - 4.54e-06 1.19e-03f 1
92 1.2526481e+05 1.04e+04 1.98e+06 -1.0 1.09e+05 - 1.56e-04 1.55e-03h 1
93 1.2527575e+05 1.04e+04 1.98e+06 -1.0 1.11e+05 - 2.43e-03 9.54e-05h 1
94 1.2530792e+05 1.04e+04 1.97e+06 -1.0 1.65e+05 - 2.96e-03 2.41e-04h 1
95 1.2590033e+05 1.03e+04 1.97e+06 -1.0 1.33e+05 - 4.26e-03 4.70e-03h 1
96 1.2605799e+05 1.03e+04 1.96e+06 -1.0 1.31e+05 - 9.38e-05 1.26e-03h 1
97 1.2887468e+05 1.01e+04 1.92e+06 -1.0 1.14e+05 - 2.13e-03 2.36e-02h 1
98 1.2905784e+05 1.01e+04 1.91e+06 -1.0 1.21e+05 - 5.99e-03 1.52e-03h 1
99 1.3651965e+05 9.39e+03 2.63e+06 -1.0 1.18e+05 - 2.53e-03 6.23e-02h 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
100 1.3858118e+05 9.21e+03 2.57e+06 -1.0 1.06e+05 - 1.18e-02 1.87e-02h 1
101 1.4296639e+05 8.82e+03 2.48e+06 -1.0 1.05e+05 - 4.56e-02 4.03e-02h 1
102 1.4301087e+05 8.82e+03 3.01e+06 -1.0 1.02e+05 - 2.26e-01 4.22e-04h 1
103 1.4301009e+05 8.82e+03 9.94e+06 -1.0 7.10e+05 - 3.25e-02 1.03e-05f 1
104 1.3902004e+05 8.64e+03 2.83e+06 -1.0 1.28e+06 - 1.90e-04 1.97e-02f 1
105 1.4219397e+05 8.44e+03 5.25e+06 -1.0 2.09e+05 - 3.44e-06 2.24e-02h 1
106 1.4889658e+05 8.07e+03 8.87e+06 -1.0 2.55e+05 - 2.97e-02 4.45e-02h 1
107 1.6098257e+05 7.60e+03 1.48e+07 -1.0 4.67e+05 - 8.93e-02 6.10e-02h 1
108 1.5780383e+05 7.49e+03 1.90e+08 -1.0 1.32e+06 - 4.01e-02 1.37e-02f 1
109r 1.5780383e+05 7.49e+03 1.00e+03 3.3 0.00e+00 - 0.00e+00 3.65e-07R 7
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
110r 1.5764509e+05 7.13e+03 6.40e+04 3.3 2.80e+05 - 2.44e-02 8.87e-03f 1
111 1.5795418e+05 6.98e+03 5.77e+01 -1.0 5.38e+04 - 2.48e-02 2.10e-02h 1
112 1.5797208e+05 6.98e+03 1.83e+02 -1.0 5.27e+04 - 2.40e-02 3.19e-04h 1
113 1.5803844e+05 6.97e+03 6.56e+04 -1.0 8.97e+04 - 2.58e-01 9.43e-04h 1
114 1.6678352e+05 6.34e+03 5.91e+04 -1.0 8.97e+04 - 2.93e-01 1.28e-01h 1
115 1.6686395e+05 6.33e+03 5.26e+04 -1.0 7.60e+04 - 1.21e-01 1.43e-03h 1
116 1.6687203e+05 6.33e+03 7.26e+04 -1.0 1.73e+05 - 3.17e-03 6.78e-05h 1
117 1.6700141e+05 6.32e+03 7.25e+04 -1.0 1.96e+05 - 1.26e-03 1.27e-03h 2
118 1.6706516e+05 6.32e+03 6.94e+04 -1.0 6.20e+05 - 8.17e-04 3.82e-04h 3
119 1.6715642e+05 6.32e+03 5.59e+04 -1.0 1.07e+06 - 2.19e-03 3.29e-04h 3
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
120 1.6722665e+05 6.31e+03 5.47e+04 -1.0 2.15e+06 - 5.94e-04 1.22e-04h 4
121 1.6723902e+05 6.31e+03 2.59e+05 -1.0 5.25e+05 - 1.34e-02 4.99e-05h 1
122 1.6746665e+05 6.31e+03 5.47e+05 -1.0 4.81e+05 - 2.38e-02 1.12e-03h 5
123 1.6758171e+05 6.30e+03 9.82e+05 -1.0 4.30e+05 - 5.19e-02 7.44e-04h 6
124 1.6758728e+05 6.30e+03 1.06e+06 -1.0 4.45e+05 - 5.86e-02 3.44e-05h 11
125 1.6758993e+05 6.30e+03 1.08e+06 -1.0 4.45e+05 - 5.87e-02 1.64e-05h 12
126 1.7294320e+05 6.09e+03 1.04e+06 -1.0 4.45e+05 - 3.32e-02 3.32e-02s 18
127r 1.7294320e+05 6.09e+03 1.00e+03 3.0 0.00e+00 -2.0 0.00e+00 0.00e+00R 1
128r 1.7267703e+05 5.50e+03 4.72e+03 3.0 3.33e+05 - 2.62e-02 1.25e-02f 1
129 1.7687213e+05 5.11e+03 8.55e+01 -1.0 6.24e+04 - 2.13e-01 6.74e-02h 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
130 1.7694922e+05 5.11e+03 8.20e+02 -1.0 6.15e+04 - 1.80e-01 1.42e-03h 1
131 1.8092837e+05 4.77e+03 1.06e+04 -1.0 6.78e+04 - 4.46e-01 7.95e-02h 1
132 1.8096502e+05 4.77e+03 6.86e+03 -1.0 6.13e+04 - 3.32e-01 8.57e-04h 1
133 1.8122654e+05 4.76e+03 1.01e+05 -1.0 2.25e+05 - 2.87e-02 2.46e-03h 1
134 1.8564136e+05 4.57e+03 3.25e+05 -1.0 2.32e+05 - 1.15e-01 4.09e-02h 1
135 1.9516155e+05 4.20e+03 4.74e+05 -1.0 2.77e+05 - 1.57e-01 8.22e-02h 4
136 1.9828459e+05 4.13e+03 1.88e+06 -1.0 5.69e+05 - 1.16e-01 1.75e-02h 3
137 2.0093231e+05 4.09e+03 6.58e+06 -1.0 9.72e+05 - 8.19e-02 9.73e-03h 3
138 2.0126541e+05 4.09e+03 1.57e+07 -1.0 4.72e+06 - 3.00e-03 2.89e-04h 4
139 2.0142056e+05 4.09e+03 1.52e+08 -1.0 1.31e+07 - 3.11e-03 4.97e-05h 4
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
140r 2.0142056e+05 4.09e+03 1.00e+03 1.4 0.00e+00 - 0.00e+00 3.37e-07R 7
141r 2.0142218e+05 2.98e+03 1.00e+03 1.4 1.88e+04 - 2.87e-03 1.24e-03f 1
142 2.0143358e+05 2.98e+03 1.73e+02 -1.0 4.31e+04 - 2.86e-02 3.56e-04h 1
143 2.0144628e+05 2.97e+03 1.11e+04 -1.0 5.29e+04 - 3.73e-02 4.22e-04h 1
144 2.0152748e+05 2.97e+03 2.84e+06 -1.0 2.84e+05 - 2.43e-01 7.81e-04h 1
145 2.0619341e+05 2.85e+03 2.47e+06 -1.0 3.09e+05 - 2.37e-01 4.00e-02h 4
146 2.0951386e+05 2.78e+03 2.46e+06 -1.0 3.53e+05 - 2.36e-01 2.65e-02h 6
147 2.1391754e+05 2.69e+03 2.52e+06 -1.0 3.93e+05 - 9.31e-02 3.29e-02h 5
148 2.1601572e+05 2.65e+03 2.80e+06 -1.0 4.91e+05 - 4.04e-02 1.34e-02h 4
149 2.1800279e+05 2.62e+03 6.65e+06 -1.0 6.18e+05 - 1.24e-01 1.07e-02h 4
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
150 2.1911794e+05 2.61e+03 1.20e+07 -1.0 1.09e+06 - 2.58e-02 3.73e-03h 4
151 2.1921110e+05 2.61e+03 2.22e+08 -1.0 7.05e+06 - 6.58e-03 5.31e-05h 4
152r 2.1921110e+05 2.61e+03 1.00e+03 0.8 0.00e+00 - 0.00e+00 3.47e-07R 9
153r 2.1920807e+05 1.05e+03 9.97e+02 0.8 3.12e+04 - 2.84e-03 1.09e-03f 1
154 2.1920994e+05 1.05e+03 8.77e+02 -1.0 6.13e+04 - 3.70e-02 1.09e-04h 1
155 2.1921866e+05 1.04e+03 2.86e+04 -1.0 7.02e+04 - 6.17e-02 4.80e-04h 1
156 2.1935917e+05 1.04e+03 1.88e+05 -1.0 1.89e+05 - 9.20e-03 1.34e-03h 1
157 2.2047205e+05 1.03e+03 5.99e+05 -1.0 2.97e+05 - 2.24e-02 9.35e-03h 1
158 2.2322883e+05 1.00e+03 1.06e+07 -1.0 2.29e+05 - 3.85e-01 3.16e-02h 2
159 2.2786400e+05 9.50e+02 1.01e+07 -1.0 1.87e+05 - 4.84e-02 5.42e-02h 2
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
160 2.3657417e+05 8.52e+02 4.64e+06 -1.0 1.58e+05 - 4.59e-01 1.15e-01h 4
161 2.5533866e+05 6.96e+02 5.06e+06 -1.0 1.04e+05 - 1.07e-01 2.98e-01h 2
162 2.7232586e+05 4.73e+01 1.09e+08 -1.0 2.36e+04 -2.5 3.03e-02 7.62e-01h 1
163 2.6900408e+05 5.89e+01 1.02e+08 -1.0 3.09e+05 -3.0 6.59e-05 6.98e-02f 1
164 2.6900426e+05 5.89e+01 4.73e+08 -1.0 5.04e+03 2.0 4.86e-02 3.68e-05h 1
165 2.6909458e+05 5.78e+01 8.01e+09 -1.0 5.13e+03 1.5 8.94e-01 1.88e-02h 1
166 2.6909495e+05 5.78e+01 9.26e+09 -1.0 2.37e+04 1.0 1.40e-02 1.98e-04h 1
167r 2.6909495e+05 5.78e+01 1.00e+03 1.0 0.00e+00 1.5 0.00e+00 2.63e-07R 4
168r 2.6909238e+05 5.72e+01 9.98e+02 1.0 4.35e+04 - 1.50e-03 1.19e-03f 1
169 2.6909001e+05 5.72e+01 1.28e+01 -1.0 1.10e+05 - 6.92e-04 9.10e-05f 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
170 2.6908843e+05 5.72e+01 8.01e+03 -1.0 5.35e+04 - 3.86e-02 2.57e-04f 1
171 2.6909676e+05 5.72e+01 5.63e+04 -1.0 8.96e+04 - 2.97e-02 3.43e-04h 1
172 2.6981660e+05 5.56e+01 1.11e+06 -1.0 9.26e+04 - 6.95e-01 2.75e-02h 1
173 2.6981668e+05 5.56e+01 4.78e+08 -1.0 5.26e+03 1.0 5.79e-03 1.38e-05h 1
174r 2.6981668e+05 5.56e+01 1.00e+03 0.7 0.00e+00 0.5 0.00e+00 4.56e-07R 10
175r 2.6981543e+05 5.36e+01 1.01e+03 0.7 7.75e+03 - 1.43e-03 2.48e-03f 1
176 2.6981276e+05 5.36e+01 1.42e+01 -1.0 1.11e+05 - 8.35e-04 1.00e-04f 1
177 2.6981158e+05 5.36e+01 1.49e+05 -1.0 5.11e+04 - 6.29e-01 2.92e-04f 1
178 2.7002156e+05 5.32e+01 2.73e+05 -1.0 9.73e+04 - 1.08e-01 7.32e-03h 1
179 2.7648347e+05 3.97e+01 7.02e+05 -1.0 9.69e+04 - 6.95e-01 2.24e-01H 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
180 3.0483323e+05 6.63e+00 4.37e+05 -1.0 8.30e+04 - 1.18e-01 1.00e+00H 1
181 3.0179103e+05 3.87e+00 1.38e+05 -1.0 1.38e+04 - 6.84e-01 1.00e+00f 1
182 2.9676419e+05 4.28e+00 3.17e+04 -1.0 2.30e+04 - 5.96e-01 1.00e+00f 1
183 2.9580476e+05 5.30e+00 1.68e+05 -1.0 4.92e+04 - 9.55e-01 9.53e-02f 4
184 2.9471482e+05 6.43e+00 1.53e+05 -1.0 4.80e+04 - 3.22e-01 1.13e-01f 4
185 2.9356666e+05 7.44e+00 1.62e+05 -1.0 4.71e+04 - 9.59e-01 1.25e-01f 4
186 2.9248608e+05 8.06e+00 1.47e+05 -1.0 4.59e+04 - 3.97e-01 1.25e-01f 4
187 2.9148465e+05 8.35e+00 1.55e+05 -1.0 4.40e+04 - 1.00e+00 1.25e-01f 4
188 2.8411311e+05 6.68e+01 5.02e+04 -1.0 4.19e+04 - 5.18e-01 1.00e+00f 1
189 2.8411315e+05 6.68e+01 1.45e+10 -1.0 1.71e+03 0.0 1.00e+00 7.58e-05h 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
190 2.8431586e+05 6.69e+01 1.40e+10 -1.0 8.59e+05 - 2.95e-02 2.18e-03h 6
191 2.8550182e+05 6.77e+01 8.69e+09 -1.0 2.14e+05 - 3.81e-01 4.32e-02h 4
192 2.9244683e+05 5.69e+01 6.37e+08 -1.0 7.96e+04 - 9.27e-01 5.00e-01h 2
193 2.8933019e+05 9.78e+00 4.78e+10 -1.0 1.85e+04 -0.4 1.21e-02 1.00e+00f 1
194 2.8932087e+05 9.77e+00 4.77e+10 -1.0 2.32e+05 -0.9 6.56e-03 3.14e-04f 1
195 2.8669790e+05 1.20e+01 1.16e+10 -1.0 1.27e+04 -0.5 4.52e-05 1.00e+00f 1
196 2.8659568e+05 1.73e-01 2.41e+07 -1.0 5.32e+02 -1.0 8.33e-01 1.00e+00f 1
197 2.8659422e+05 2.82e-05 1.55e+04 -1.0 4.07e+00 -1.5 9.71e-01 1.00e+00f 1
198 2.8658968e+05 4.41e-05 1.74e+03 -1.0 1.33e+01 -1.9 7.52e-01 1.00e+00f 1
199 2.8657518e+05 1.01e-02 2.72e-01 -1.0 4.54e+01 -2.4 1.00e+00 1.00e+00f 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
200 2.8289737e+05 2.81e+00 1.83e+03 -1.0 2.38e+07 - 1.43e-02 5.60e-04f 1
201 2.8281029e+05 2.81e+00 1.68e+05 -1.0 1.41e+06 - 1.68e-01 7.93e-04f 1
202 2.8006701e+05 1.41e+02 3.59e+05 -1.0 1.19e+06 - 2.95e-01 5.51e-02f 1
203 2.8006884e+05 1.40e+02 7.79e+07 -1.0 9.29e+02 -2.0 1.00e+00 5.28e-03h 1
204 2.8015019e+05 1.39e+02 7.73e+07 -1.0 7.90e+04 -2.5 8.06e-03 8.35e-03h 2
205 2.8064274e+05 1.34e+02 1.05e+08 -1.0 8.16e+04 -2.9 7.51e-02 3.57e-02h 1
206 2.8064278e+05 1.34e+02 4.03e+11 -1.0 8.64e+02 2.0 1.00e+00 3.23e-04h 1
207 2.8064335e+05 1.34e+02 4.30e+11 -1.0 5.43e+04 2.4 2.35e-04 2.94e-05h 5
208 2.8064399e+05 1.34e+02 4.40e+11 -1.0 5.85e+04 2.0 2.47e-04 3.03e-05h 5
209 2.8064552e+05 1.34e+02 4.54e+11 -1.0 6.58e+04 1.5 9.02e-04 6.77e-05h 4
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
210 2.8222241e+05 1.24e+02 3.97e+11 -1.0 9.40e+04 - 1.24e-01 7.34e-02h 1
211 2.8220445e+05 1.24e+02 3.93e+11 -1.0 9.07e+04 1.0 1.52e-03 7.58e-04f 1
212r 2.8220445e+05 1.24e+02 1.00e+03 1.8 0.00e+00 5.9 0.00e+00 3.67e-07R 5
213r 2.8220129e+05 2.03e+01 1.38e+04 1.8 7.36e+04 - 5.97e-03 1.70e-03f 1
214 2.8216015e+05 2.03e+01 3.00e+00 -1.0 1.24e+05 - 2.25e-03 1.12e-03f 1
215 2.8215891e+05 2.03e+01 5.34e+04 -1.0 8.34e+04 - 3.16e-01 6.13e-05f 1
216 2.8209715e+05 2.02e+01 2.17e+05 -1.0 8.68e+04 - 7.12e-01 3.18e-03f 1
217 2.8285849e+05 1.94e+01 3.61e+05 -1.0 8.46e+04 - 1.39e-01 3.95e-02h 1
218 2.8931606e+05 1.27e+01 7.06e+05 -1.0 8.25e+04 - 7.24e-01 3.44e-01h 1
219 3.0346405e+05 1.81e+01 3.18e+05 -1.0 6.22e+04 - 1.67e-01 1.00e+00h 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
220 3.0474704e+05 2.29e+00 1.55e+05 -1.0 5.63e+03 - 2.22e-01 1.00e+00h 1
221 3.0400748e+05 1.53e+00 4.24e+04 -1.0 3.34e+03 - 6.64e-01 1.00e+00f 1
222 3.0170824e+05 6.32e-01 7.78e+03 -1.0 1.04e+04 - 3.95e-01 1.00e+00f 1
223 2.9693737e+05 2.81e+01 1.11e+04 -1.0 2.19e+04 - 9.83e-01 1.00e+00f 1
224 2.9693737e+05 2.81e+01 1.69e+10 -1.0 2.42e+01 5.5 9.94e-01 3.29e-05h 1
225 2.9693737e+05 2.81e+01 1.79e+13 -1.0 2.39e+02 5.0 1.00e+00 3.45e-05h 1
226 2.9937267e+05 2.21e+00 1.79e+11 -1.0 7.59e+03 - 9.90e-01 1.00e+00h 1
227 2.9716454e+05 3.10e+01 1.66e+15 -1.0 1.60e+04 4.5 4.83e-05 4.54e-01f 1
228 2.9716640e+05 3.10e+01 1.66e+15 -1.0 7.66e+04 - 2.24e-06 7.62e-05h 14
229 2.9716796e+05 3.10e+01 1.66e+15 -1.0 2.18e+06 - 6.70e-02 3.24e-06H 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
230 2.9715453e+05 3.04e+01 1.63e+15 -1.0 3.23e+03 4.0 4.11e-01 1.93e-02f 1
231 2.9718942e+05 3.03e+01 2.40e+15 -1.0 2.72e+04 3.6 1.00e+00 5.65e-03h 1
232 3.0357797e+05 4.86e+00 2.98e+14 -1.0 2.80e+04 3.1 6.51e-01 1.00e+00h 1
233 3.0357797e+05 4.86e+00 2.98e+14 -1.0 2.51e+01 12.9 5.51e-02 3.60e-04h 9
234 3.0357797e+05 4.86e+00 2.98e+14 -1.0 8.54e+01 12.4 2.19e-02 9.33e-05h 10
235 2.4711830e+05 3.19e+02 2.26e+14 -1.0 1.43e+05 - 9.69e-01 1.00e+00H 1
236 2.4827390e+05 3.12e+02 2.21e+14 -1.0 2.01e+05 - 1.00e+00 2.38e-02h 1
237 2.6037627e+05 2.53e+02 1.76e+14 -1.0 2.00e+05 - 1.00e+00 2.50e-01h 3
238 2.6037627e+05 2.54e+02 1.77e+14 -1.0 6.29e+01 12.9 2.35e-02 2.73e-03h 6
239 2.6430151e+05 1.21e+01 2.92e+12 -1.0 1.88e+04 - 1.00e+00 1.00e+00h 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
240 2.7611279e+05 8.75e+01 9.74e+12 -1.0 9.24e+04 - 9.56e-01 5.00e-01h 2
241 2.9333225e+05 4.81e+01 7.71e+12 -1.0 7.76e+04 - 6.87e-02 1.00e+00H 1
242r 2.9333225e+05 4.81e+01 1.00e+03 0.9 0.00e+00 12.4 0.00e+00 7.39e-09R 2
243r 2.9333613e+05 4.77e+01 1.26e+04 0.9 1.53e+04 - 1.43e-02 1.16e-03f 1
244 2.9333219e+05 4.77e+01 7.00e+00 -1.0 1.37e+05 - 4.04e-04 1.01e-04f 1
245 2.9332573e+05 4.77e+01 1.21e+05 -1.0 8.47e+04 - 5.21e-01 3.63e-04f 1
246 2.9202097e+05 4.53e+01 1.15e+05 -1.0 1.29e+05 - 4.51e-02 4.74e-02f 2
247 2.9143485e+05 4.41e+01 1.40e+05 -1.0 1.15e+05 - 1.50e-01 2.50e-02f 3
248 2.9080870e+05 4.28e+01 1.55e+05 -1.0 1.10e+05 - 1.02e-01 2.88e-02f 3
249 2.9017179e+05 4.13e+01 3.44e+05 -1.0 9.62e+04 - 6.03e-01 3.56e-02f 3
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
250 2.8985394e+05 4.05e+01 3.52e+05 -1.0 1.01e+05 - 6.52e-02 1.84e-02f 4
251 2.8739410e+05 8.34e+01 4.67e+05 -1.0 8.26e+04 - 6.84e-01 1.90e-01f 1
252 2.8739410e+05 8.34e+01 1.79e+09 -1.0 6.96e+01 11.9 1.84e-01 3.12e-05h 1
253r 2.8739410e+05 8.34e+01 1.00e+03 1.9 0.00e+00 11.4 0.00e+00 1.56e-07R 2
254r 2.8739740e+05 3.23e+01 1.65e+04 1.9 3.82e+04 - 6.90e-03 1.66e-03f 1
255 2.8736484e+05 3.23e+01 1.25e+00 -1.0 1.42e+05 - 9.40e-04 8.12e-04f 1
256 2.8720051e+05 3.21e+01 7.11e+03 -1.0 9.99e+04 - 1.22e-01 5.46e-03f 1
257 2.8719406e+05 3.21e+01 1.94e+05 -1.0 8.73e+04 - 4.69e-01 2.16e-04f 1
258 2.8417159e+05 2.87e+01 1.94e+05 -1.0 1.35e+05 - 1.13e-01 7.18e-02f 1
259r 2.8417159e+05 2.87e+01 1.00e+03 1.4 0.00e+00 11.0 0.00e+00 4.73e-07R 4
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
260r 2.8416979e+05 2.86e+01 9.97e+02 1.4 1.57e+04 - 2.50e-03 1.47e-03f 1
261 2.8414991e+05 2.86e+01 1.89e+00 -1.0 1.28e+05 - 7.81e-04 5.31e-04f 1
262 2.8413550e+05 2.86e+01 3.89e+03 -1.0 8.07e+04 - 2.30e-02 7.41e-04f 1
263 2.8411984e+05 2.85e+01 7.36e+03 -1.0 7.88e+04 - 1.72e-02 7.90e-04f 1
264 2.8412882e+05 2.85e+01 1.12e+06 -1.0 4.83e+04 - 7.25e-01 1.01e-03h 1
265 2.8660718e+05 2.40e+01 9.41e+05 -1.0 6.83e+04 - 1.80e-01 1.57e-01h 3
266 2.9650411e+05 9.26e+00 3.76e+05 -1.0 6.22e+04 - 7.72e-01 6.14e-01H 1
267 3.0368460e+05 2.10e+00 2.26e+05 -1.0 3.04e+04 - 1.27e-01 1.00e+00H 1
268 3.0051784e+05 2.23e+00 1.50e+05 -1.0 1.43e+04 - 3.94e-01 1.00e+00f 1
269 2.9540297e+05 1.76e+00 3.42e+04 -1.0 2.36e+04 - 3.24e-01 1.00e+00F 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
270 2.9540297e+05 1.76e+00 3.86e+08 -1.0 8.06e+00 10.5 7.86e-05 1.57e-03h 1
271 2.9540297e+05 1.76e+00 3.87e+08 -1.0 8.05e+00 10.0 1.64e-03 1.57e-05h 1
272r 2.9540297e+05 1.76e+00 1.00e+03 0.2 0.00e+00 9.5 0.00e+00 9.08e-08R 2
273r 2.9540344e+05 4.13e-01 1.73e+03 0.2 1.13e+04 - 4.55e-03 1.00e-03f 1
274 2.9540180e+05 4.13e-01 1.69e+04 -1.0 1.20e+05 - 2.17e-01 4.88e-05f 1
275 2.9529371e+05 4.21e-01 1.13e+05 -1.0 8.26e+04 - 2.19e-01 6.33e-03f 1
276 2.7222296e+05 3.33e+02 2.62e+05 -1.0 9.50e+04 - 2.06e-01 1.00e+00F 1
277 2.7172564e+05 2.82e+02 2.40e+05 -1.0 3.52e+04 - 5.42e-01 8.69e-02f 1
278 2.7003695e+05 2.56e+02 1.68e+05 -1.0 2.78e+04 - 7.46e-01 4.36e-01f 1
279r 2.7003695e+05 2.56e+02 1.00e+03 2.4 0.00e+00 9.1 0.00e+00 4.76e-07R 3
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
280r 2.7004490e+05 1.60e+02 3.83e+04 2.4 9.18e+04 - 1.13e-02 2.12e-03f 1
281 2.6994022e+05 1.59e+02 1.42e+00 -1.0 1.13e+05 - 2.94e-03 3.10e-03f 1
282 2.6993730e+05 1.59e+02 9.49e+03 -1.0 8.36e+04 - 2.32e-01 1.09e-04f 1
283 2.6954764e+05 1.57e+02 3.34e+04 -1.0 8.59e+04 - 4.99e-01 1.34e-02f 1
284 2.6948270e+05 1.57e+02 4.32e+05 -1.0 1.77e+05 - 5.12e-01 1.91e-03f 1
285 2.6681167e+05 1.43e+02 4.27e+05 -1.0 1.80e+05 - 1.61e-01 8.16e-02f 1
286r 2.6681167e+05 1.43e+02 1.00e+03 2.2 0.00e+00 8.6 0.00e+00 4.99e-07R 3
287r 2.6680781e+05 8.51e+00 9.96e+02 2.2 2.43e+04 - 5.65e-03 5.84e-03f 1
288 2.6657756e+05 8.46e+00 6.83e+00 -1.0 1.00e+05 - 3.03e-02 7.31e-03f 1
289 2.6657463e+05 8.45e+00 1.21e+04 -1.0 7.95e+04 - 1.51e-01 1.27e-04f 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
290 2.6649023e+05 8.42e+00 1.24e+04 -1.0 7.03e+04 - 7.83e-03 4.01e-03f 1
291 2.6638786e+05 8.35e+00 7.77e+04 -1.0 5.44e+04 - 3.74e-01 8.53e-03f 1
292 2.6641247e+05 8.34e+00 4.95e+05 -1.0 8.17e+04 - 3.42e-01 1.34e-03h 1
293 2.6895978e+05 7.68e+00 6.89e+05 -1.0 9.10e+04 - 6.11e-01 1.25e-01h 4
294 2.7128721e+05 7.65e+00 6.12e+05 -1.0 8.99e+04 - 2.79e-01 1.15e-01h 4
295 2.7376815e+05 7.61e+00 5.65e+05 -1.0 8.83e+04 - 4.82e-01 1.25e-01h 4
296 2.7618467e+05 7.45e+00 5.61e+05 -1.0 8.58e+04 - 6.72e-01 1.25e-01h 4
297 2.7851781e+05 7.21e+00 4.96e+05 -1.0 8.27e+04 - 1.73e-01 1.25e-01h 4
298 2.8298300e+05 8.16e+00 4.65e+05 -1.0 7.90e+04 - 8.31e-01 2.50e-01h 3
299 2.8398247e+05 7.77e+00 4.53e+05 -1.0 7.06e+04 - 1.74e-01 6.25e-02h 5
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
300 2.8410295e+05 7.71e+00 5.82e+05 -1.0 6.80e+04 - 9.09e-01 7.81e-03h 8
301 2.8411793e+05 7.70e+00 5.84e+05 -1.0 6.76e+04 - 1.87e-01 9.77e-04h 11
302 2.8411981e+05 7.70e+00 5.97e+05 -1.0 6.76e+04 - 9.96e-01 1.22e-04h 14
303 2.9945684e+05 2.93e+01 2.41e+05 -1.0 6.76e+04 - 1.81e-01 1.00e+00w 1
304 3.0340995e+05 2.22e+00 2.62e+04 -1.0 1.68e+04 - 1.00e+00 1.00e+00w 1
305 2.9827244e+05 3.31e+00 7.99e+04 -1.0 2.36e+04 - 4.02e-01 1.00e+00w 1
306 2.8412027e+05 7.70e+00 5.97e+05 -1.0 3.93e+04 - 1.81e-01 3.05e-05h 15
307 3.0354204e+05 1.23e+01 2.89e+05 -1.0 6.76e+04 - 1.00e+00 1.00e+00H 1
308 3.0149455e+05 2.28e+00 1.62e+05 -1.0 9.49e+03 - 3.32e-01 1.00e+00f 1
309 2.9665499e+05 6.16e+00 1.32e+04 -1.0 2.23e+04 - 1.00e+00 1.00e+00f 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
310 2.9343608e+05 2.56e+01 1.71e+04 -1.0 7.76e+04 - 1.61e-01 2.06e-01f 2
311 2.9343608e+05 2.56e+01 1.84e+09 -1.0 1.49e+01 8.1 1.00e+00 2.87e-04h 1
312 2.9317468e+05 8.50e+00 8.12e+07 -1.0 2.97e+03 - 9.56e-01 1.00e+00f 1
313 2.8944359e+05 2.11e+00 2.10e+06 -1.0 1.68e+04 - 9.95e-01 1.00e+00f 1
314 2.8918867e+05 2.17e-02 2.73e+03 -1.0 1.31e+03 - 1.00e+00 1.00e+00f 1
315 2.8319976e+05 5.42e+01 3.18e+04 -1.0 3.26e+04 - 8.80e-01 1.00e+00f 1
316 2.8319976e+05 5.42e+01 1.35e+10 -1.0 1.46e+01 7.6 1.00e+00 3.19e-05h 1
317 2.8594547e+05 8.26e+00 1.33e+08 -1.0 1.32e+04 - 9.90e-01 1.00e+00h 1
318 2.8595448e+05 6.08e-01 1.99e+14 -1.0 1.32e+02 7.1 6.73e-07 1.00e+00h 1
319 2.8595449e+05 1.61e-04 8.82e+09 -1.0 7.07e-01 6.7 9.40e-01 1.00e+00h 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
320 2.8595471e+05 1.65e-07 1.40e+05 -1.0 1.12e+00 - 9.91e-01 1.00e+00h 1
321 2.8595471e+05 1.04e-10 8.05e+01 -1.0 1.05e-07 6.2 9.95e-01 1.00e+00h 1
322 2.8381914e+05 4.99e-01 3.55e+03 -1.0 1.42e+08 - 3.10e-03 6.84e-05f 1
323 2.8066086e+05 4.59e+01 7.36e+03 -1.0 9.09e+06 - 6.59e-03 3.23e-03f 1
324 2.7668880e+05 9.00e+01 3.96e+04 -1.0 3.97e+06 - 4.45e-02 1.14e-02f 1
325 2.7668880e+05 9.00e+01 1.67e+09 -1.0 8.95e+01 5.7 1.00e+00 1.14e-05h 1
326 2.8191331e+05 4.53e+01 1.64e+07 -1.0 4.18e+04 - 9.90e-01 5.00e-01h 2
327 2.8544472e+05 3.47e+00 3.02e+04 -1.0 1.15e+04 - 1.00e+00 1.00e+00h 1
328 2.8228282e+05 2.38e+01 6.58e+04 -1.0 4.78e+04 - 7.35e-01 5.00e-01f 2
329 2.8311865e+05 4.27e+00 3.39e+03 -1.0 1.16e+04 - 1.00e+00 1.00e+00h 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
330 2.8247002e+05 8.36e-01 1.84e+01 -1.0 3.99e+03 - 1.00e+00 1.00e+00f 1
331 2.8251898e+05 4.93e-03 4.89e-01 -1.7 3.96e+02 - 1.00e+00 1.00e+00h 1
332 2.8251870e+05 1.50e-07 1.85e-05 -3.8 1.13e+00 - 1.00e+00 1.00e+00f 1
333 2.8251869e+05 7.46e-11 7.78e-10 -8.6 1.49e-03 - 1.00e+00 1.00e+00h 1
Number of Iterations....: 333
(scaled) (unscaled)
Objective...............: 2.8251869477498095e+05 2.8251869477498095e+05
Dual infeasibility......: 7.7843619785268429e-10 7.7843619785268429e-10
Constraint violation....: 1.3128149817982369e-11 7.4578565545380116e-11
Complementarity.........: 2.5072731634536451e-09 2.5072731634536451e-09
Overall NLP error.......: 4.0904109550221068e-11 2.5072731634536451e-09
Number of objective function evaluations = 1045
Number of objective gradient evaluations = 311
Number of equality constraint evaluations = 1049
Number of inequality constraint evaluations = 1049
Number of equality constraint Jacobian evaluations = 349
Number of inequality constraint Jacobian evaluations = 349
Number of Lagrangian Hessian evaluations = 333
Total CPU secs in IPOPT (w/o function evaluations) = 0.411
Total CPU secs in NLP function evaluations = 0.037
EXIT: Optimal Solution Found.
Step 3: Test the Byproduct Recovery Framework#
Now that the model is solved, the next task is to calculate the cost and evaluate economic feasibility.
3.1. Specify Product Prices
Product prices are defined in costing_dictionaries.py. Users can access the default sale prices via load_default_sale_prices() function, as shown below:
sale_prices = load_default_sale_prices()
Li_price = sale_prices["Li"]
Co_price = sale_prices["Co"]
Alternatively, users may specify custom sale prices by manually replacing the right-hand side values of the price expressions.
These prices will be used to compute annual revenue, which is a key input to the byproduct recovery decision framework.
3.2. Introduce the Framework and Specify the Product Outputs
Next, introduce the byproduct recovery framework and specify the target products recovered from the diafiltration process.
The byproduct recovery framework accepts user inputs, where products are listed in a structure called material_list, and their associated data (e.g. flow rate, price) are organized in a dictionary called material_data.
material_list: A list of product names (strings).material_data: A dictionary where each key corresponds to a product name and maps to its properties such as flow rate and price.
This structured input will be passed into the byproduct recovery decision framework to assess economic viability.
# The framework take user input
material_list = ["Lithium", "Cobalt"]
# Introduce the byproduct recovery framework
model = ConcreteModel()
model.recovery_determine = ByproductRecovery(materials=material_list)
# Define input values based on provided materials
material_data = {
"Lithium": {
"production": Li_recovery_mass,
"market_value": Li_price,
"waste_disposal": 1,
"conversion": 0,
"conversion_cost": 0,
"process_steps": 1,
"process_cost": total_annualized_cost,
},
"Cobalt": {
"production": Co_recovery_mass,
"market_value": Co_price,
"waste_disposal": 1,
"conversion": 0,
"conversion_cost": 0,
"process_steps": 0,
"process_cost": 0,
},
}
3.3. Set Additional Parameters and Evaluate Net Benefit
To evaluate the economic feasibility, we must define additional parameters for each product:
"waste_disposal": Set to1to indicate that waste disposal costs are considered."conversion": Set to0if no conversion process is required to recover the material."conversion_cost": Set to0when conversion is not needed."process_steps": Set to0if no additional steps are needed beyond the current recovery process.
In this case, the lithium–cobalt diafiltration plant recovers both lithium and cobalt in a single process. No additional purification or recovery steps are considered for either product. As such:
The process cost is only accounted for once under
"Lithium"production (though it could alternatively be placed under"Cobalt"with no impact on results).Both products are assumed to be sold at market prices, regardless of purity level.
# Set values based on material list
for m in material_list:
data = material_data.get(m, {})
model.recovery_determine.material_production[m].set_value(data.get("production", 0))
model.recovery_determine.market_value[m].set_value(data.get("market_value", 0))
model.recovery_determine.waste_disposal_cost[m].set_value(
data.get("waste_disposal", 0)
)
model.recovery_determine.conversion_possible[m].set_value(data.get("conversion", 0))
model.recovery_determine.conversion_cost[m].set_value(
data.get("conversion_cost", 0)
)
model.recovery_determine.added_process_steps[m].set_value(
data.get("process_steps", 0)
)
model.recovery_determine.added_process_cost[m].set_value(
data.get("process_cost", 0)
)
💡 Note: The
0indata.get("production", 0)does not mean zero production. It indicates that the production rate is assumed to be steady-state (i.e., constant over time), not time-varying.
3.4. Calculate the Overall Net Benefit
With parameters such as production rate, market price, and associated costs specified for each product, the byproduct recovery framework can now be implemented to quantify the overall net benefit.
The overall net benefit is used to determine profitability:
If
net_benefit_value> 0 → The byproduct recovery process is profitable.If
net_benefit_value≤ 0 → The process is not profitable.
potential_revenue = value(model.recovery_determine.potential_revenue)
assert potential_revenue >= 0, "Potential revenue should be non-negative."
determine_result = model.recovery_determine.determine_financial_viability()
assert isinstance(
determine_result, str
), f"Expected a string message, but got {type(determine_result)}"
net_benefit_value = value(model.recovery_determine.net_benefit)
assert net_benefit_value == pytest.approx(320373532.81, rel=1e-4)
# Check the output string for financial viability
print("\n--- Byproduct Recovery Decision ---")
print(determine_result)
--- Byproduct Recovery Decision ---
✅ Byproduct recovery is financially viable. Net Benefit: 320342254.82 $/yr
✅ Note: The
assertstatements are included to verify that the model is built as expected.
They are helpful for testing and debugging, but not required for using the byproduct recovery framework.
Package Installation#
As mentioned previously, Pyomo, IDAES, and PrOMMiS packages are necessary to use the framework. If these packages are not installed, this may be done using the following commands in Anaconda Prompt:
pip install pyomo
pip install idaes-pse
For more detailed installation instructions, refer to the respective README.md files for Pyomo, IDAES, and ProMMiS.