University of Kentucky Flowsheet Optimization Tutorial#
Throughout this tutorial, you will learn how to write an optimization function for a given flowsheet and iteratively optimize the flowsheet, while also gaining an understanding of the engineering insights used to justify the system’s operating conditions. Our case study will be the University of Kentucky (UKy) flowsheet, a continuous, pilot-scale plant operation for recovering rare earth elements (REEs) from coal and coal byproducts with the goal of producing marketable mixed rare earth oxides (REOs), as shown in the process flow diagram below. For more information on this flowsheet, please refer to the Useful Links at the bottom of this cell.
UKy Flowsheet Connectivity#

Tutorial Outline#
In this tutorial, we will start with a low-recovery version of the UKy flowsheet that is only able to achieve 0.9% REE recovery. Then, we will write an optimization function that unfixes a variety of operating conditions in order to maximize the REE recovery while still adhering to realistic variable bounds. From there, we will walk through an iterative process of running the optimization, updating the flowsheet operating conditions, diagnosing any issues, and then expanding the bounds of the optimization until we hit the target recovery of ~20% REE.
Useful Links:#
Public Github Repository: prommis/prommis
Tutorial on Building the UKy Flowsheet: UKy Flowsheet Tutorial
Current UKy Flowsheet Code: prommis/prommis
Low-Recovery UKy Flowsheet Code: Low-Recovery UKy
Step 1: Import the necessary tools#
We’ll leverage basic functionalities from Pyomo, general-purpose models from IDAES, and process-specific models from PrOMMiS.
# Import the essentials from Pyomo
from pyomo.environ import (
Constraint,
Objective,
value,
)
from pyomo.network import SequentialDecomposition
# Import the essentials from IDAES
import idaes.logger as idaeslog
# Import scaling, initialization, and diagnostic tools from IDAES
from idaes.core.initialization import BlockTriangularizationInitializer
from idaes.core.scaling.util import get_scaling_factor, set_scaling_factor
from idaes.core.solvers import get_solver
# Import unit models from IDAES
from idaes.models.unit_models.feed import FeedInitializer
from idaes.models.unit_models.mixer import MixerInitializer
from idaes.models.unit_models.product import ProductInitializer
from idaes.models.unit_models.separator import SeparatorInitializer
# Import the UKy-specific unit and property models
from prommis.leaching.leach_train import LeachingTrainInitializer
from prommis.solvent_extraction.solvent_extraction import SolventExtractionInitializer
# Import parameter sweep tools from WaterTAP
from parameter_sweep import LinearSample, parameter_sweep
# Import the low-recovery UKy flowsheet
import uky_flowsheet_low_recovery as uky
# Set up logger
_log = idaeslog.getLogger(__name__)
WARNING: DEPRECATED: the 'DiagnosticsToolbox' class has been moved to
'idaes.co re.util.diagnostics_tools.diagnostics_toolbox.DiagnosticsToolbox'.
Please update your import. (deprecated in 2.12.0) (called from <frozen
importlib._bootstrap>:241)
Step 2: Run the low-recovery UKy Flowsheet#
We will start by running a low-recovery version of the UKy flowsheet that only recovered 0.9% of the total REEs. To do so, we will simply import the functions directly from the flowsheet. If you’d like to take a closer look at these functions, see Low-Recovery UKy.
m1 = uky.build()
uky.set_operating_conditions(m1, DEHPA_dosage=0.05)
uky.set_scaling(m1)
uky.initialize_system(m1)
uky.solve_system(m1, tee=False)
uky.fix_organic_recycle(m1)
uky.solve_system(m1, tee=False)
uky.add_result_expressions(m1)
Scaling fs.leach
Scaling fs.sl_sep1
Scaling fs.scrubber_HCl_leach_translator
Scaling fs.leach_mixer
Scaling fs.leach_liquid_feed
Scaling fs.leach_solid_feed
Scaling fs.leach_filter_cake
Scaling fs.leach_filter_cake_liquid
Scaling fs.rougher_org_make_up
Scaling fs.solex_rougher_load
Scaling fs.acid_feed1
Scaling fs.solex_rougher_scrub
Scaling fs.acid_feed2
Scaling fs.solex_rougher_strip
Scaling fs.rougher_sep
Scaling fs.rougher_mixer
Scaling fs.load_sep
Scaling fs.scrub_sep
Scaling fs.rougher_organic_purge
Scaling fs.solex_cleaner_load
Scaling fs.solex_cleaner_strip
Scaling fs.cleaner_org_make_up
Scaling fs.cleaner_mixer
Scaling fs.cleaner_sep
Scaling fs.cleaner_HCl_leach_translator
Scaling fs.leach_sx_mixer
Scaling fs.acid_feed3
Scaling fs.cleaner_organic_purge
Scaling fs.precipitator
Scaling fs.sl_sep2
Scaling fs.precip_sep
Scaling fs.precip_sx_mixer
Scaling fs.precip_purge
Scaling fs.roaster
Scaling fs.leaching_sol_feed_expanded
Scaling fs.leaching_liq_feed_expanded
Scaling fs.leaching_feed_mixture_expanded
Scaling fs.leaching_solid_outlet_expanded
Scaling fs.leaching_liquid_outlet_expanded
Scaling fs.sl_sep1_solid_outlet_expanded
Scaling fs.sl_sep1_retained_liquid_outlet_expanded
Scaling fs.sl_sep1_liquid_outlet_expanded
Scaling fs.sx_rougher_load_aq_feed_expanded
Scaling fs.sx_rougher_org_feed_expanded
Scaling fs.sx_rougher_mixed_org_recycle_expanded
Scaling fs.sx_rougher_load_aq_outlet_expanded
Scaling fs.sx_rougher_load_aq_recycle_expanded
Scaling fs.sx_rougher_load_org_outlet_expanded
Scaling fs.sx_rougher_scrub_acid_feed_expanded
Scaling fs.sx_rougher_scrub_aq_outlet_expanded
Scaling fs.sx_rougher_scrub_aq_translator_expanded
Scaling fs.translator_scrub_recycle_expanded
Scaling fs.sx_rougher_scrub_org_outlet_expanded
Scaling fs.sx_rougher_strip_acid_feed_expanded
Scaling fs.sx_rougher_strip_org_outlet_expanded
Scaling fs.sx_rougher_strip_org_purge_expanded
Scaling fs.sx_rougher_strip_org_recycle_expanded
Scaling fs.sx_rougher_strip_aq_outlet_expanded
Scaling fs.sx_cleaner_load_aq_feed_expanded
Scaling fs.sx_cleaner_org_feed_expanded
Scaling fs.sx_cleaner_mixed_org_recycle_expanded
Scaling fs.sx_cleaner_load_aq_outlet_translator_expanded
Scaling fs.sx_cleaner_load_translator_leach_sx_mixer_expanded
Scaling fs.sx_cleaner_strip_acid_feed_expanded
Scaling fs.sx_cleaner_load_org_outlet_expanded
Scaling fs.sx_cleaner_strip_org_outlet_expanded
Scaling fs.sx_cleaner_strip_org_purge_expanded
Scaling fs.sx_cleaner_strip_org_recycle_expanded
Scaling fs.sx_cleaner_strip_aq_precip_expanded
Scaling fs.precip_solid_outlet_expanded
Scaling fs.precip_aq_sl_sep2_expanded
Scaling fs.sl_sep2_solid_outlet_expanded
Scaling fs.sl_sep2_liquid_outlet_expanded
Scaling fs.sl_sep2_retained_liquid_roaster_expanded
Scaling fs.sl_sep2_aq_purge_expanded
Scaling fs.sl_sep2_aq_recycle_expanded
2026-06-29 11:22:55 [INFO] idaes.uky_flowsheet_low_recovery: Initialization Order: {_init_ord}
2026-06-29 11:22:55 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.leach_solid_feed
2026-06-29 11:22:55 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.leach_liquid_feed
2026-06-29 11:22:55 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.solex_rougher_load
2026-06-29 11:22:56 [INFO] idaes.init.fs.solex_rougher_load.mscontactor: Stream Initialization Completed.
2026-06-29 11:22:56 [INFO] idaes.init.fs.solex_rougher_load.mscontactor: Initialization Completed, optimal - <undefined>
2026-06-29 11:22:56 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.rougher_org_make_up
2026-06-29 11:22:56 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.acid_feed1
2026-06-29 11:22:56 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.acid_feed2
2026-06-29 11:22:56 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.solex_cleaner_load
2026-06-29 11:22:57 [INFO] idaes.init.fs.solex_cleaner_load.mscontactor: Stream Initialization Completed.
2026-06-29 11:22:57 [INFO] idaes.init.fs.solex_cleaner_load.mscontactor: Initialization Completed, optimal - <undefined>
2026-06-29 11:22:57 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.cleaner_org_make_up
2026-06-29 11:22:57 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.acid_feed3
2026-06-29 11:22:57 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.leach
2026-06-29 11:22:57 [INFO] idaes.init.fs.leach.mscontactor: Stream Initialization Completed.
2026-06-29 11:22:57 [INFO] idaes.init.fs.leach.mscontactor: Initialization Completed, optimal - <undefined>
2026-06-29 11:22:57 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.load_sep
2026-06-29 11:22:57 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.solex_rougher_scrub
2026-06-29 11:22:57 [INFO] idaes.init.fs.solex_rougher_scrub.mscontactor: Stream Initialization Completed.
2026-06-29 11:22:57 [INFO] idaes.init.fs.solex_rougher_scrub.mscontactor: Initialization Completed, optimal - <undefined>
2026-06-29 11:22:58 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.cleaner_HCl_leach_translator
2026-06-29 11:22:58 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.solex_cleaner_strip
2026-06-29 11:22:58 [INFO] idaes.init.fs.solex_cleaner_strip.mscontactor: Stream Initialization Completed.
2026-06-29 11:22:58 [INFO] idaes.init.fs.solex_cleaner_strip.mscontactor: Initialization Completed, optimal - <undefined>
2026-06-29 11:22:58 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.sl_sep1
2026-06-29 11:22:58 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.scrub_sep
2026-06-29 11:22:58 [INFO] idaes.init.fs.scrub_sep: Initialization Step 2 Complete: optimal - <undefined>
2026-06-29 11:22:58 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.solex_rougher_strip
2026-06-29 11:22:59 [INFO] idaes.init.fs.solex_rougher_strip.mscontactor: Stream Initialization Completed.
2026-06-29 11:22:59 [INFO] idaes.init.fs.solex_rougher_strip.mscontactor: Initialization Completed, optimal - <undefined>
2026-06-29 11:22:59 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.cleaner_sep
2026-06-29 11:22:59 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.precipitator
2026-06-29 11:22:59 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.leach_filter_cake
2026-06-29 11:22:59 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.leach_filter_cake_liquid
2026-06-29 11:22:59 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.leach_sx_mixer
2026-06-29 11:22:59 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.scrubber_HCl_leach_translator
2026-06-29 11:22:59 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.rougher_sep
2026-06-29 11:22:59 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.cleaner_mixer
2026-06-29 11:22:59 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.cleaner_organic_purge
2026-06-29 11:22:59 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.sl_sep2
2026-06-29 11:22:59 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.precip_sep
2026-06-29 11:23:00 [INFO] idaes.init.fs.precip_sep: Initialization Step 2 Complete: optimal - <undefined>
2026-06-29 11:23:00 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.leach_mixer
2026-06-29 11:23:00 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.rougher_mixer
2026-06-29 11:23:00 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.rougher_organic_purge
2026-06-29 11:23:00 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.roaster
2026-06-29 11:23:00 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.precip_purge
2026-06-29 11:23:00 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.precip_sx_mixer
2026-06-29 11:23:00 [INFO] idaes.init.fs.precip_sx_mixer: Initialization Complete: optimal - <undefined>
2026-06-29 11:23:00 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.leach_solid_feed
2026-06-29 11:23:00 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.leach_liquid_feed
2026-06-29 11:23:00 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.rougher_org_make_up
2026-06-29 11:23:00 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.acid_feed1
2026-06-29 11:23:00 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.acid_feed2
2026-06-29 11:23:00 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.cleaner_org_make_up
2026-06-29 11:23:00 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.acid_feed3
2026-06-29 11:23:00 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.solex_cleaner_load
2026-06-29 11:23:01 [INFO] idaes.init.fs.solex_cleaner_load.mscontactor: Stream Initialization Completed.
2026-06-29 11:23:01 [INFO] idaes.init.fs.solex_cleaner_load.mscontactor: Initialization Completed, optimal - <undefined>
2026-06-29 11:23:01 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.solex_rougher_load
2026-06-29 11:23:01 [INFO] idaes.init.fs.solex_rougher_load.mscontactor: Stream Initialization Completed.
2026-06-29 11:23:01 [INFO] idaes.init.fs.solex_rougher_load.mscontactor: Initialization Completed, optimal - <undefined>
2026-06-29 11:23:01 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.leach
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,1].conversion_comp[Sc2O3]' to a numeric value
`-8.39508749947673e-09` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,1].conversion_comp[Y2O3]' to a numeric value
`-5.554896289474591e-09` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,1].conversion_comp[Pr2O3]' to a numeric value
`-1.9851327705076312e-08` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,1].conversion_comp[Sm2O3]' to a numeric value
`-2.4603533721480436e-08` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,1].conversion_comp[Gd2O3]' to a numeric value
`-3.922440689474765e-08` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,1].conversion_comp[Dy2O3]' to a numeric value
`-5.784556213406547e-08` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,2].conversion_comp[Y2O3]' to a numeric value
`-4.612734358929686e-08` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,2].conversion_comp[La2O3]' to a numeric value
`-1.7118508850188173e-08` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,2].conversion_comp[Ce2O3]' to a numeric value
`-1.6617558214273316e-09` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,2].conversion_comp[Pr2O3]' to a numeric value
`-9.775264216386736e-08` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,2].conversion_comp[Nd2O3]' to a numeric value
`-1.7162725927342594e-08` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,2].conversion_comp[Sm2O3]' to a numeric value
`-1.1493075758028818e-07` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,2].conversion_comp[Gd2O3]' to a numeric value
`-1.6768875575544955e-07` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,2].conversion_comp[Dy2O3]' to a numeric value
`-2.3496518629329045e-07` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,2].conversion_comp[Sc2O3]' to a numeric value
`-5.639046511099609e-08` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
2026-06-29 11:23:02 [INFO] idaes.init.fs.leach.mscontactor: Stream Initialization Completed.
2026-06-29 11:23:02 [INFO] idaes.init.fs.leach.mscontactor: Initialization Completed, optimal - <undefined>
2026-06-29 11:23:02 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.solex_cleaner_strip
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,2].conc_mass_comp[Y]' to a
numeric value `-1.4853771878321977e-07` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,1].conc_mass_comp[Y]' to a
numeric value `-1.618981210901991e-06` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,1].conc_mol_comp[Y]' to a
numeric value `-1.8210236313333542e-11` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,1].flow_mol_comp[Y]' to a
numeric value `-5.463071401506925e-13` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,2].conc_mol_comp[Y]' to a
numeric value `-1.6707470355868944e-12` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,2].flow_mol_comp[Y]' to a
numeric value `-5.012234117335311e-14` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,3].conc_mass_comp[La]' to a
numeric value `-4.454542171227379e-08` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,1].conc_mass_comp[La]' to a
numeric value `-2.4660036392662285e-08` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,1].conc_mol_comp[La]' to a
numeric value `-1.775315872935924e-13` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,1].flow_mol_comp[La]' to a
numeric value `-5.325946660691277e-15` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,3].conc_mol_comp[La]' to a
numeric value `-3.20689796944284e-13` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,3].flow_mol_comp[La]' to a
numeric value `-9.620695082604436e-15` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,3].conc_mass_comp[Ce]' to a
numeric value `-5.005125578010475e-08` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,2].conc_mass_comp[Ce]' to a
numeric value `-1.530667196900397e-07` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,1].conc_mass_comp[Ce]' to a
numeric value `-3.3382136149787053e-07` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,1].conc_mol_comp[Ce]' to a
numeric value `-2.382464255790752e-12` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,1].flow_mol_comp[Ce]' to a
numeric value `-7.147392757939769e-14` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,2].conc_mol_comp[Ce]' to a
numeric value `-1.092428471788867e-12` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,2].flow_mol_comp[Ce]' to a
numeric value `-3.2772856694077146e-14` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,3].conc_mol_comp[Ce]' to a
numeric value `-3.57212991981993e-13` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,3].flow_mol_comp[Ce]' to a
numeric value `-1.0716389798118287e-14` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,1].conc_mass_comp[Nd]' to a
numeric value `-3.669787206827058e-09` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,1].conc_mol_comp[Nd]' to a
numeric value `-2.54417471269784e-14` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,1].flow_mol_comp[Nd]' to a
numeric value `-7.632529184413773e-16` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,3].conc_mass_comp[Gd]' to a
numeric value `-5.307607088822642e-07` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,2].conc_mass_comp[Gd]' to a
numeric value `-1.4309371714782985e-06` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,1].conc_mass_comp[Gd]' to a
numeric value `-2.7315364064454747e-06` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,1].conc_mol_comp[Gd]' to a
numeric value `-1.737066198353965e-11` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,1].flow_mol_comp[Gd]' to a
numeric value `-5.211198226412472e-13` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,2].conc_mol_comp[Gd]' to a
numeric value `-9.099759097804798e-12` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,2].flow_mol_comp[Gd]' to a
numeric value `-2.7299278289316664e-13` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,3].conc_mol_comp[Gd]' to a
numeric value `-3.3752671415626624e-12` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,3].flow_mol_comp[Gd]' to a
numeric value `-1.0125797769711118e-13` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
2026-06-29 11:23:02 [INFO] idaes.init.fs.solex_cleaner_strip.mscontactor: Stream Initialization Completed.
2026-06-29 11:23:02 [INFO] idaes.init.fs.solex_cleaner_strip.mscontactor: Initialization Completed, optimal - <undefined>
2026-06-29 11:23:02 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.cleaner_HCl_leach_translator
2026-06-29 11:23:02 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.solex_rougher_scrub
WARNING (W1002): Setting Var
'fs.solex_rougher_scrub.mscontactor.aqueous[0.0,1].conc_mass_comp[Al]' to a
numeric value `-5.373539777396408e-09` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_scrub.mscontactor.aqueous[0.0,1].conc_mol_comp[Al]' to a
numeric value `-1.9915421077639774e-13` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_scrub.mscontactor.aqueous[0.0,1].flow_mol_comp[Al]' to a
numeric value `-1.991484234464824e-14` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_scrub.mscontactor.aqueous[0.0,1].conc_mass_comp[Y]' to a
numeric value `-1.1652032545622514e-08` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_scrub.mscontactor.aqueous[0.0,1].conc_mol_comp[Y]' to a
numeric value `-1.3106114809925054e-13` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_scrub.mscontactor.aqueous[0.0,1].flow_mol_comp[Y]' to a
numeric value `-1.3106052701439272e-14` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_scrub.mscontactor.aqueous[0.0,1].conc_mass_comp[La]' to a
numeric value `-2.0721299861039885e-09` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_scrub.mscontactor.aqueous[0.0,1].conc_mol_comp[La]' to a
numeric value `-1.491758654179295e-14` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_scrub.mscontactor.aqueous[0.0,1].flow_mol_comp[La]' to a
numeric value `-1.4917537691228052e-15` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_scrub.mscontactor.aqueous[0.0,1].conc_mass_comp[Gd]' to a
numeric value `-2.327437992935657e-08` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_scrub.mscontactor.aqueous[0.0,1].conc_mol_comp[Gd]' to a
numeric value `-1.4800905669774322e-13` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_scrub.mscontactor.aqueous[0.0,1].flow_mol_comp[Gd]' to a
numeric value `-1.4800877537468615e-14` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_scrub.mscontactor.aqueous[0.0,1].conc_mass_comp[Dy]' to a
numeric value `-1.3296748957509564e-07` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_scrub.mscontactor.aqueous[0.0,1].conc_mol_comp[Dy]' to a
numeric value `-8.182597901815402e-13` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_scrub.mscontactor.aqueous[0.0,1].flow_mol_comp[Dy]' to a
numeric value `-8.182603900008799e-14` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
2026-06-29 11:23:02 [INFO] idaes.init.fs.solex_rougher_scrub.mscontactor: Stream Initialization Completed.
2026-06-29 11:23:02 [INFO] idaes.init.fs.solex_rougher_scrub.mscontactor: Initialization Completed, optimal - <undefined>
2026-06-29 11:23:02 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.load_sep
2026-06-29 11:23:03 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.sl_sep1
2026-06-29 11:23:03 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.precipitator
2026-06-29 11:23:03 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.leach_sx_mixer
2026-06-29 11:23:03 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.cleaner_sep
2026-06-29 11:23:03 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.solex_rougher_strip
WARNING (W1002): Setting Var
'fs.solex_rougher_strip.mscontactor.aqueous[0.0,1].conc_mass_comp[Y]' to a
numeric value `-2.562766639686921e-07` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_strip.mscontactor.aqueous[0.0,1].conc_mol_comp[Y]' to a
numeric value `-2.8825882410536405e-12` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_strip.mscontactor.aqueous[0.0,1].flow_mol_comp[Y]' to a
numeric value `-3.7473670000398585e-13` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_strip.mscontactor.aqueous[0.0,2].conc_mass_comp[Ce]' to a
numeric value `-1.4871335898585942e-08` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_strip.mscontactor.aqueous[0.0,1].conc_mass_comp[Ce]' to a
numeric value `-7.175298916778155e-08` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_strip.mscontactor.aqueous[0.0,1].conc_mol_comp[Ce]' to a
numeric value `-5.120974744073906e-13` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_strip.mscontactor.aqueous[0.0,1].flow_mol_comp[Ce]' to a
numeric value `-6.657261547582394e-14` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_strip.mscontactor.aqueous[0.0,2].conc_mol_comp[Ce]' to a
numeric value `-1.0613596463398301e-13` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_strip.mscontactor.aqueous[0.0,2].flow_mol_comp[Ce]' to a
numeric value `-1.3797665267267778e-14` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_strip.mscontactor.aqueous[0.0,1].conc_mass_comp[Nd]' to a
numeric value `-1.5871224996779604e-09` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_strip.mscontactor.aqueous[0.0,1].conc_mol_comp[Nd]' to a
numeric value `-1.100321056289167e-14` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_strip.mscontactor.aqueous[0.0,1].flow_mol_comp[Nd]' to a
numeric value `-1.4304150312144381e-15` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_strip.mscontactor.aqueous[0.0,1].conc_mass_comp[Gd]' to a
numeric value `-1.1742907370370155e-07` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_strip.mscontactor.aqueous[0.0,1].conc_mol_comp[Gd]' to a
numeric value `-7.467674470317085e-13` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_strip.mscontactor.aqueous[0.0,1].flow_mol_comp[Gd]' to a
numeric value `-9.707946252435204e-14` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_strip.mscontactor.aqueous[0.0,1].conc_mass_comp[Dy]' to a
numeric value `-2.847277535595592e-07` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_strip.mscontactor.aqueous[0.0,1].conc_mol_comp[Dy]' to a
numeric value `-1.7521737250857628e-12` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_strip.mscontactor.aqueous[0.0,1].flow_mol_comp[Dy]' to a
numeric value `-2.277822028218246e-13` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
2026-06-29 11:23:03 [INFO] idaes.init.fs.solex_rougher_strip.mscontactor: Stream Initialization Completed.
2026-06-29 11:23:04 [INFO] idaes.init.fs.solex_rougher_strip.mscontactor: Initialization Completed, optimal - <undefined>
2026-06-29 11:23:04 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.scrub_sep
2026-06-29 11:23:04 [INFO] idaes.init.fs.scrub_sep: Initialization Step 2 Complete: optimal - <undefined>
2026-06-29 11:23:04 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.sl_sep2
2026-06-29 11:23:04 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.cleaner_mixer
2026-06-29 11:23:04 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.rougher_sep
2026-06-29 11:23:04 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.scrubber_HCl_leach_translator
2026-06-29 11:23:04 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.precip_sep
2026-06-29 11:23:04 [INFO] idaes.init.fs.precip_sep: Initialization Step 2 Complete: optimal - <undefined>
2026-06-29 11:23:04 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.rougher_mixer
2026-06-29 11:23:04 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.leach_mixer
2026-06-29 11:23:05 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.precip_sx_mixer
WARNING (W1002): Setting Var
'fs.precip_sx_mixer.precip_state[0.0].flow_mol_comp[Sc]' to a numeric value
`-5.308855143197683e-12` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
2026-06-29 11:23:05 [INFO] idaes.init.fs.precip_sx_mixer: Initialization Complete: optimal - <undefined>
WARNING: Direct failed to converge in 1 iterations
2026-06-29 11:23:05 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.leach_filter_cake
2026-06-29 11:23:05 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.leach_filter_cake_liquid
2026-06-29 11:23:05 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.rougher_organic_purge
2026-06-29 11:23:05 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.cleaner_organic_purge
2026-06-29 11:23:05 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.roaster
2026-06-29 11:23:05 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.precip_purge
print(f"Total REE recovery is {value(m1.fs.overall_ree_recovery_percentage[0])} %")
Total REE recovery is 0.9049600258591484 %
Step 3: Write an optimization function to maximize REE recovery#
Now we want to write an optimization function that maximizes the total REE recovery. So we’ll need to write an objective function and unfix various operating conditions.
Step 3.1 Create objective function#
The objective function will maximize the REE recovery without using an excessive volume of reagents (leachate and acids) and limiting the amount of contaminants (aluminum, iron, and calcium) in the final product. We can model this by assigning penalties (positive or negative coefficients) to each of these quantities with the goal of minimizing the objective function. To maximize the REE recovery, we’ll set an arbitrarily large, negative coefficient for the REE product flow (m.fs.ree_product_flow). Since the purity of the final product is just as important as the mass of REEs recovered, we’ll assign an equally large, positive coefficient to minimize the total contaminants in the product flow. Lastly, we’ll assign a small penalty for using larger flow rates of reagents than necessary; otherwise, the objective function would increase the mass of REE recovered by simply inflating the flow of REEs coming into the system.
def create_objective(m):
# Goal: Minimize this objective function
m.obj = Objective(
expr=(
# Assign a small penalty for having larger flow rates than necessary
0.01
* (
m.fs.leach_liquid_feed.flow_vol[0]
+ m.fs.acid_feed1.flow_vol[0]
+ m.fs.acid_feed2.flow_vol[0]
+ m.fs.acid_feed3.flow_vol[0]
)
# Assign a large penalty for having contaminants
+ 1e5
* (
+m.fs.metal_product_flow[0, "Al"]
+ m.fs.metal_product_flow[0, "Ca"]
+ m.fs.metal_product_flow[0, "Fe"]
)
# Assign a large incentive for increasing REE product flow (REE recovery)
- 1e5 * m.fs.ree_product_flow[0]
)
)
Step 3.2 Unfix liquid feed conditions#
Now we have an objective function that we can use to optimize the system for REE recovery, but all of the system’s variables are still fixed. Thus, the next few steps will involve unfixing various operating conditions (design decisions) that the objective function can change, as it sees fit. To ensure the objective function does not give these variables unrealistic values, we’ll assign bounds and/or define constraints so that the optimized solution does not violate any laws of chemistry or explore scenarios outside the bounds of what we think is plausible.
We’ll start by unfixing the flow rate and concentration of the liquid leaching feed. Constraints are added to uphold chemistry, scaling is updated to lighten the burden on the solver, and a lower bound is set for the volumetric flow rate to ensure realistic operating conditions.
def optimize_liquid_feed(m):
# Unfix the H2SO4 feed rate and feed concentration
m.fs.leach_liquid_feed.flow_vol.unfix()
m.fs.leach_liquid_feed.properties[0].flow_vol.setlb(100)
m.fs.leach_liquid_feed.conc_mass_comp[0, "H"].unfix()
m.fs.leach_liquid_feed.conc_mass_comp[0, "HSO4"].unfix()
m.fs.leach_liquid_feed.conc_mass_comp[0, "SO4"].unfix()
# Ensure that stoichiometry is upheld
@m.fs.leach_liquid_feed.Constraint(m.fs.time)
def H2SO4_stoich_eqn(b, t):
return (
b.properties[t].conc_mol_comp["H"]
== 2 * b.properties[t].conc_mol_comp["SO4"]
+ b.properties[t].conc_mol_comp["HSO4"]
)
# Apply a scaling factor of 10 to conc_mol_comp values
for condata in m.fs.leach_liquid_feed.H2SO4_stoich_eqn.values():
set_scaling_factor(condata, 10)
# Ensure chemical equilibrium for HSO4 dissociation
@m.fs.leach_liquid_feed.Constraint(m.fs.time)
def HSO4_dissociation(b, t):
return (
b.properties[t].params.Ka2 * b.properties[t].conc_mol_comp["HSO4"]
== b.properties[t].conc_mol_comp["SO4"] * b.properties[t].conc_mol_comp["H"]
)
# Update scaling factors
sf = get_scaling_factor(m.fs.leach.mscontactor.liquid[0, 1].hso4_dissociation)
for condata in m.fs.leach_liquid_feed.HSO4_dissociation.values():
set_scaling_factor(condata, sf)
Step 3.3 Unfix organic feed conditions#
Similarly, we’ll unfix the flow rates and DEHPA concentration of the organic feed streams.
def optimize_organic_feed(m, DEHPA_ub=10):
m.fs.rougher_mixer.outlet.flow_vol.unfix()
m.fs.cleaner_mixer.outlet.flow_vol.unfix()
m.fs.rougher_org_make_up.conc_mass_comp[0, "DEHPA"].unfix()
m.fs.cleaner_org_make_up.conc_mass_comp[0, "DEHPA"].unfix()
m.fs.rougher_org_make_up.properties[0].extractant_dosage.bounds = (5, DEHPA_ub)
m.fs.cleaner_org_make_up.properties[0].extractant_dosage.bounds = (5, DEHPA_ub)
Step 3.4 Unfix acid feed conditions#
Now we’ll unfix the flow rates and concentrations of the acid feed streams, while ensuring the stoichiometry remains consistent.
def optimize_acid_feed(m):
# Unfix HCl feed flow rates and concentrations
for feed in [m.fs.acid_feed1, m.fs.acid_feed2, m.fs.acid_feed3]:
feed.flow_vol.unfix()
feed.conc_mass_comp[0, "H"].unfix()
feed.conc_mass_comp[0, "Cl"].unfix()
feed.properties[0].pH_phase["liquid"].setlb(0)
@feed.Constraint(m.fs.time)
def HCl_stoich_eqn(b, t):
return (
b.properties[t].conc_mol_comp["H"]
== b.properties[t].conc_mol_comp["Cl"]
)
for condata in feed.HCl_stoich_eqn.values():
set_scaling_factor(condata, 10)
Step 3.5 Set additional bounds on pH#
For the reasons specified directly above, we should also bound the pH of other streams.
def optimize_pH(m):
m.fs.leach_liquid_feed.properties[0].pH_phase["liquid"].setlb(0)
m.fs.solex_rougher_scrub.mscontactor.aqueous[0.0, 1].pH_phase["liquid"].setub(4)
Reference: Zhang, W., Xie, X., Tong, X., Du, Y., Song, Q., & Feng, D. (2021). Study on the effect and mechanism of impurity aluminum on the solvent extraction of rare earth elements (Nd, Pr, La) by P204-P350 in chloride solution. Minerals, 11(1), 61.
Step 3.5 Run the optimization#
Now we’ll simply create a function that combines all of the optimization-related functions into a single place.
def optimize_model(m, DEHPA_ub=10):
create_objective(m)
optimize_liquid_feed(m)
optimize_organic_feed(m, DEHPA_ub=DEHPA_ub)
optimize_acid_feed(m)
optimize_pH(m)
Then we’ll call the optimization function (optimize_model) to optimize the flowsheet and re-solve the system.
optimize_model(m1, DEHPA_ub=10)
uky.solve_system(m1, tee=False)
# Uncomment to display various system metrics like component recovery or leaching recovery
# uky.display_results(m1)
{'Problem': [{'Lower bound': None, 'Upper bound': -72.40363202525349, 'Number of objectives': 1, 'Number of constraints': nan, 'Number of variables': nan, 'Sense': 'minimize'}], 'Solver': [{'Status': 'ok', 'Termination condition': 'optimal', 'Termination message': 'TerminationCondition.convergenceCriteriaSatisfied'}]}
print(f"Total REE recovery is {value(m1.fs.overall_ree_recovery_percentage[0])} %")
Total REE recovery is 11.853435818889045 %
Step 4: Analyze the optimization results#
Now that we have the system solving at 10% DEHPA, we’ll need to update the tear guesses in the initialization routine so that we can try to solve the system at 20% DEHPA with a better starting point.
Step 4.1: Print the optimized conditions#
First, let’s display the values for the conditions optimized by the optimization function.
print(
f" The leach liquid feed flow is: {value(m1.fs.leach_liquid_feed.flow_vol[0]):.2f} L/hr"
)
print(
f" The leach liquid feed H concentration is: {value(m1.fs.leach_liquid_feed.conc_mass_comp[0, 'H']):.2f} mg/L"
)
print(
f" The leach liquid feed SO4 concentration is: {value(m1.fs.leach_liquid_feed.conc_mass_comp[0, 'SO4']):.2f} mg/L"
)
print(
f" The leach liquid feed HSO4 concentration is: {value(m1.fs.leach_liquid_feed.conc_mass_comp[0, 'HSO4']):.2f} mg/L \n"
)
print(
f" The SX Rougher organic make-up flow is: {value(m1.fs.rougher_org_make_up.flow_vol[0]):.2f} L/hr"
)
print(
f" The SX Cleaner organic make-up flow is: {value(m1.fs.rougher_org_make_up.flow_vol[0]):.2f} L/hr \n"
)
print(f" The acid feed 1 flow is: {value(m1.fs.acid_feed1.flow_vol[0])} L/hr")
print(
f" The acid feed 1 H concentration is: {value(m1.fs.acid_feed1.conc_mass_comp[0, 'H']):.2f} mg/L"
)
print(
f" The acid feed 1 Cl concentration is: {value(m1.fs.acid_feed1.conc_mass_comp[0, 'Cl']):.2f} mg/L \n"
)
print(f" The acid feed 2 flow is: {value(m1.fs.acid_feed2.flow_vol[0]):.2f} L/hr")
print(
f" The acid feed 2 H concentration is: {value(m1.fs.acid_feed2.conc_mass_comp[0, 'H']):.2f} mg/L"
)
print(
f" The acid feed 2 Cl concentration is: {value(m1.fs.acid_feed2.conc_mass_comp[0, 'Cl']):.2f} mg/L \n"
)
print(f" The acid feed 3 flow is: {value(m1.fs.acid_feed3.flow_vol[0]):.2f} L/hr")
print(
f" The acid feed 3 H concentration is: {value(m1.fs.acid_feed3.conc_mass_comp[0, 'H']):.2f} mg/L"
)
print(
f" The acid feed 3 Cl concentration is: {value(m1.fs.acid_feed3.conc_mass_comp[0, 'Cl']):.2f} mg/L"
)
The leach liquid feed flow is: 100.00 L/hr
The leach liquid feed H concentration is: 191.75 mg/L
The leach liquid feed SO4 concentration is: 887.63 mg/L
The leach liquid feed HSO4 concentration is: 16806.49 mg/L
The SX Rougher organic make-up flow is: 37.68 L/hr
The SX Cleaner organic make-up flow is: 37.68 L/hr
The acid feed 1 flow is: 2.607883614712462e-06 L/hr
The acid feed 1 H concentration is: 976.15 mg/L
The acid feed 1 Cl concentration is: 34332.81 mg/L
The acid feed 2 flow is: 3.87 L/hr
The acid feed 2 H concentration is: 1008.00 mg/L
The acid feed 2 Cl concentration is: 35453.00 mg/L
The acid feed 3 flow is: 4.01 L/hr
The acid feed 3 H concentration is: 1008.00 mg/L
The acid feed 3 Cl concentration is: 35453.00 mg/L
Step 4.2 Update the optimize_acid_feed function#
Let’s update the optimize_acid_feed function to fix the volumetric flow rate of acid_feed1 rather than trying to optimize it. It will be fixed at its default value specified in the flowsheet file (0.1 L/hr).
def optimize_acid_feed(m):
# Unfix HCl feed flow rates and concentrations
for feed in [m.fs.acid_feed1, m.fs.acid_feed2, m.fs.acid_feed3]:
# Trying to optimize acid_feed1 will bring its flow to zero, so we'll keep it fixed
if feed == m.fs.acid_feed1:
continue
else:
feed.flow_vol.unfix()
feed.conc_mass_comp[0, "H"].unfix()
feed.conc_mass_comp[0, "Cl"].unfix()
# Revisit how strong of an acid we can use
feed.properties[0].pH_phase["liquid"].setlb(0)
@feed.Constraint(m.fs.time)
def HCl_stoich_eqn(b, t):
return (
b.properties[t].conc_mol_comp["H"]
== b.properties[t].conc_mol_comp["Cl"]
)
for condata in feed.HCl_stoich_eqn.values():
set_scaling_factor(condata, 10)
Step 4.2 Re-run the optimization#
Let’s create a new model, m2, to represent this system, re-build the flowsheet, and then run optimization again.
m2 = uky.build()
uky.set_operating_conditions(m2, DEHPA_dosage=0.05)
uky.set_scaling(m2)
uky.initialize_system(m2)
uky.solve_system(m2, tee=False)
uky.fix_organic_recycle(m2)
uky.solve_system(m2, tee=False)
uky.add_result_expressions(m2)
Scaling fs.leach
Scaling fs.sl_sep1
Scaling fs.scrubber_HCl_leach_translator
Scaling fs.leach_mixer
Scaling fs.leach_liquid_feed
Scaling fs.leach_solid_feed
Scaling fs.leach_filter_cake
Scaling fs.leach_filter_cake_liquid
Scaling fs.rougher_org_make_up
Scaling fs.solex_rougher_load
Scaling fs.acid_feed1
Scaling fs.solex_rougher_scrub
Scaling fs.acid_feed2
Scaling fs.solex_rougher_strip
Scaling fs.rougher_sep
Scaling fs.rougher_mixer
Scaling fs.load_sep
Scaling fs.scrub_sep
Scaling fs.rougher_organic_purge
Scaling fs.solex_cleaner_load
Scaling fs.solex_cleaner_strip
Scaling fs.cleaner_org_make_up
Scaling fs.cleaner_mixer
Scaling fs.cleaner_sep
Scaling fs.cleaner_HCl_leach_translator
Scaling fs.leach_sx_mixer
Scaling fs.acid_feed3
Scaling fs.cleaner_organic_purge
Scaling fs.precipitator
Scaling fs.sl_sep2
Scaling fs.precip_sep
Scaling fs.precip_sx_mixer
Scaling fs.precip_purge
Scaling fs.roaster
Scaling fs.leaching_sol_feed_expanded
Scaling fs.leaching_liq_feed_expanded
Scaling fs.leaching_feed_mixture_expanded
Scaling fs.leaching_solid_outlet_expanded
Scaling fs.leaching_liquid_outlet_expanded
Scaling fs.sl_sep1_solid_outlet_expanded
Scaling fs.sl_sep1_retained_liquid_outlet_expanded
Scaling fs.sl_sep1_liquid_outlet_expanded
Scaling fs.sx_rougher_load_aq_feed_expanded
Scaling fs.sx_rougher_org_feed_expanded
Scaling fs.sx_rougher_mixed_org_recycle_expanded
Scaling fs.sx_rougher_load_aq_outlet_expanded
Scaling fs.sx_rougher_load_aq_recycle_expanded
Scaling fs.sx_rougher_load_org_outlet_expanded
Scaling fs.sx_rougher_scrub_acid_feed_expanded
Scaling fs.sx_rougher_scrub_aq_outlet_expanded
Scaling fs.sx_rougher_scrub_aq_translator_expanded
Scaling fs.translator_scrub_recycle_expanded
Scaling fs.sx_rougher_scrub_org_outlet_expanded
Scaling fs.sx_rougher_strip_acid_feed_expanded
Scaling fs.sx_rougher_strip_org_outlet_expanded
Scaling fs.sx_rougher_strip_org_purge_expanded
Scaling fs.sx_rougher_strip_org_recycle_expanded
Scaling fs.sx_rougher_strip_aq_outlet_expanded
Scaling fs.sx_cleaner_load_aq_feed_expanded
Scaling fs.sx_cleaner_org_feed_expanded
Scaling fs.sx_cleaner_mixed_org_recycle_expanded
Scaling fs.sx_cleaner_load_aq_outlet_translator_expanded
Scaling fs.sx_cleaner_load_translator_leach_sx_mixer_expanded
Scaling fs.sx_cleaner_strip_acid_feed_expanded
Scaling fs.sx_cleaner_load_org_outlet_expanded
Scaling fs.sx_cleaner_strip_org_outlet_expanded
Scaling fs.sx_cleaner_strip_org_purge_expanded
Scaling fs.sx_cleaner_strip_org_recycle_expanded
Scaling fs.sx_cleaner_strip_aq_precip_expanded
Scaling fs.precip_solid_outlet_expanded
Scaling fs.precip_aq_sl_sep2_expanded
Scaling fs.sl_sep2_solid_outlet_expanded
Scaling fs.sl_sep2_liquid_outlet_expanded
Scaling fs.sl_sep2_retained_liquid_roaster_expanded
Scaling fs.sl_sep2_aq_purge_expanded
Scaling fs.sl_sep2_aq_recycle_expanded
2026-06-29 11:23:10 [INFO] idaes.uky_flowsheet_low_recovery: Initialization Order: {_init_ord}
2026-06-29 11:23:10 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.leach_solid_feed
2026-06-29 11:23:10 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.leach_liquid_feed
2026-06-29 11:23:10 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.solex_rougher_load
2026-06-29 11:23:10 [INFO] idaes.init.fs.solex_rougher_load.mscontactor: Stream Initialization Completed.
2026-06-29 11:23:10 [INFO] idaes.init.fs.solex_rougher_load.mscontactor: Initialization Completed, optimal - <undefined>
2026-06-29 11:23:10 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.rougher_org_make_up
2026-06-29 11:23:10 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.acid_feed1
2026-06-29 11:23:10 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.acid_feed2
2026-06-29 11:23:10 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.solex_cleaner_load
2026-06-29 11:23:11 [INFO] idaes.init.fs.solex_cleaner_load.mscontactor: Stream Initialization Completed.
2026-06-29 11:23:11 [INFO] idaes.init.fs.solex_cleaner_load.mscontactor: Initialization Completed, optimal - <undefined>
2026-06-29 11:23:11 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.cleaner_org_make_up
2026-06-29 11:23:11 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.acid_feed3
2026-06-29 11:23:11 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.leach
2026-06-29 11:23:11 [INFO] idaes.init.fs.leach.mscontactor: Stream Initialization Completed.
2026-06-29 11:23:11 [INFO] idaes.init.fs.leach.mscontactor: Initialization Completed, optimal - <undefined>
2026-06-29 11:23:11 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.load_sep
2026-06-29 11:23:11 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.solex_rougher_scrub
2026-06-29 11:23:12 [INFO] idaes.init.fs.solex_rougher_scrub.mscontactor: Stream Initialization Completed.
2026-06-29 11:23:12 [INFO] idaes.init.fs.solex_rougher_scrub.mscontactor: Initialization Completed, optimal - <undefined>
2026-06-29 11:23:12 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.cleaner_HCl_leach_translator
2026-06-29 11:23:12 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.solex_cleaner_strip
2026-06-29 11:23:12 [INFO] idaes.init.fs.solex_cleaner_strip.mscontactor: Stream Initialization Completed.
2026-06-29 11:23:12 [INFO] idaes.init.fs.solex_cleaner_strip.mscontactor: Initialization Completed, optimal - <undefined>
2026-06-29 11:23:12 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.sl_sep1
2026-06-29 11:23:12 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.scrub_sep
2026-06-29 11:23:13 [INFO] idaes.init.fs.scrub_sep: Initialization Step 2 Complete: optimal - <undefined>
2026-06-29 11:23:13 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.solex_rougher_strip
2026-06-29 11:23:13 [INFO] idaes.init.fs.solex_rougher_strip.mscontactor: Stream Initialization Completed.
2026-06-29 11:23:13 [INFO] idaes.init.fs.solex_rougher_strip.mscontactor: Initialization Completed, optimal - <undefined>
2026-06-29 11:23:13 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.cleaner_sep
2026-06-29 11:23:13 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.precipitator
2026-06-29 11:23:13 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.leach_filter_cake
2026-06-29 11:23:13 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.leach_filter_cake_liquid
2026-06-29 11:23:13 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.leach_sx_mixer
2026-06-29 11:23:13 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.scrubber_HCl_leach_translator
2026-06-29 11:23:13 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.rougher_sep
2026-06-29 11:23:13 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.cleaner_mixer
2026-06-29 11:23:13 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.cleaner_organic_purge
2026-06-29 11:23:13 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.sl_sep2
2026-06-29 11:23:14 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.precip_sep
2026-06-29 11:23:14 [INFO] idaes.init.fs.precip_sep: Initialization Step 2 Complete: optimal - <undefined>
2026-06-29 11:23:14 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.leach_mixer
2026-06-29 11:23:14 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.rougher_mixer
2026-06-29 11:23:14 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.rougher_organic_purge
2026-06-29 11:23:14 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.roaster
2026-06-29 11:23:14 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.precip_purge
2026-06-29 11:23:14 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.precip_sx_mixer
2026-06-29 11:23:14 [INFO] idaes.init.fs.precip_sx_mixer: Initialization Complete: optimal - <undefined>
2026-06-29 11:23:14 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.leach_solid_feed
2026-06-29 11:23:14 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.leach_liquid_feed
2026-06-29 11:23:14 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.rougher_org_make_up
2026-06-29 11:23:14 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.acid_feed1
2026-06-29 11:23:14 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.acid_feed2
2026-06-29 11:23:15 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.cleaner_org_make_up
2026-06-29 11:23:15 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.acid_feed3
2026-06-29 11:23:15 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.solex_cleaner_load
2026-06-29 11:23:15 [INFO] idaes.init.fs.solex_cleaner_load.mscontactor: Stream Initialization Completed.
2026-06-29 11:23:15 [INFO] idaes.init.fs.solex_cleaner_load.mscontactor: Initialization Completed, optimal - <undefined>
2026-06-29 11:23:15 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.solex_rougher_load
2026-06-29 11:23:15 [INFO] idaes.init.fs.solex_rougher_load.mscontactor: Stream Initialization Completed.
2026-06-29 11:23:15 [INFO] idaes.init.fs.solex_rougher_load.mscontactor: Initialization Completed, optimal - <undefined>
2026-06-29 11:23:15 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.leach
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,1].conversion_comp[Sc2O3]' to a numeric value
`-8.39508749947673e-09` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,1].conversion_comp[Y2O3]' to a numeric value
`-5.554896289474591e-09` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,1].conversion_comp[Pr2O3]' to a numeric value
`-1.9851327705076312e-08` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,1].conversion_comp[Sm2O3]' to a numeric value
`-2.4603533721480436e-08` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,1].conversion_comp[Gd2O3]' to a numeric value
`-3.922440689474765e-08` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,1].conversion_comp[Dy2O3]' to a numeric value
`-5.784556213406547e-08` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,2].conversion_comp[Y2O3]' to a numeric value
`-4.612734358929686e-08` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,2].conversion_comp[La2O3]' to a numeric value
`-1.7118508850188173e-08` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,2].conversion_comp[Ce2O3]' to a numeric value
`-1.6617558214273316e-09` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,2].conversion_comp[Pr2O3]' to a numeric value
`-9.775264216386736e-08` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,2].conversion_comp[Nd2O3]' to a numeric value
`-1.7162725927342594e-08` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,2].conversion_comp[Sm2O3]' to a numeric value
`-1.1493075758028818e-07` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,2].conversion_comp[Gd2O3]' to a numeric value
`-1.6768875575544955e-07` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,2].conversion_comp[Dy2O3]' to a numeric value
`-2.3496518629329045e-07` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,2].conversion_comp[Sc2O3]' to a numeric value
`-5.639046511099609e-08` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
2026-06-29 11:23:16 [INFO] idaes.init.fs.leach.mscontactor: Stream Initialization Completed.
2026-06-29 11:23:16 [INFO] idaes.init.fs.leach.mscontactor: Initialization Completed, optimal - <undefined>
2026-06-29 11:23:16 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.solex_cleaner_strip
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,2].conc_mass_comp[Y]' to a
numeric value `-1.4853771878321977e-07` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,1].conc_mass_comp[Y]' to a
numeric value `-1.618981210901991e-06` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,1].conc_mol_comp[Y]' to a
numeric value `-1.8210236313333542e-11` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,1].flow_mol_comp[Y]' to a
numeric value `-5.463071401506925e-13` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,2].conc_mol_comp[Y]' to a
numeric value `-1.6707470355868944e-12` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,2].flow_mol_comp[Y]' to a
numeric value `-5.012234117335311e-14` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,3].conc_mass_comp[La]' to a
numeric value `-4.454542171227379e-08` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,1].conc_mass_comp[La]' to a
numeric value `-2.4660036392662285e-08` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,1].conc_mol_comp[La]' to a
numeric value `-1.775315872935924e-13` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,1].flow_mol_comp[La]' to a
numeric value `-5.325946660691277e-15` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,3].conc_mol_comp[La]' to a
numeric value `-3.20689796944284e-13` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,3].flow_mol_comp[La]' to a
numeric value `-9.620695082604436e-15` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,3].conc_mass_comp[Ce]' to a
numeric value `-5.005125578010475e-08` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,2].conc_mass_comp[Ce]' to a
numeric value `-1.530667196900397e-07` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,1].conc_mass_comp[Ce]' to a
numeric value `-3.3382136149787053e-07` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,1].conc_mol_comp[Ce]' to a
numeric value `-2.382464255790752e-12` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,1].flow_mol_comp[Ce]' to a
numeric value `-7.147392757939769e-14` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,2].conc_mol_comp[Ce]' to a
numeric value `-1.092428471788867e-12` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,2].flow_mol_comp[Ce]' to a
numeric value `-3.2772856694077146e-14` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,3].conc_mol_comp[Ce]' to a
numeric value `-3.57212991981993e-13` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,3].flow_mol_comp[Ce]' to a
numeric value `-1.0716389798118287e-14` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,1].conc_mass_comp[Nd]' to a
numeric value `-3.669787206827058e-09` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,1].conc_mol_comp[Nd]' to a
numeric value `-2.54417471269784e-14` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,1].flow_mol_comp[Nd]' to a
numeric value `-7.632529184413773e-16` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,3].conc_mass_comp[Gd]' to a
numeric value `-5.307607088822642e-07` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,2].conc_mass_comp[Gd]' to a
numeric value `-1.4309371714782985e-06` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,1].conc_mass_comp[Gd]' to a
numeric value `-2.7315364064454747e-06` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,1].conc_mol_comp[Gd]' to a
numeric value `-1.737066198353965e-11` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,1].flow_mol_comp[Gd]' to a
numeric value `-5.211198226412472e-13` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,2].conc_mol_comp[Gd]' to a
numeric value `-9.099759097804798e-12` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,2].flow_mol_comp[Gd]' to a
numeric value `-2.7299278289316664e-13` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,3].conc_mol_comp[Gd]' to a
numeric value `-3.3752671415626624e-12` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_cleaner_strip.mscontactor.aqueous[0.0,3].flow_mol_comp[Gd]' to a
numeric value `-1.0125797769711118e-13` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
2026-06-29 11:23:16 [INFO] idaes.init.fs.solex_cleaner_strip.mscontactor: Stream Initialization Completed.
2026-06-29 11:23:16 [INFO] idaes.init.fs.solex_cleaner_strip.mscontactor: Initialization Completed, optimal - <undefined>
2026-06-29 11:23:16 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.cleaner_HCl_leach_translator
2026-06-29 11:23:16 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.solex_rougher_scrub
WARNING (W1002): Setting Var
'fs.solex_rougher_scrub.mscontactor.aqueous[0.0,1].conc_mass_comp[Al]' to a
numeric value `-5.373539777396408e-09` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_scrub.mscontactor.aqueous[0.0,1].conc_mol_comp[Al]' to a
numeric value `-1.9915421077639774e-13` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_scrub.mscontactor.aqueous[0.0,1].flow_mol_comp[Al]' to a
numeric value `-1.991484234464824e-14` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_scrub.mscontactor.aqueous[0.0,1].conc_mass_comp[Y]' to a
numeric value `-1.1652032545622514e-08` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_scrub.mscontactor.aqueous[0.0,1].conc_mol_comp[Y]' to a
numeric value `-1.3106114809925054e-13` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_scrub.mscontactor.aqueous[0.0,1].flow_mol_comp[Y]' to a
numeric value `-1.3106052701439272e-14` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_scrub.mscontactor.aqueous[0.0,1].conc_mass_comp[La]' to a
numeric value `-2.0721299861039885e-09` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_scrub.mscontactor.aqueous[0.0,1].conc_mol_comp[La]' to a
numeric value `-1.491758654179295e-14` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_scrub.mscontactor.aqueous[0.0,1].flow_mol_comp[La]' to a
numeric value `-1.4917537691228052e-15` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_scrub.mscontactor.aqueous[0.0,1].conc_mass_comp[Gd]' to a
numeric value `-2.327437992935657e-08` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_scrub.mscontactor.aqueous[0.0,1].conc_mol_comp[Gd]' to a
numeric value `-1.4800905669774322e-13` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_scrub.mscontactor.aqueous[0.0,1].flow_mol_comp[Gd]' to a
numeric value `-1.4800877537468615e-14` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_scrub.mscontactor.aqueous[0.0,1].conc_mass_comp[Dy]' to a
numeric value `-1.3296748957509564e-07` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_scrub.mscontactor.aqueous[0.0,1].conc_mol_comp[Dy]' to a
numeric value `-8.182597901815402e-13` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_scrub.mscontactor.aqueous[0.0,1].flow_mol_comp[Dy]' to a
numeric value `-8.182603900008799e-14` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
2026-06-29 11:23:16 [INFO] idaes.init.fs.solex_rougher_scrub.mscontactor: Stream Initialization Completed.
2026-06-29 11:23:17 [INFO] idaes.init.fs.solex_rougher_scrub.mscontactor: Initialization Completed, optimal - <undefined>
2026-06-29 11:23:17 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.load_sep
2026-06-29 11:23:17 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.sl_sep1
2026-06-29 11:23:17 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.precipitator
2026-06-29 11:23:17 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.leach_sx_mixer
2026-06-29 11:23:17 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.cleaner_sep
2026-06-29 11:23:17 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.solex_rougher_strip
WARNING (W1002): Setting Var
'fs.solex_rougher_strip.mscontactor.aqueous[0.0,1].conc_mass_comp[Y]' to a
numeric value `-2.562766639686921e-07` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_strip.mscontactor.aqueous[0.0,1].conc_mol_comp[Y]' to a
numeric value `-2.8825882410536405e-12` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_strip.mscontactor.aqueous[0.0,1].flow_mol_comp[Y]' to a
numeric value `-3.7473670000398585e-13` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_strip.mscontactor.aqueous[0.0,2].conc_mass_comp[Ce]' to a
numeric value `-1.4871335898585942e-08` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_strip.mscontactor.aqueous[0.0,1].conc_mass_comp[Ce]' to a
numeric value `-7.175298916778155e-08` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_strip.mscontactor.aqueous[0.0,1].conc_mol_comp[Ce]' to a
numeric value `-5.120974744073906e-13` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_strip.mscontactor.aqueous[0.0,1].flow_mol_comp[Ce]' to a
numeric value `-6.657261547582394e-14` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_strip.mscontactor.aqueous[0.0,2].conc_mol_comp[Ce]' to a
numeric value `-1.0613596463398301e-13` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_strip.mscontactor.aqueous[0.0,2].flow_mol_comp[Ce]' to a
numeric value `-1.3797665267267778e-14` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_strip.mscontactor.aqueous[0.0,1].conc_mass_comp[Nd]' to a
numeric value `-1.5871224996779604e-09` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_strip.mscontactor.aqueous[0.0,1].conc_mol_comp[Nd]' to a
numeric value `-1.100321056289167e-14` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_strip.mscontactor.aqueous[0.0,1].flow_mol_comp[Nd]' to a
numeric value `-1.4304150312144381e-15` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_strip.mscontactor.aqueous[0.0,1].conc_mass_comp[Gd]' to a
numeric value `-1.1742907370370155e-07` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_strip.mscontactor.aqueous[0.0,1].conc_mol_comp[Gd]' to a
numeric value `-7.467674470317085e-13` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_strip.mscontactor.aqueous[0.0,1].flow_mol_comp[Gd]' to a
numeric value `-9.707946252435204e-14` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_strip.mscontactor.aqueous[0.0,1].conc_mass_comp[Dy]' to a
numeric value `-2.847277535595592e-07` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_strip.mscontactor.aqueous[0.0,1].conc_mol_comp[Dy]' to a
numeric value `-1.7521737250857628e-12` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_strip.mscontactor.aqueous[0.0,1].flow_mol_comp[Dy]' to a
numeric value `-2.277822028218246e-13` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
2026-06-29 11:23:18 [INFO] idaes.init.fs.solex_rougher_strip.mscontactor: Stream Initialization Completed.
2026-06-29 11:23:18 [INFO] idaes.init.fs.solex_rougher_strip.mscontactor: Initialization Completed, optimal - <undefined>
2026-06-29 11:23:18 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.scrub_sep
2026-06-29 11:23:18 [INFO] idaes.init.fs.scrub_sep: Initialization Step 2 Complete: optimal - <undefined>
2026-06-29 11:23:18 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.sl_sep2
2026-06-29 11:23:18 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.cleaner_mixer
2026-06-29 11:23:18 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.rougher_sep
2026-06-29 11:23:18 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.scrubber_HCl_leach_translator
2026-06-29 11:23:18 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.precip_sep
2026-06-29 11:23:18 [INFO] idaes.init.fs.precip_sep: Initialization Step 2 Complete: optimal - <undefined>
2026-06-29 11:23:18 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.rougher_mixer
2026-06-29 11:23:18 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.leach_mixer
2026-06-29 11:23:19 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.precip_sx_mixer
WARNING (W1002): Setting Var
'fs.precip_sx_mixer.precip_state[0.0].flow_mol_comp[Sc]' to a numeric value
`-5.308855143197683e-12` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
2026-06-29 11:23:19 [INFO] idaes.init.fs.precip_sx_mixer: Initialization Complete: optimal - <undefined>
WARNING: Direct failed to converge in 1 iterations
2026-06-29 11:23:19 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.leach_filter_cake
2026-06-29 11:23:19 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.leach_filter_cake_liquid
2026-06-29 11:23:19 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.rougher_organic_purge
2026-06-29 11:23:19 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.cleaner_organic_purge
2026-06-29 11:23:19 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.roaster
2026-06-29 11:23:19 [INFO] idaes.uky_flowsheet_low_recovery: Initializing fs.precip_purge
optimize_model(m2, DEHPA_ub=10)
uky.solve_system(m2, tee=False)
# Uncomment to display various system metrics like component recovery or leaching recovery
# uky.display_results(m2)
{'Problem': [{'Lower bound': None, 'Upper bound': -70.71927081062844, 'Number of objectives': 1, 'Number of constraints': nan, 'Number of variables': nan, 'Sense': 'minimize'}], 'Solver': [{'Status': 'ok', 'Termination condition': 'optimal', 'Termination message': 'TerminationCondition.convergenceCriteriaSatisfied'}]}
Step 4.3 Reprint total recovery#
print(f"Total REE recovery is {value(m2.fs.overall_ree_recovery_percentage[0])} %")
Total REE recovery is 11.703180792039857 %
Step 5: Update the base conditions of the flowsheet#
Now that we have the system successfully solving again at 10% DEHPA, we’ll want to update the operating conditions to match the specs of the optimized system above. In order to do so, we’ll need to update the initialization routine, which is currently hard-coding initial guesses based on the unoptimized system.
Step 5.1 Print optimized operating conditions#
Print the optimized variable values from m2.
print(
f" The leach liquid feed flow is: {value(m2.fs.leach_liquid_feed.flow_vol[0]):.2f} L/hr"
)
print(
f" The leach liquid feed H concentration is: {value(m2.fs.leach_liquid_feed.conc_mass_comp[0, 'H']):.2f} mg/L"
)
print(
f" The leach liquid feed SO4 concentration is: {value(m2.fs.leach_liquid_feed.conc_mass_comp[0, 'SO4']):.2f} mg/L"
)
print(
f" The leach liquid feed HSO4 concentration is: {value(m2.fs.leach_liquid_feed.conc_mass_comp[0, 'HSO4']):.2f} mg/L \n"
)
print(
f" The SX Rougher organic make-up flow is: {value(m2.fs.rougher_org_make_up.flow_vol[0]):.2f} L/hr"
)
print(
f" The SX Cleaner organic make-up flow is: {value(m2.fs.rougher_org_make_up.flow_vol[0]):.2f} L/hr \n"
)
print(f" The acid feed 1 flow is: {value(m2.fs.acid_feed1.flow_vol[0]):.2f} L/hr")
print(
f" The acid feed 1 H concentration is: {value(m2.fs.acid_feed1.conc_mass_comp[0, 'H']):.2f} mg/L"
)
print(
f" The acid feed 1 Cl concentration is: {value(m2.fs.acid_feed1.conc_mass_comp[0, 'Cl']):.2f} mg/L \n"
)
print(f" The acid feed 2 flow is: {value(m2.fs.acid_feed2.flow_vol[0]):.2f} L/hr")
print(
f" The acid feed 2 H concentration is: {value(m2.fs.acid_feed2.conc_mass_comp[0, 'H']):.2f} mg/L"
)
print(
f" The acid feed 2 Cl concentration is: {value(m2.fs.acid_feed2.conc_mass_comp[0, 'Cl']):.2f} mg/L \n"
)
print(f" The acid feed 3 flow is: {value(m2.fs.acid_feed3.flow_vol[0]):.2f} L/hr")
print(
f" The acid feed 3 H concentration is: {value(m2.fs.acid_feed3.conc_mass_comp[0, 'H']):.2f} mg/L"
)
print(
f" The acid feed 3 Cl concentration is: {value(m2.fs.acid_feed3.conc_mass_comp[0, 'Cl']):.2f} mg/L"
)
The leach liquid feed flow is: 100.00 L/hr
The leach liquid feed H concentration is: 194.47 mg/L
The leach liquid feed SO4 concentration is: 888.82 mg/L
The leach liquid feed HSO4 concentration is: 17067.63 mg/L
The SX Rougher organic make-up flow is: 40.03 L/hr
The SX Cleaner organic make-up flow is: 40.03 L/hr
The acid feed 1 flow is: 0.10 L/hr
The acid feed 1 H concentration is: 1023.00 mg/L
The acid feed 1 Cl concentration is: 35980.00 mg/L
The acid feed 2 flow is: 4.03 L/hr
The acid feed 2 H concentration is: 1008.00 mg/L
The acid feed 2 Cl concentration is: 35453.00 mg/L
The acid feed 3 flow is: 4.19 L/hr
The acid feed 3 H concentration is: 1008.00 mg/L
The acid feed 3 Cl concentration is: 35453.00 mg/L
Step 5.2: Update the operating conditions#
Let’s create a new instance of the flowsheet, m3, and update the operating conditions to match those of the optimized case in m2.
m3 = uky.build()
uky.set_operating_conditions(m3, DEHPA_dosage=0.1)
m3.fs.leach_liquid_feed.flow_vol.fix(100)
m3.fs.leach_liquid_feed.conc_mass_comp[0, "H"].fix(194.5)
m3.fs.leach_liquid_feed.conc_mass_comp[0, "HSO4"].fix(17067.6)
m3.fs.leach_liquid_feed.conc_mass_comp[0, "SO4"].fix(888.8)
m3.fs.rougher_org_make_up.flow_vol.fix(40.03)
m3.fs.cleaner_org_make_up.flow_vol.fix(73.75)
m3.fs.acid_feed1.flow_vol.fix(0.1)
m3.fs.acid_feed1.conc_mass_comp[0, "H"].fix(1023)
m3.fs.acid_feed1.conc_mass_comp[0, "Cl"].fix(35980)
m3.fs.acid_feed2.flow_vol.fix(4.03)
m3.fs.acid_feed2.conc_mass_comp[0, "H"].fix(1008)
m3.fs.acid_feed2.conc_mass_comp[0, "Cl"].fix(35453)
m3.fs.acid_feed3.flow_vol.fix(4.19)
m3.fs.acid_feed3.conc_mass_comp[0, "H"].fix(1008)
m3.fs.acid_feed3.conc_mass_comp[0, "Cl"].fix(35453)
uky.set_scaling(m3)
Scaling fs.leach
Scaling fs.sl_sep1
Scaling fs.scrubber_HCl_leach_translator
Scaling fs.leach_mixer
Scaling fs.leach_liquid_feed
Scaling fs.leach_solid_feed
Scaling fs.leach_filter_cake
Scaling fs.leach_filter_cake_liquid
Scaling fs.rougher_org_make_up
Scaling fs.solex_rougher_load
Scaling fs.acid_feed1
Scaling fs.solex_rougher_scrub
Scaling fs.acid_feed2
Scaling fs.solex_rougher_strip
Scaling fs.rougher_sep
Scaling fs.rougher_mixer
Scaling fs.load_sep
Scaling fs.scrub_sep
Scaling fs.rougher_organic_purge
Scaling fs.solex_cleaner_load
Scaling fs.solex_cleaner_strip
Scaling fs.cleaner_org_make_up
Scaling fs.cleaner_mixer
Scaling fs.cleaner_sep
Scaling fs.cleaner_HCl_leach_translator
Scaling fs.leach_sx_mixer
Scaling fs.acid_feed3
Scaling fs.cleaner_organic_purge
Scaling fs.precipitator
Scaling fs.sl_sep2
Scaling fs.precip_sep
Scaling fs.precip_sx_mixer
Scaling fs.precip_purge
Scaling fs.roaster
Scaling fs.leaching_sol_feed_expanded
Scaling fs.leaching_liq_feed_expanded
Scaling fs.leaching_feed_mixture_expanded
Scaling fs.leaching_solid_outlet_expanded
Scaling fs.leaching_liquid_outlet_expanded
Scaling fs.sl_sep1_solid_outlet_expanded
Scaling fs.sl_sep1_retained_liquid_outlet_expanded
Scaling fs.sl_sep1_liquid_outlet_expanded
Scaling fs.sx_rougher_load_aq_feed_expanded
Scaling fs.sx_rougher_org_feed_expanded
Scaling fs.sx_rougher_mixed_org_recycle_expanded
Scaling fs.sx_rougher_load_aq_outlet_expanded
Scaling fs.sx_rougher_load_aq_recycle_expanded
Scaling fs.sx_rougher_load_org_outlet_expanded
Scaling fs.sx_rougher_scrub_acid_feed_expanded
Scaling fs.sx_rougher_scrub_aq_outlet_expanded
Scaling fs.sx_rougher_scrub_aq_translator_expanded
Scaling fs.translator_scrub_recycle_expanded
Scaling fs.sx_rougher_scrub_org_outlet_expanded
Scaling fs.sx_rougher_strip_acid_feed_expanded
Scaling fs.sx_rougher_strip_org_outlet_expanded
Scaling fs.sx_rougher_strip_org_purge_expanded
Scaling fs.sx_rougher_strip_org_recycle_expanded
Scaling fs.sx_rougher_strip_aq_outlet_expanded
Scaling fs.sx_cleaner_load_aq_feed_expanded
Scaling fs.sx_cleaner_org_feed_expanded
Scaling fs.sx_cleaner_mixed_org_recycle_expanded
Scaling fs.sx_cleaner_load_aq_outlet_translator_expanded
Scaling fs.sx_cleaner_load_translator_leach_sx_mixer_expanded
Scaling fs.sx_cleaner_strip_acid_feed_expanded
Scaling fs.sx_cleaner_load_org_outlet_expanded
Scaling fs.sx_cleaner_strip_org_outlet_expanded
Scaling fs.sx_cleaner_strip_org_purge_expanded
Scaling fs.sx_cleaner_strip_org_recycle_expanded
Scaling fs.sx_cleaner_strip_aq_precip_expanded
Scaling fs.precip_solid_outlet_expanded
Scaling fs.precip_aq_sl_sep2_expanded
Scaling fs.sl_sep2_solid_outlet_expanded
Scaling fs.sl_sep2_liquid_outlet_expanded
Scaling fs.sl_sep2_retained_liquid_roaster_expanded
Scaling fs.sl_sep2_aq_purge_expanded
Scaling fs.sl_sep2_aq_recycle_expanded
Step 5.3: Update tear guesses#
Here we recreate the entire initialization routine, but the only portion of this that is changing from the original implementation are the values for the tear guesses. Rather than just hard-coding new values, we will simply set the tear guesses equal to the value of the corresponding variable in m2 to represent the new starting points.
def updated_initialization(m, ref=m2.fs):
seq = SequentialDecomposition()
seq.options.tear_method = "Direct"
seq.options.iterLim = 1
seq.options.tear_set = [
m.fs.leaching_feed_mixture,
m.fs.sx_rougher_load_aq_feed,
m.fs.sx_rougher_mixed_org_recycle,
m.fs.sx_cleaner_load_aq_feed,
m.fs.sx_cleaner_mixed_org_recycle,
]
tear_guesses1 = {
"flow_vol": {0: value(ref.leach.liquid_inlet.flow_vol[0])},
"conc_mass_comp": {
(0, "Al"): value(ref.leach.liquid_inlet.conc_mass_comp[0, "Al"]),
(0, "Ca"): value(ref.leach.liquid_inlet.conc_mass_comp[0, "Ca"]),
(0, "Ce"): value(ref.leach.liquid_inlet.conc_mass_comp[0, "Ce"]),
(0, "Cl"): value(ref.leach.liquid_inlet.conc_mass_comp[0, "Cl"]),
(0, "Dy"): value(ref.leach.liquid_inlet.conc_mass_comp[0, "Dy"]),
(0, "Fe"): value(ref.leach.liquid_inlet.conc_mass_comp[0, "Fe"]),
(0, "Gd"): value(ref.leach.liquid_inlet.conc_mass_comp[0, "Gd"]),
(0, "H"): value(ref.leach.liquid_inlet.conc_mass_comp[0, "H"]),
(0, "H2O"): value(ref.leach.liquid_inlet.conc_mass_comp[0, "H2O"]),
(0, "HSO4"): value(ref.leach.liquid_inlet.conc_mass_comp[0, "HSO4"]),
(0, "La"): value(ref.leach.liquid_inlet.conc_mass_comp[0, "La"]),
(0, "Nd"): value(ref.leach.liquid_inlet.conc_mass_comp[0, "Nd"]),
(0, "Pr"): value(ref.leach.liquid_inlet.conc_mass_comp[0, "Pr"]),
(0, "SO4"): value(ref.leach.liquid_inlet.conc_mass_comp[0, "SO4"]),
(0, "Sc"): value(ref.leach.liquid_inlet.conc_mass_comp[0, "Sc"]),
(0, "Sm"): value(ref.leach.liquid_inlet.conc_mass_comp[0, "Sm"]),
(0, "Y"): value(ref.leach.liquid_inlet.conc_mass_comp[0, "Y"]),
},
}
tear_guesses2 = {
"flow_vol": {0: value(ref.solex_rougher_load.organic_inlet.flow_vol[0])},
"conc_mass_comp": {
(0, "Al_o"): value(
ref.solex_rougher_load.organic_inlet.conc_mass_comp[0, "Al_o"]
),
(0, "Ca_o"): value(
ref.solex_rougher_load.organic_inlet.conc_mass_comp[0, "Ca_o"]
),
(0, "Ce_o"): value(
ref.solex_rougher_load.organic_inlet.conc_mass_comp[0, "Ce_o"]
),
(0, "Dy_o"): value(
ref.solex_rougher_load.organic_inlet.conc_mass_comp[0, "Dy_o"]
),
(0, "Fe_o"): value(
ref.solex_rougher_load.organic_inlet.conc_mass_comp[0, "Fe_o"]
),
(0, "Gd_o"): value(
ref.solex_rougher_load.organic_inlet.conc_mass_comp[0, "Gd_o"]
),
(0, "La_o"): value(
ref.solex_rougher_load.organic_inlet.conc_mass_comp[0, "La_o"]
),
(0, "Nd_o"): value(
ref.solex_rougher_load.organic_inlet.conc_mass_comp[0, "Nd_o"]
),
(0, "Pr_o"): value(
ref.solex_rougher_load.organic_inlet.conc_mass_comp[0, "Pr_o"]
),
(0, "Sc_o"): value(
ref.solex_rougher_load.organic_inlet.conc_mass_comp[0, "Sc_o"]
),
(0, "Sm_o"): value(
ref.solex_rougher_load.organic_inlet.conc_mass_comp[0, "Sm_o"]
),
(0, "Y_o"): value(
ref.solex_rougher_load.organic_inlet.conc_mass_comp[0, "Y_o"]
),
(0, "DEHPA"): value(
ref.solex_rougher_load.organic_inlet.conc_mass_comp[0, "DEHPA"]
),
(0, "Kerosene"): value(
ref.solex_rougher_load.organic_inlet.conc_mass_comp[0, "Kerosene"]
),
},
}
tear_guesses3 = {
"flow_vol": {0: value(ref.solex_rougher_load.aqueous_inlet.flow_vol[0])},
"conc_mass_comp": {
(0, "Al"): value(
ref.solex_rougher_load.aqueous_inlet.conc_mass_comp[0, "Al"]
),
(0, "Ca"): value(
ref.solex_rougher_load.aqueous_inlet.conc_mass_comp[0, "Ca"]
),
(0, "Ce"): value(
ref.solex_rougher_load.aqueous_inlet.conc_mass_comp[0, "Ce"]
),
(0, "Cl"): value(
ref.solex_rougher_load.aqueous_inlet.conc_mass_comp[0, "Cl"]
),
(0, "Dy"): value(
ref.solex_rougher_load.aqueous_inlet.conc_mass_comp[0, "Dy"]
),
(0, "Fe"): value(
ref.solex_rougher_load.aqueous_inlet.conc_mass_comp[0, "Fe"]
),
(0, "Gd"): value(
ref.solex_rougher_load.aqueous_inlet.conc_mass_comp[0, "Gd"]
),
(0, "H"): value(
ref.solex_rougher_load.aqueous_inlet.conc_mass_comp[0, "H"]
),
(0, "H2O"): value(
ref.solex_rougher_load.aqueous_inlet.conc_mass_comp[0, "H2O"]
),
(0, "HSO4"): value(
ref.solex_rougher_load.aqueous_inlet.conc_mass_comp[0, "HSO4"]
),
(0, "La"): value(
ref.solex_rougher_load.aqueous_inlet.conc_mass_comp[0, "La"]
),
(0, "Nd"): value(
ref.solex_rougher_load.aqueous_inlet.conc_mass_comp[0, "Nd"]
),
(0, "Pr"): value(
ref.solex_rougher_load.aqueous_inlet.conc_mass_comp[0, "Pr"]
),
(0, "SO4"): value(
ref.solex_rougher_load.aqueous_inlet.conc_mass_comp[0, "SO4"]
),
(0, "Sc"): value(
ref.solex_rougher_load.aqueous_inlet.conc_mass_comp[0, "Sc"]
),
(0, "Sm"): value(
ref.solex_rougher_load.aqueous_inlet.conc_mass_comp[0, "Sm"]
),
(0, "Y"): value(
ref.solex_rougher_load.aqueous_inlet.conc_mass_comp[0, "Y"]
),
},
}
tear_guesses4 = {
"flow_vol": {0: value(ref.solex_cleaner_load.organic_inlet.flow_vol[0])},
"conc_mass_comp": {
(0, "Al_o"): value(
ref.solex_cleaner_load.organic_inlet.conc_mass_comp[0, "Al_o"]
),
(0, "Ca_o"): value(
ref.solex_cleaner_load.organic_inlet.conc_mass_comp[0, "Ca_o"]
),
(0, "Ce_o"): value(
ref.solex_cleaner_load.organic_inlet.conc_mass_comp[0, "Ce_o"]
),
(0, "Dy_o"): value(
ref.solex_cleaner_load.organic_inlet.conc_mass_comp[0, "Dy_o"]
),
(0, "Fe_o"): value(
ref.solex_cleaner_load.organic_inlet.conc_mass_comp[0, "Fe_o"]
),
(0, "Gd_o"): value(
ref.solex_cleaner_load.organic_inlet.conc_mass_comp[0, "Gd_o"]
),
(0, "La_o"): value(
ref.solex_cleaner_load.organic_inlet.conc_mass_comp[0, "La_o"]
),
(0, "Nd_o"): value(
ref.solex_cleaner_load.organic_inlet.conc_mass_comp[0, "Nd_o"]
),
(0, "Pr_o"): value(
ref.solex_cleaner_load.organic_inlet.conc_mass_comp[0, "Pr_o"]
),
(0, "Sc_o"): value(
ref.solex_cleaner_load.organic_inlet.conc_mass_comp[0, "Sc_o"]
),
(0, "Sm_o"): value(
ref.solex_cleaner_load.organic_inlet.conc_mass_comp[0, "Sm_o"]
),
(0, "Y_o"): value(
ref.solex_cleaner_load.organic_inlet.conc_mass_comp[0, "Y_o"]
),
(0, "DEHPA"): value(
ref.solex_cleaner_load.organic_inlet.conc_mass_comp[0, "DEHPA"]
),
(0, "Kerosene"): value(
ref.solex_cleaner_load.organic_inlet.conc_mass_comp[0, "Kerosene"]
),
},
}
tear_guesses5 = {
"flow_vol": {0: value(ref.solex_cleaner_load.aqueous_inlet.flow_vol[0])},
"conc_mass_comp": {
(0, "Al"): value(
ref.solex_cleaner_load.aqueous_inlet.conc_mass_comp[0, "Al"]
),
(0, "Ca"): value(
ref.solex_cleaner_load.aqueous_inlet.conc_mass_comp[0, "Ca"]
),
(0, "Ce"): value(
ref.solex_cleaner_load.aqueous_inlet.conc_mass_comp[0, "Ce"]
),
(0, "Cl"): value(
ref.solex_cleaner_load.aqueous_inlet.conc_mass_comp[0, "Cl"]
),
(0, "Dy"): value(
ref.solex_cleaner_load.aqueous_inlet.conc_mass_comp[0, "Dy"]
),
(0, "Fe"): value(
ref.solex_cleaner_load.aqueous_inlet.conc_mass_comp[0, "Fe"]
),
(0, "Gd"): value(
ref.solex_cleaner_load.aqueous_inlet.conc_mass_comp[0, "Gd"]
),
(0, "H"): value(
ref.solex_cleaner_load.aqueous_inlet.conc_mass_comp[0, "H"]
),
(0, "H2O"): value(
ref.solex_cleaner_load.aqueous_inlet.conc_mass_comp[0, "H2O"]
),
(0, "La"): value(
ref.solex_cleaner_load.aqueous_inlet.conc_mass_comp[0, "La"]
),
(0, "Nd"): value(
ref.solex_cleaner_load.aqueous_inlet.conc_mass_comp[0, "Nd"]
),
(0, "Pr"): value(
ref.solex_cleaner_load.aqueous_inlet.conc_mass_comp[0, "Pr"]
),
(0, "Sc"): value(
ref.solex_cleaner_load.aqueous_inlet.conc_mass_comp[0, "Sc"]
),
(0, "Sm"): value(
ref.solex_cleaner_load.aqueous_inlet.conc_mass_comp[0, "Sm"]
),
(0, "Y"): value(
ref.solex_cleaner_load.aqueous_inlet.conc_mass_comp[0, "Y"]
),
},
}
# Pass the tear_guess to the SD tool
seq.set_guesses_for(m.fs.leach.liquid_inlet, tear_guesses1)
seq.set_guesses_for(m.fs.solex_rougher_load.organic_inlet, tear_guesses2)
seq.set_guesses_for(m.fs.solex_rougher_load.aqueous_inlet, tear_guesses3)
seq.set_guesses_for(m.fs.solex_cleaner_load.organic_inlet, tear_guesses4)
seq.set_guesses_for(m.fs.solex_cleaner_load.aqueous_inlet, tear_guesses5)
initializer_feed = FeedInitializer()
feed_units = [
m.fs.leach_liquid_feed,
m.fs.leach_solid_feed,
m.fs.rougher_org_make_up,
m.fs.acid_feed1,
m.fs.acid_feed2,
m.fs.acid_feed3,
m.fs.cleaner_org_make_up,
]
initializer_product = ProductInitializer()
product_units = [
m.fs.leach_filter_cake,
m.fs.leach_filter_cake_liquid,
m.fs.cleaner_organic_purge,
m.fs.rougher_organic_purge,
m.fs.precip_purge,
]
initializer_sep = SeparatorInitializer()
sep_units = [
m.fs.scrub_sep,
m.fs.precip_sep,
]
initializer_mix = MixerInitializer()
mix_units = [
m.fs.precip_sx_mixer,
]
initializer_leach = LeachingTrainInitializer()
leach_units = [
m.fs.leach,
]
initializer_sx = SolventExtractionInitializer()
sx_units = [
m.fs.solex_rougher_load,
m.fs.solex_rougher_scrub,
m.fs.solex_rougher_strip,
m.fs.solex_cleaner_load,
m.fs.solex_cleaner_strip,
]
initializer_bt = BlockTriangularizationInitializer()
def function(unit):
if unit in feed_units:
_log.info(f"Initializing {unit}")
initializer_feed.initialize(unit)
elif unit in product_units:
_log.info(f"Initializing {unit}")
initializer_product.initialize(unit)
elif unit in sep_units:
_log.info(f"Initializing {unit}")
initializer_sep.initialize(unit)
elif unit in mix_units:
_log.info(f"Initializing {unit}")
initializer_mix.initialize(unit)
elif unit in leach_units:
_log.info(f"Initializing {unit}")
initializer_leach.initialize(unit)
elif unit in sx_units:
_log.info(f"Initializing {unit}")
initializer_sx.initialize(unit)
else:
_log.info(f"Initializing {unit}")
initializer_bt.initialize(unit)
seq.run(m, function)
Step 5.4: Solve the new system and print the recovery#
We should expect the total REE recovery to match that of the optimized m2 model.
updated_initialization(m3)
uky.solve_system(m3, tee=False)
uky.fix_organic_recycle(m3)
uky.solve_system(m3, tee=False)
uky.add_result_expressions(m3)
# Uncomment to display various system metrics like component recovery or leaching recovery
# uky.display_results(m3)
2026-06-29 11:23:23 [INFO] idaes.__main__: Initializing fs.leach_solid_feed
2026-06-29 11:23:23 [INFO] idaes.__main__: Initializing fs.leach_liquid_feed
2026-06-29 11:23:23 [INFO] idaes.__main__: Initializing fs.solex_rougher_load
2026-06-29 11:23:23 [INFO] idaes.init.fs.solex_rougher_load.mscontactor: Stream Initialization Completed.
2026-06-29 11:23:23 [INFO] idaes.init.fs.solex_rougher_load.mscontactor: Initialization Completed, optimal - <undefined>
2026-06-29 11:23:23 [INFO] idaes.__main__: Initializing fs.rougher_org_make_up
2026-06-29 11:23:23 [INFO] idaes.__main__: Initializing fs.acid_feed1
2026-06-29 11:23:23 [INFO] idaes.__main__: Initializing fs.acid_feed2
2026-06-29 11:23:23 [INFO] idaes.__main__: Initializing fs.solex_cleaner_load
2026-06-29 11:23:24 [INFO] idaes.init.fs.solex_cleaner_load.mscontactor: Stream Initialization Completed.
2026-06-29 11:23:24 [INFO] idaes.init.fs.solex_cleaner_load.mscontactor: Initialization Completed, optimal - <undefined>
2026-06-29 11:23:24 [INFO] idaes.__main__: Initializing fs.cleaner_org_make_up
2026-06-29 11:23:24 [INFO] idaes.__main__: Initializing fs.acid_feed3
2026-06-29 11:23:24 [INFO] idaes.__main__: Initializing fs.leach
2026-06-29 11:23:24 [INFO] idaes.init.fs.leach.mscontactor: Stream Initialization Completed.
2026-06-29 11:23:24 [INFO] idaes.init.fs.leach.mscontactor: Initialization Completed, optimal - <undefined>
2026-06-29 11:23:24 [INFO] idaes.__main__: Initializing fs.load_sep
2026-06-29 11:23:24 [INFO] idaes.__main__: Initializing fs.solex_rougher_scrub
2026-06-29 11:23:25 [INFO] idaes.init.fs.solex_rougher_scrub.mscontactor: Stream Initialization Completed.
2026-06-29 11:23:25 [INFO] idaes.init.fs.solex_rougher_scrub.mscontactor: Initialization Completed, optimal - <undefined>
2026-06-29 11:23:25 [INFO] idaes.__main__: Initializing fs.cleaner_HCl_leach_translator
2026-06-29 11:23:25 [INFO] idaes.__main__: Initializing fs.solex_cleaner_strip
2026-06-29 11:23:25 [INFO] idaes.init.fs.solex_cleaner_strip.mscontactor: Stream Initialization Completed.
2026-06-29 11:23:25 [INFO] idaes.init.fs.solex_cleaner_strip.mscontactor: Initialization Completed, optimal - <undefined>
2026-06-29 11:23:25 [INFO] idaes.__main__: Initializing fs.sl_sep1
2026-06-29 11:23:25 [INFO] idaes.__main__: Initializing fs.scrub_sep
2026-06-29 11:23:26 [INFO] idaes.init.fs.scrub_sep: Initialization Step 2 Complete: optimal - <undefined>
2026-06-29 11:23:26 [INFO] idaes.__main__: Initializing fs.solex_rougher_strip
2026-06-29 11:23:26 [INFO] idaes.init.fs.solex_rougher_strip.mscontactor: Stream Initialization Completed.
2026-06-29 11:23:26 [INFO] idaes.init.fs.solex_rougher_strip.mscontactor: Initialization Completed, optimal - <undefined>
2026-06-29 11:23:26 [INFO] idaes.__main__: Initializing fs.cleaner_sep
2026-06-29 11:23:26 [INFO] idaes.__main__: Initializing fs.precipitator
2026-06-29 11:23:26 [INFO] idaes.__main__: Initializing fs.leach_filter_cake
2026-06-29 11:23:26 [INFO] idaes.__main__: Initializing fs.leach_filter_cake_liquid
2026-06-29 11:23:26 [INFO] idaes.__main__: Initializing fs.leach_sx_mixer
2026-06-29 11:23:26 [INFO] idaes.__main__: Initializing fs.scrubber_HCl_leach_translator
2026-06-29 11:23:26 [INFO] idaes.__main__: Initializing fs.rougher_sep
2026-06-29 11:23:26 [INFO] idaes.__main__: Initializing fs.cleaner_mixer
2026-06-29 11:23:27 [INFO] idaes.__main__: Initializing fs.cleaner_organic_purge
2026-06-29 11:23:27 [INFO] idaes.__main__: Initializing fs.sl_sep2
2026-06-29 11:23:27 [INFO] idaes.__main__: Initializing fs.precip_sep
2026-06-29 11:23:27 [INFO] idaes.init.fs.precip_sep: Initialization Step 2 Complete: optimal - <undefined>
2026-06-29 11:23:27 [INFO] idaes.__main__: Initializing fs.leach_mixer
2026-06-29 11:23:27 [INFO] idaes.__main__: Initializing fs.rougher_mixer
2026-06-29 11:23:27 [INFO] idaes.__main__: Initializing fs.rougher_organic_purge
2026-06-29 11:23:27 [INFO] idaes.__main__: Initializing fs.roaster
2026-06-29 11:23:27 [INFO] idaes.__main__: Initializing fs.precip_purge
2026-06-29 11:23:27 [INFO] idaes.__main__: Initializing fs.precip_sx_mixer
2026-06-29 11:23:28 [INFO] idaes.init.fs.precip_sx_mixer: Initialization Complete: optimal - <undefined>
2026-06-29 11:23:28 [INFO] idaes.__main__: Initializing fs.leach_solid_feed
2026-06-29 11:23:28 [INFO] idaes.__main__: Initializing fs.leach_liquid_feed
2026-06-29 11:23:28 [INFO] idaes.__main__: Initializing fs.rougher_org_make_up
2026-06-29 11:23:28 [INFO] idaes.__main__: Initializing fs.acid_feed1
2026-06-29 11:23:28 [INFO] idaes.__main__: Initializing fs.acid_feed2
2026-06-29 11:23:28 [INFO] idaes.__main__: Initializing fs.cleaner_org_make_up
2026-06-29 11:23:28 [INFO] idaes.__main__: Initializing fs.acid_feed3
2026-06-29 11:23:28 [INFO] idaes.__main__: Initializing fs.solex_cleaner_load
2026-06-29 11:23:28 [INFO] idaes.init.fs.solex_cleaner_load.mscontactor: Stream Initialization Completed.
2026-06-29 11:23:28 [INFO] idaes.init.fs.solex_cleaner_load.mscontactor: Initialization Completed, optimal - <undefined>
2026-06-29 11:23:28 [INFO] idaes.__main__: Initializing fs.solex_rougher_load
2026-06-29 11:23:29 [INFO] idaes.init.fs.solex_rougher_load.mscontactor: Stream Initialization Completed.
2026-06-29 11:23:29 [INFO] idaes.init.fs.solex_rougher_load.mscontactor: Initialization Completed, optimal - <undefined>
2026-06-29 11:23:29 [INFO] idaes.__main__: Initializing fs.leach
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,1].conversion_comp[Sc2O3]' to a numeric value
`-1.6728639816779275e-07` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,1].conversion_comp[Y2O3]' to a numeric value
`-1.3987343537181505e-07` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,1].conversion_comp[La2O3]' to a numeric value
`-6.240507971067158e-08` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,1].conversion_comp[Ce2O3]' to a numeric value
`-2.1138268358545827e-08` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,1].conversion_comp[Pr2O3]' to a numeric value
`-2.7777298903369584e-07` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,1].conversion_comp[Nd2O3]' to a numeric value
`-6.253152279855576e-08` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,1].conversion_comp[Sm2O3]' to a numeric value
`-3.2359650497266735e-07` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,1].conversion_comp[Gd2O3]' to a numeric value
`-4.6446290023222933e-07` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,1].conversion_comp[Dy2O3]' to a numeric value
`-6.44228732983215e-07` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,2].conversion_comp[Y2O3]' to a numeric value
`-4.95859330836544e-07` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,2].conversion_comp[La2O3]' to a numeric value
`-2.3439891593488992e-07` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,2].conversion_comp[Ce2O3]' to a numeric value
`-9.509176164494752e-08` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,2].conversion_comp[Pr2O3]' to a numeric value
`-9.613375374041799e-07` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,2].conversion_comp[Nd2O3]' to a numeric value
`-2.348199992259363e-07` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,2].conversion_comp[Sm2O3]' to a numeric value
`-1.116016562285061e-06` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,2].conversion_comp[Gd2O3]' to a numeric value
`-1.5915465627360537e-06` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,2].conversion_comp[Dy2O3]' to a numeric value
`-2.198315860248783e-06` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.leach.mscontactor.solid[0.0,2].conversion_comp[Sc2O3]' to a numeric value
`-5.884141277247368e-07` outside the bounds (0, 0.99999999).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
2026-06-29 11:23:29 [INFO] idaes.init.fs.leach.mscontactor: Stream Initialization Completed.
2026-06-29 11:23:29 [INFO] idaes.init.fs.leach.mscontactor: Initialization Completed, optimal - <undefined>
2026-06-29 11:23:29 [INFO] idaes.__main__: Initializing fs.solex_cleaner_strip
2026-06-29 11:23:30 [INFO] idaes.init.fs.solex_cleaner_strip.mscontactor: Stream Initialization Completed.
2026-06-29 11:23:30 [INFO] idaes.init.fs.solex_cleaner_strip.mscontactor: Initialization Completed, optimal - <undefined>
2026-06-29 11:23:30 [INFO] idaes.__main__: Initializing fs.cleaner_HCl_leach_translator
2026-06-29 11:23:30 [INFO] idaes.__main__: Initializing fs.solex_rougher_scrub
WARNING (W1002): Setting Var
'fs.solex_rougher_scrub.mscontactor.aqueous[0.0,1].conc_mass_comp[Al]' to a
numeric value `-1.662747314857559e-08` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_scrub.mscontactor.aqueous[0.0,1].conc_mol_comp[Al]' to a
numeric value `-6.162397945968672e-13` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_scrub.mscontactor.aqueous[0.0,1].flow_mol_comp[Al]' to a
numeric value `-6.16243167606001e-14` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_scrub.mscontactor.aqueous[0.0,1].conc_mass_comp[Ca]' to a
numeric value `-1.1988761234534856e-08` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_scrub.mscontactor.aqueous[0.0,1].conc_mol_comp[Ca]' to a
numeric value `-2.991363997333738e-13` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_scrub.mscontactor.aqueous[0.0,1].flow_mol_comp[Ca]' to a
numeric value `-2.991357161974406e-14` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_scrub.mscontactor.aqueous[0.0,1].conc_mass_comp[Dy]' to a
numeric value `-5.97600125197985e-09` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_scrub.mscontactor.aqueous[0.0,1].conc_mol_comp[Dy]' to a
numeric value `-3.677537454048153e-14` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
WARNING (W1002): Setting Var
'fs.solex_rougher_scrub.mscontactor.aqueous[0.0,1].flow_mol_comp[Dy]' to a
numeric value `-3.677539230171473e-15` outside the bounds (1e-30, None).
See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
2026-06-29 11:23:30 [INFO] idaes.init.fs.solex_rougher_scrub.mscontactor: Stream Initialization Completed.
2026-06-29 11:23:30 [INFO] idaes.init.fs.solex_rougher_scrub.mscontactor: Initialization Completed, optimal - <undefined>
2026-06-29 11:23:30 [INFO] idaes.__main__: Initializing fs.load_sep
2026-06-29 11:23:30 [INFO] idaes.__main__: Initializing fs.sl_sep1
2026-06-29 11:23:31 [INFO] idaes.__main__: Initializing fs.precipitator
2026-06-29 11:23:31 [INFO] idaes.__main__: Initializing fs.leach_sx_mixer
2026-06-29 11:23:31 [INFO] idaes.__main__: Initializing fs.cleaner_sep
2026-06-29 11:23:31 [INFO] idaes.__main__: Initializing fs.solex_rougher_strip
2026-06-29 11:23:31 [INFO] idaes.init.fs.solex_rougher_strip.mscontactor: Stream Initialization Completed.
2026-06-29 11:23:31 [INFO] idaes.init.fs.solex_rougher_strip.mscontactor: Initialization Completed, optimal - <undefined>
2026-06-29 11:23:31 [INFO] idaes.__main__: Initializing fs.scrub_sep
2026-06-29 11:23:31 [INFO] idaes.init.fs.scrub_sep: Initialization Step 2 Complete: optimal - <undefined>
2026-06-29 11:23:31 [INFO] idaes.__main__: Initializing fs.sl_sep2
2026-06-29 11:23:32 [INFO] idaes.__main__: Initializing fs.cleaner_mixer
2026-06-29 11:23:32 [INFO] idaes.__main__: Initializing fs.rougher_sep
2026-06-29 11:23:32 [INFO] idaes.__main__: Initializing fs.scrubber_HCl_leach_translator
2026-06-29 11:23:32 [INFO] idaes.__main__: Initializing fs.precip_sep
2026-06-29 11:23:32 [INFO] idaes.init.fs.precip_sep: Initialization Step 2 Complete: optimal - <undefined>
2026-06-29 11:23:32 [INFO] idaes.__main__: Initializing fs.rougher_mixer
2026-06-29 11:23:32 [INFO] idaes.__main__: Initializing fs.leach_mixer
2026-06-29 11:23:32 [INFO] idaes.__main__: Initializing fs.precip_sx_mixer
2026-06-29 11:23:32 [INFO] idaes.init.fs.precip_sx_mixer: Initialization Complete: optimal - <undefined>
WARNING: Direct failed to converge in 1 iterations
2026-06-29 11:23:32 [INFO] idaes.__main__: Initializing fs.leach_filter_cake
2026-06-29 11:23:32 [INFO] idaes.__main__: Initializing fs.leach_filter_cake_liquid
2026-06-29 11:23:32 [INFO] idaes.__main__: Initializing fs.rougher_organic_purge
2026-06-29 11:23:33 [INFO] idaes.__main__: Initializing fs.cleaner_organic_purge
2026-06-29 11:23:33 [INFO] idaes.__main__: Initializing fs.roaster
2026-06-29 11:23:33 [INFO] idaes.__main__: Initializing fs.precip_purge
print(f"Total REE recovery is {value(m3.fs.overall_ree_recovery_percentage[0])} %")
Total REE recovery is 11.701773902385716 %
Step 6: Run the optimization case for 20%#
Now let’s see if we can run an optimization on m3 where the DEHPA dosage is 20%.
optimize_model(m3, DEHPA_ub=20)
uky.solve_system(m3, tee=False)
uky.display_results(m3)
====================================================================================
Unit : fs.roaster Time: 0.0
------------------------------------------------------------------------------------
Unit Performance
Expressions:
Key : Value : Units
Product Al Mass Fraction : 0.027099 : dimensionless
Product Fe Mass Fraction : 0.044784 : dimensionless
Product Ca Mass Fraction : 0.052857 : dimensionless
Product Sc Mass Fraction : 3.3135e-10 : dimensionless
Product Y Mass Fraction : 0.014045 : dimensionless
Product La Mass Fraction : 0.023887 : dimensionless
Product Ce Mass Fraction : 0.54057 : dimensionless
Product Pr Mass Fraction : 0.0038718 : dimensionless
Product Nd Mass Fraction : 0.21854 : dimensionless
Product Sm Mass Fraction : 0.0025543 : dimensionless
Product Gd Mass Fraction : 0.054738 : dimensionless
Product Dy Mass Fraction : 0.017049 : dimensionless
------------------------------------------------------------------------------------
Stream Table
Empty DataFrame
Columns: [Units]
Index: []
====================================================================================
REE product mass flow is 0.0016912770699706165 kg/hr
REE feed mass flow is 0.007623590660980152 kg/hr
Total REE recovery is 22.184783328243018 %
Product purity is 74.81797119501488 % REE
REE element recovery:
Leaching scandium recovery is 8.648753719844635 %
Overall scandium recovery is 1.1881388957750587e-07 %
Scandium rejected in leach filter cake solids is 87.79567843063991 %
Scandium rejected in leach filter cake entrained liquid is 3.713025194308788 %
Scandium rejected in rougher load aqueous purge is 0.019224075513982537 %
Scandium rejected in rougher scrub aqueous purge is 1.0209328383793216e-05 %
Scandium rejected in rougher organic purge is 8.467827045540886 %
Scandium rejected in cleaner aqueous purge is 2.4347681414695388e-08 %
Scandium rejected in cleaner organic purge is 0.0035555842925388288 %
Scandium accounted for is 99.99932068278606 %
Leaching yttrium recovery is 20.5128100046401 %
Overall yttrium recovery is 4.259614805880617 %
Yttrium rejected in leach filter cake solids is 70.84699282958118 %
Yttrium rejected in leach filter cake entrained liquid is 8.809942865803968 %
Yttrium rejected in rougher load aqueous purge is 7.59448110656119e-08 %
Yttrium rejected in rougher scrub aqueous purge is 0.023683416653830437 %
Yttrium rejected in rougher organic purge is 13.124510312639146 %
Yttrium rejected in cleaner aqueous purge is 0.13841469759182462 %
Yttrium rejected in cleaner organic purge is 2.41922482413484 %
Yttrium accounted for is 99.62238382823021 %
Leaching lanthanum recovery is 56.62308972090888 %
Overall lanthanum recovery is 3.5128149372806172 %
Lanthanum rejected in leach filter cake solids is 37.09224150268593 %
Lanthanum rejected in leach filter cake entrained liquid is 47.10198465460479 %
Lanthanum rejected in rougher load aqueous purge is 10.388019590447385 %
Lanthanum rejected in rougher scrub aqueous purge is 0.0673816723441948 %
Lanthanum rejected in rougher organic purge is 0.2852851497482015 %
Lanthanum rejected in cleaner aqueous purge is 0.3132702666163305 %
Lanthanum rejected in cleaner organic purge is 0.70641796855886 %
Lanthanum accounted for is 99.46741574228632 %
Leaching cerium recovery is 51.84105218072601 %
Overall cerium recovery is 34.50267101187438 %
Cerium rejected in leach filter cake solids is 29.389890606775065 %
Cerium rejected in leach filter cake entrained liquid is 25.170808776623748 %
Cerium rejected in rougher load aqueous purge is 0.9400376275389256 %
Cerium rejected in rougher scrub aqueous purge is 0.5368774758161462 %
Cerium rejected in rougher organic purge is 1.8642484961983885 %
Cerium rejected in cleaner aqueous purge is 1.5332126409573263 %
Cerium rejected in cleaner organic purge is 2.544141121559924 %
Cerium accounted for is 96.48188775734388 %
Leaching praseodymium recovery is 62.38000564252935 %
Overall praseodymium recovery is 2.251015440020321 %
Praseodymium rejected in leach filter cake solids is 23.84932628170995 %
Praseodymium rejected in leach filter cake entrained liquid is 58.5706188746908 %
Praseodymium rejected in rougher load aqueous purge is 13.205992505829226 %
Praseodymium rejected in rougher scrub aqueous purge is 0.025592583855294962 %
Praseodymium rejected in rougher organic purge is 0.6473817720112262 %
Praseodymium rejected in cleaner aqueous purge is 0.060147310130359295 %
Praseodymium rejected in cleaner organic purge is 1.2051278097593947 %
Praseodymium accounted for is 99.81520257800658 %
Leaching neodynium recovery is 57.993485483239986 %
Overall neodynium recovery is 32.19275915689231 %
Neodynium rejected in leach filter cake solids is 23.260592740720817 %
Neodynium rejected in leach filter cake entrained liquid is 33.70456173446737 %
Neodynium rejected in rougher load aqueous purge is 3.500466861616108 %
Neodynium rejected in rougher scrub aqueous purge is 0.45601045737728446 %
Neodynium rejected in rougher organic purge is 1.4923173549985156 %
Neodynium rejected in cleaner aqueous purge is 0.690010233181806 %
Neodynium rejected in cleaner organic purge is 2.24261385508284 %
Neodynium accounted for is 97.53933239433705 %
Leaching samarium recovery is 46.475355616922094 %
Overall samarium recovery is 1.7210928016717666 %
Samarium rejected in leach filter cake solids is 56.63960402369066 %
Samarium rejected in leach filter cake entrained liquid is 33.56898866819252 %
Samarium rejected in rougher load aqueous purge is 7.591518869092059 %
Samarium rejected in rougher scrub aqueous purge is 0.02357667382554316 %
Samarium rejected in rougher organic purge is 0.0939901357471293 %
Samarium rejected in cleaner aqueous purge is 0.023612980504363043 %
Samarium rejected in cleaner organic purge is 0.22116868799607156 %
Samarium accounted for is 99.88355284072011 %
Leaching gadolinium recovery is 65.89683271865671 %
Overall gadolinium recovery is 52.43426320659248 %
Gadolinium rejected in leach filter cake solids is 6.425926291696099 %
Gadolinium rejected in leach filter cake entrained liquid is 30.95636586629903 %
Gadolinium rejected in rougher load aqueous purge is 0.38861047482388744 %
Gadolinium rejected in rougher scrub aqueous purge is 0.6795048690952671 %
Gadolinium rejected in rougher organic purge is 2.330766394361969 %
Gadolinium rejected in cleaner aqueous purge is 0.6767390479100326 %
Gadolinium rejected in cleaner organic purge is 2.596968331808265 %
Gadolinium accounted for is 96.48914448258705 %
Leaching dysprosium recovery is 28.213748387073036 %
Overall dysprosium recovery is 22.51233415995388 %
Dysprosium rejected in leach filter cake solids is 60.786252639007415 %
Dysprosium rejected in leach filter cake entrained liquid is 12.312656000630971 %
Dysprosium rejected in rougher load aqueous purge is 0.00016243128538162818 %
Dysprosium rejected in rougher scrub aqueous purge is 0.20296244721091708 %
Dysprosium rejected in rougher organic purge is 1.7711411611104666 %
Dysprosium rejected in cleaner aqueous purge is 0.314186292061094 %
Dysprosium rejected in cleaner organic purge is 0.5666652520439225 %
Dysprosium accounted for is 98.46636038330404 %
Gangue recovery:
Leaching aluminum recovery is 16.965950129449492 %
Overall aluminum recovery is 0.0011396182051251404 %
Aluminum rejected in leach filter cake solids is 89.29492701302176 %
Aluminum rejected in leach filter cake entrained liquid is 8.569748681444647 %
Aluminum rejected in rougher load aqueous purge is 1.9835017754978814 %
Aluminum rejected in rougher scrub aqueous purge is 0.0009501572359221703 %
Aluminum rejected in rougher organic purge is 0.037798899205439225 %
Aluminum rejected in cleaner aqueous purge is 0.011888898523268904 %
Aluminum rejected in cleaner organic purge is 0.08746355738279249 %
Aluminum accounted for is 99.98741860051685 %
Leaching iron recovery is 42.042547772520756 %
Overall iron recovery is 0.006952784850266881 %
Iron rejected in leach filter cake solids is 63.563051717021594 %
Iron rejected in leach filter cake entrained liquid is 28.67561575895541 %
Iron rejected in rougher load aqueous purge is 6.568771750095962 %
Iron rejected in rougher scrub aqueous purge is 0.0032008108273045475 %
Iron rejected in rougher organic purge is 0.5193653826711973 %
Iron rejected in cleaner aqueous purge is 0.02633659710926837 %
Iron rejected in cleaner organic purge is 0.6077609087253594 %
Iron accounted for is 99.97105571025637 %
Leaching calcium recovery is 61.756409142083726 %
Overall calcium recovery is 0.15916479007268367 %
Calcium rejected in leach filter cake solids is 26.195170059569513 %
Calcium rejected in leach filter cake entrained liquid is 58.868946358493865 %
Calcium rejected in rougher load aqueous purge is 13.59609049711636 %
Calcium rejected in rougher scrub aqueous purge is 0.006540071863908139 %
Calcium rejected in rougher organic purge is 0.3602295878288399 %
Calcium rejected in cleaner aqueous purge is 0.05847620400359704 %
Calcium rejected in cleaner organic purge is 0.6833479121016393 %
Calcium accounted for is 99.9279654810504 %
print(f"Total REE recovery is {value(m3.fs.overall_ree_recovery_percentage[0])} %")
Total REE recovery is 22.184783328243018 %