From 1743f208a8b5a4d3bdb7d70ea0adf7f6f8ca2bc1 Mon Sep 17 00:00:00 2001 From: Doug A Date: Fri, 24 Apr 2026 16:16:00 -0400 Subject: [PATCH 1/7] scaling 201 --- .../notebooks/docs/scaling/scaling_201.ipynb | 2520 +++++++++++++++++ 1 file changed, 2520 insertions(+) create mode 100644 idaes_examples/notebooks/docs/scaling/scaling_201.ipynb diff --git a/idaes_examples/notebooks/docs/scaling/scaling_201.ipynb b/idaes_examples/notebooks/docs/scaling/scaling_201.ipynb new file mode 100644 index 00000000..4a601bb3 --- /dev/null +++ b/idaes_examples/notebooks/docs/scaling/scaling_201.ipynb @@ -0,0 +1,2520 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "4a1d7eaf-e297-436e-bb48-e65d1fdcd7f6", + "metadata": {}, + "outputs": [], + "source": [ + "###############################################################################\n", + "# The Institute for the Design of Advanced Energy Systems Integrated Platform\n", + "# Framework (IDAES IP) was produced under the DOE Institute for the\n", + "# Design of Advanced Energy Systems (IDAES).\n", + "#\n", + "# Copyright (c) 2018-2023 by the software owners: The Regents of the\n", + "# University of California, through Lawrence Berkeley National Laboratory,\n", + "# National Technology & Engineering Solutions of Sandia, LLC, Carnegie Mellon\n", + "# University, West Virginia University Research Corporation, et al.\n", + "# All rights reserved. Please see the files COPYRIGHT.md and LICENSE.md\n", + "# for full copyright and license information.\n", + "###############################################################################" + ] + }, + { + "cell_type": "markdown", + "id": "80fb4087-ae32-4ca1-9ec1-7fc8b60d3613", + "metadata": {}, + "source": [ + "# Scaling 201\n", + "\n", + "Author: Doug Allan\n", + "Maintainer: Doug Allan\n", + "Updated: 2026-04-24\n", + "\n", + "## Introduction\n", + "\n", + "This notebook is intended to give the user further insight into how the scaling toolbox can be used to improve robustness. By the end of this study, the user should understand:\n", + "* how a default scaler object can be specified for a property pacakge\n", + "* how to set default scaling factors for property package variables\n", + "* the strengths and weaknesses of the ``NominalValueExpressionWalker`` used in ``CustomScalerBase.get_sum_terms_nominal_values`` and ``CustomScalerBase.get_expression_nominal_value`` for use in constraint scaling\n", + "* how to use the ``SVDToolbox`` to troubleshoot scaling issues\n", + "\n", + "## Step 1: Set Up Test Case\n", + "We will use the `SolventReboiler` unit model as a case study. It is a component in a stripping column used for solvent regeneration. It is modeled as a single equilibrium stage with an external heat duty. A completely liquid phase is the inlet stream, with boilup and bottoms outlet streams. The liquid and vapor phases use different configurations of the modular property framework.\n", + "\n", + "First, we set up and attempt to initialize the unit model." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "e9e198c2-800e-48ac-b67c-8223a19abf96", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2026-04-24 15:46:18 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Starting initialization routine\n", + "2026-04-24 15:46:18 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Bubble, dew, and critical point initialization completed.\n", + "2026-04-24 15:46:18 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Equilibrium temperature initialization completed.\n", + "2026-04-24 15:46:18 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: State variable initialization completed.\n", + "2026-04-24 15:46:18 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Phase equilibrium initialization completed.\n", + "2026-04-24 15:46:19 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Property initialization routine finished.\n", + "2026-04-24 15:46:19 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Starting initialization routine\n", + "2026-04-24 15:46:19 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Bubble, dew, and critical point initialization completed.\n", + "2026-04-24 15:46:19 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Equilibrium temperature initialization completed.\n", + "2026-04-24 15:46:19 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: State variable initialization completed.\n", + "2026-04-24 15:46:19 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Phase equilibrium initialization completed.\n", + "2026-04-24 15:46:19 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Property initialization routine finished.\n", + "2026-04-24 15:46:19 [INFO] idaes.init.fs.unit.vapor_phase: Starting initialization routine\n", + "2026-04-24 15:46:19 [INFO] idaes.init.fs.unit.vapor_phase: Bubble, dew, and critical point initialization completed.\n", + "2026-04-24 15:46:19 [INFO] idaes.init.fs.unit.vapor_phase: Equilibrium temperature initialization completed.\n", + "2026-04-24 15:46:19 [INFO] idaes.init.fs.unit.vapor_phase: State variable initialization completed.\n", + "2026-04-24 15:46:19 [INFO] idaes.init.fs.unit.vapor_phase: Phase equilibrium initialization completed.\n", + "2026-04-24 15:46:19 [INFO] idaes.init.fs.unit.vapor_phase: Property initialization routine finished.\n", + "2026-04-24 15:46:19 [INFO] idaes.init.fs.unit: Initialization Complete: maxIterations - \n", + "Initialization failed.\n" + ] + } + ], + "source": [ + "import logging\n", + "import pytest\n", + "from pyomo.environ import (\n", + " check_optimal_termination,\n", + " ComponentMap,\n", + " ConcreteModel,\n", + " Constraint,\n", + " exp,\n", + " Param,\n", + " units,\n", + " value,\n", + ")\n", + "from pyomo.util.check_units import assert_units_consistent, assert_units_equivalent\n", + "\n", + "from idaes.core import FlowsheetBlock\n", + "from idaes.core.scaling.util import get_scaling_factor\n", + "from idaes.core.solvers import get_solver\n", + "from idaes.core.util.model_statistics import (\n", + " degrees_of_freedom,\n", + " number_variables,\n", + " number_total_constraints,\n", + " number_unused_variables,\n", + ")\n", + "from idaes.core.util.testing import initialization_tester\n", + "from idaes.core.util import scaling as iscale\n", + "from idaes.core.util.exceptions import InitializationError\n", + "\n", + "from idaes.models.properties.modular_properties.base.generic_property import (\n", + " GenericParameterBlock,\n", + ")\n", + "\n", + "from idaes.models_extra.column_models.solvent_reboiler import SolventReboiler\n", + "from idaes.models_extra.column_models.properties.MEA_solvent import (\n", + " configuration as aqueous_mea,\n", + ")\n", + "from idaes.models_extra.column_models.properties.MEA_vapor import flue_gas\n", + "\n", + "logging.getLogger('pyomo.repn.plugins.nl_writer').setLevel(logging.ERROR)\n", + "\n", + "def create_model():\n", + " m = ConcreteModel()\n", + " m.fs = FlowsheetBlock(dynamic=False)\n", + "\n", + " m.fs.liquid_properties = GenericParameterBlock(**aqueous_mea)\n", + " m.fs.vapor_properties = GenericParameterBlock(**flue_gas)\n", + "\n", + " m.fs.unit = SolventReboiler(\n", + " liquid_property_package=m.fs.liquid_properties,\n", + " vapor_property_package=m.fs.vapor_properties,\n", + " )\n", + "\n", + " m.fs.unit.inlet.flow_mol[0].fix(83.89)\n", + " m.fs.unit.inlet.temperature[0].fix(392.5)\n", + " m.fs.unit.inlet.pressure[0].fix(183700)\n", + " m.fs.unit.inlet.mole_frac_comp[0, \"CO2\"].fix(0.0326)\n", + " m.fs.unit.inlet.mole_frac_comp[0, \"H2O\"].fix(0.8589)\n", + " m.fs.unit.inlet.mole_frac_comp[0, \"MEA\"].fix(0.1085)\n", + "\n", + " # m.fs.unit.vapor_reboil.flow_mol[0].fix(9.56)\n", + " m.fs.unit.heat_duty.fix(430.61e3)\n", + " return m\n", + "\n", + "if __name__ == \"__main__\":\n", + " m = create_model()\n", + "\n", + " reboiler_init = m.fs.unit.default_initializer(\n", + " always_estimate_states=True,\n", + " )\n", + " try:\n", + " reboiler_init.initialize(m.fs.unit)\n", + " except InitializationError:\n", + " print(\"Initialization failed.\")" + ] + }, + { + "cell_type": "markdown", + "id": "d4285f74-1a23-47a8-be15-fce69216953c", + "metadata": {}, + "source": [ + "## Step 2: Run Model Diagnostics\n", + "\n", + "We see that the unit model failed to initialize. When confronted with a bad solution state, we should first use the `DiagnosticsToolbox` to check to see if there are structural issues with the model." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "69b249a7-99ad-408d-b6aa-470bb1ea9057", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "====================================================================================\n", + "Model Statistics\n", + "\n", + " Activated Blocks: 23 (Deactivated: 0)\n", + " Free Variables in Activated Constraints: 77 (External: 0)\n", + " Free Variables with only lower bounds: 15\n", + " Free Variables with only upper bounds: 0\n", + " Free Variables with upper and lower bounds: 50\n", + " Fixed Variables in Activated Constraints: 66 (External: 0)\n", + " Activated Equality Constraints: 77 (Deactivated: 0)\n", + " Activated Inequality Constraints: 0 (Deactivated: 0)\n", + " Activated Objectives: 0 (Deactivated: 0)\n", + "\n", + "------------------------------------------------------------------------------------\n", + "1 WARNINGS\n", + "\n", + " WARNING: Found 17 potential evaluation errors.\n", + "\n", + "------------------------------------------------------------------------------------\n", + "2 Cautions\n", + "\n", + " Caution: 11 variables fixed to 0\n", + " Caution: 82 unused variables (82 fixed)\n", + "\n", + "------------------------------------------------------------------------------------\n", + "Suggested next steps:\n", + "\n", + " display_potential_evaluation_errors()\n", + "\n", + "====================================================================================\n" + ] + } + ], + "source": [ + "from idaes.core.util import DiagnosticsToolbox\n", + "dt = DiagnosticsToolbox(m)\n", + "dt.report_structural_issues()" + ] + }, + { + "cell_type": "markdown", + "id": "c08b1da8-20da-4291-b555-7d78cf565f67", + "metadata": {}, + "source": [ + "The density relationship is being flagged for potential evaluation errors. The interval arithmatic used to identify potential evaluation errors can produce relatively loose bounds, especially for the sort of large polynomial expressions favored in the literature. Independent testing of the density relationship over a wide range of values has demonstrated that no evaluation errors occur, so we can ignore these warnings.\n", + "\n", + "The next step is determining which numerical issues exist:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "41e8b916-6314-42b3-b643-b492486af32b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "====================================================================================\n", + "Model Statistics\n", + "\n", + " Jacobian Condition Number: 2.718E+13\n", + "\n", + "------------------------------------------------------------------------------------\n", + "3 WARNINGS\n", + "\n", + " WARNING: 3 Constraints with large residuals (>1.0E-05)\n", + " WARNING: 1 Variable with extreme Jacobian column norms (<1.0E-08 or >1.0E+08)\n", + " WARNING: 1 Constraint with extreme Jacobian row norms (<1.0E-08 or >1.0E+08)\n", + "\n", + "------------------------------------------------------------------------------------\n", + "8 Cautions\n", + "\n", + " Caution: 9 Variables with value close to their bounds (abs=1.0E-04, rel=1.0E-04)\n", + " Caution: 18 Variables with value close to zero (tol=1.0E-08)\n", + " Caution: 30 Variables with extreme value (<1.0E-04 or >1.0E+04)\n", + " Caution: 2 Constraints with mismatched terms\n", + " Caution: 1 Constraint with potential cancellation of terms\n", + " Caution: 27 Variables with extreme Jacobian column norms (<1.0E-04 or >1.0E+04)\n", + " Caution: 16 Constraints with extreme Jacobian row norms (<1.0E-04 or >1.0E+04)\n", + " Caution: 50 extreme Jacobian Entries (<1.0E-04 or >1.0E+04)\n", + "\n", + "------------------------------------------------------------------------------------\n", + "Suggested next steps:\n", + "\n", + " display_constraints_with_large_residuals()\n", + " compute_infeasibility_explanation()\n", + " display_variables_with_extreme_jacobians()\n", + " display_constraints_with_extreme_jacobians()\n", + "\n", + "====================================================================================\n" + ] + } + ], + "source": [ + "dt.report_numerical_issues()" + ] + }, + { + "cell_type": "markdown", + "id": "b247949c-c8cf-48b7-9266-033db87a908a", + "metadata": {}, + "source": [ + "We see that there are some constraints with large residuals, which is what we expect since the model did not initialize successfully. We also see that the system has a condition number of $2.718\\cdot 10^{13}$, there is one variable associated with a Jacobian column with an extreme norm, and one constraint associated with a Jacobian row with an extreme norm.\n", + "\n", + "A condition number on the order of $10^{13}$ is significantly higher than we'd like. Ideally, we want unit models to have condition numbers less than $10^4$ and flowsheets with condition numbers less than $10^8$.\n", + "\n", + "Before beginning to write a scaler, however, we should look at the structure of the unit model." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "1da2f90e-e562-4f2a-b066-c635c88b0d78", + "metadata": {}, + "outputs": [], + "source": [ + "def build(self):\n", + " \"\"\"Build the model.\n", + "\n", + " Args:\n", + " None\n", + " Returns:\n", + " None\n", + " \"\"\"\n", + " # Call UnitModel.build to setup dynamics\n", + " super().build()\n", + "\n", + " # Check phase lists match assumptions\n", + " if self.config.vapor_property_package.phase_list != [\"Vap\"]:\n", + " raise ConfigurationError(\n", + " f\"{self.name} SolventReboiler model requires that the vapor \"\n", + " f\"phase property package have a single phase named 'Vap'\"\n", + " )\n", + " if self.config.liquid_property_package.phase_list != [\"Liq\"]:\n", + " raise ConfigurationError(\n", + " f\"{self.name} SolventReboiler model requires that the liquid \"\n", + " f\"phase property package have a single phase named 'Liq'\"\n", + " )\n", + "\n", + " # Check for at least one common component in component lists\n", + " if not any(\n", + " j in self.config.vapor_property_package.component_list\n", + " for j in self.config.liquid_property_package.component_list\n", + " ):\n", + " raise ConfigurationError(\n", + " f\"{self.name} SolventReboiler model requires that the liquid \"\n", + " f\"and vapor phase property packages have at least one \"\n", + " f\"common component.\"\n", + " )\n", + "\n", + " # ---------------------------------------------------------------------\n", + " # Add Control Volume for the Liquid Phase\n", + " self.liquid_phase = ControlVolume0DBlock(\n", + " dynamic=self.config.dynamic,\n", + " has_holdup=self.config.has_holdup,\n", + " property_package=self.config.liquid_property_package,\n", + " property_package_args=self.config.liquid_property_package_args,\n", + " )\n", + "\n", + " self.liquid_phase.add_state_blocks(has_phase_equilibrium=True)\n", + "\n", + " # Separate liquid and vapor phases means that phase equilibrium will\n", + " # be handled at the unit model level, thus has_phase_equilibrium is\n", + " # False, but has_mass_transfer is True.\n", + " self.liquid_phase.add_material_balances(\n", + " balance_type=self.config.material_balance_type,\n", + " has_mass_transfer=True,\n", + " has_phase_equilibrium=False,\n", + " )\n", + "\n", + " # Need to include enthalpy transfer term for the mass transfer\n", + " self.liquid_phase.add_energy_balances(\n", + " balance_type=self.config.energy_balance_type,\n", + " has_heat_transfer=True,\n", + " has_enthalpy_transfer=True,\n", + " )\n", + "\n", + " self.liquid_phase.add_momentum_balances(\n", + " balance_type=self.config.momentum_balance_type,\n", + " has_pressure_change=self.config.has_pressure_change,\n", + " )\n", + "\n", + " # ---------------------------------------------------------------------\n", + " # Add single state block for vapor phase\n", + " tmp_dict = dict(**self.config.vapor_property_package_args)\n", + " tmp_dict[\"has_phase_equilibrium\"] = False\n", + " tmp_dict[\"defined_state\"] = False\n", + " self.vapor_phase = self.config.vapor_property_package.build_state_block(\n", + " self.flowsheet().time, doc=\"Vapor phase properties\", **tmp_dict\n", + " )\n", + "\n", + " # ---------------------------------------------------------------------\n", + " # Check flow basis is compatible\n", + " t_init = self.flowsheet().time.first()\n", + " if (\n", + " self.vapor_phase[t_init].get_material_flow_basis()\n", + " != self.liquid_phase.properties_out[t_init].get_material_flow_basis()\n", + " ):\n", + " raise ConfigurationError(\n", + " f\"{self.name} vapor and liquid property packages must use the \"\n", + " f\"same material flow basis.\"\n", + " )\n", + "\n", + " # ---------------------------------------------------------------------\n", + " # Add Ports for the reboiler\n", + " self.add_inlet_port(name=\"inlet\", block=self.liquid_phase, doc=\"Liquid feed\")\n", + " self.add_outlet_port(\n", + " name=\"bottoms\", block=self.liquid_phase, doc=\"Bottoms stream\"\n", + " )\n", + " self.add_outlet_port(\n", + " name=\"vapor_reboil\",\n", + " block=self.vapor_phase,\n", + " doc=\"Vapor stream from reboiler\",\n", + " )\n", + "\n", + " # ---------------------------------------------------------------------\n", + " # Add unit level constraints\n", + " # First, need the union and intersection of component lists\n", + " all_comps = (\n", + " self.vapor_phase.component_list\n", + " | self.liquid_phase.properties_out.component_list\n", + " )\n", + " common_comps = (\n", + " self.vapor_phase.component_list\n", + " & self.liquid_phase.properties_out.component_list\n", + " )\n", + "\n", + " # Get units for unit conversion\n", + " vunits = self.config.vapor_property_package.get_metadata().get_derived_units\n", + " lunits = self.config.liquid_property_package.get_metadata().get_derived_units\n", + " flow_basis = self.vapor_phase[t_init].get_material_flow_basis()\n", + " if flow_basis == MaterialFlowBasis.molar:\n", + " fb = \"flow_mole\"\n", + " elif flow_basis == MaterialFlowBasis.mass:\n", + " fb = \"flow_mass\"\n", + " else:\n", + " raise ConfigurationError(\n", + " f\"{self.name} SolventReboiler only supports mass or molar \"\n", + " f\"basis for MaterialFlowBasis.\"\n", + " )\n", + "\n", + " if any(j not in common_comps for j in self.vapor_phase.component_list):\n", + " # We have non-condensable components present, need zero-flow param\n", + " self.zero_flow_param = Param(\n", + " mutable=True, default=1e-8, units=vunits(\"flow_mole\")\n", + " )\n", + "\n", + " # Material balances\n", + " def rule_material_balance(blk, t, j):\n", + " if j in common_comps:\n", + " # Component is in equilibrium\n", + " # Mass transfer equals vapor flowrate\n", + " return -blk.liquid_phase.mass_transfer_term[\n", + " t, \"Liq\", j\n", + " ] == pyunits.convert(\n", + " blk.vapor_phase[t].get_material_flow_terms(\"Vap\", j),\n", + " to_units=lunits(fb),\n", + " )\n", + " elif j in self.vapor_phase.component_list:\n", + " # Non-condensable component\n", + " # No mass transfer term\n", + " # Set vapor flowrate to an arbitrary small value\n", + " return (\n", + " blk.vapor_phase[t].get_material_flow_terms(\"Vap\", j)\n", + " == blk.zero_flow_param\n", + " )\n", + " else:\n", + " # Non-vaporisable component\n", + " # Mass transfer term is zero, no vapor flowrate\n", + " return blk.liquid_phase.mass_transfer_term[t, \"Liq\", j] == 0 * lunits(\n", + " fb\n", + " )\n", + "\n", + " self.unit_material_balance = Constraint(\n", + " self.flowsheet().time,\n", + " all_comps,\n", + " rule=rule_material_balance,\n", + " doc=\"Unit level material balances\",\n", + " )\n", + "\n", + " # Phase equilibrium constraints\n", + " # For all common components, equate fugacity in vapor and liquid\n", + " def rule_phase_equilibrium(blk, t, j):\n", + " return blk.liquid_phase.properties_out[t].fug_phase_comp[\n", + " \"Liq\", j\n", + " ] == pyunits.convert(\n", + " blk.vapor_phase[t].fug_phase_comp[\"Vap\", j], to_units=lunits(\"pressure\")\n", + " )\n", + "\n", + " self.unit_phase_equilibrium = Constraint(\n", + " self.flowsheet().time,\n", + " common_comps,\n", + " rule=rule_phase_equilibrium,\n", + " doc=\"Unit level phase equilibrium constraints\",\n", + " )\n", + "\n", + " # Temperature equality constraint\n", + " def rule_temperature_balance(blk, t):\n", + " return blk.liquid_phase.properties_out[t].temperature == pyunits.convert(\n", + " blk.vapor_phase[t].temperature, to_units=lunits(\"temperature\")\n", + " )\n", + "\n", + " self.unit_temperature_equality = Constraint(\n", + " self.flowsheet().time,\n", + " rule=rule_temperature_balance,\n", + " doc=\"Unit level temperature equality\",\n", + " )\n", + "\n", + " # Unit level energy balance\n", + " # Energy leaving in vapor phase must be equal and opposite to enthalpy\n", + " # transfer from liquid phase\n", + " def rule_energy_balance(blk, t):\n", + " return -blk.liquid_phase.enthalpy_transfer[t] == pyunits.convert(\n", + " blk.vapor_phase[t].get_enthalpy_flow_terms(\"Vap\"),\n", + " to_units=lunits(\"energy\") / lunits(\"time\"),\n", + " )\n", + "\n", + " self.unit_enthalpy_balance = Constraint(\n", + " self.flowsheet().time,\n", + " rule=rule_energy_balance,\n", + " doc=\"Unit level enthalpy_balance\",\n", + " )\n", + "\n", + " # Pressure balance constraint\n", + " def rule_pressure_balance(blk, t):\n", + " return blk.liquid_phase.properties_out[t].pressure == pyunits.convert(\n", + " blk.vapor_phase[t].pressure, to_units=lunits(\"pressure\")\n", + " )\n", + "\n", + " self.unit_pressure_balance = Constraint(\n", + " self.flowsheet().time,\n", + " rule=rule_pressure_balance,\n", + " doc=\"Unit level pressure balance\",\n", + " )\n", + "\n", + " # Set references to balance terms at unit level\n", + " self.heat_duty = Reference(self.liquid_phase.heat[:])\n", + "\n", + " if (\n", + " self.config.has_pressure_change is True\n", + " and self.config.momentum_balance_type != MomentumBalanceType.none\n", + " ):\n", + " self.deltaP = Reference(self.liquid_phase.deltaP[:])" + ] + }, + { + "cell_type": "markdown", + "id": "9642460f-4f49-4edd-a212-0fa1d13bb07f", + "metadata": {}, + "source": [ + "As is typical with IDAES models, two submodels are created: the `ControlVolume0D` named `liquid_phase` and the `StateBlock` named `vapor_phase`. Then several unit model level constraints are written. \n", + "\n", + "## Step 3: Creating a New Scaler Class\n", + "\n", + "To create a new scaling routine for the equilibrium reactor, we start by creating a new ``Scaler`` class which inherits from the ``CustomScalerBase`` class in ``idaes.core.scaling``. The ``CustomScalerBase`` class contains a number of useful methods to help us in developing our scaling routine, including some placeholder methods for implementing a standard scaling workflow and helper methods for doing common tasks.\n", + "\n", + "The cell below shows how to create our new class which we will name ``SolventReboilerScaler`` as well as two key methods we will fill out as part of this workshop." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "6910d881-8875-4529-bd30-5807aa15f400", + "metadata": {}, + "outputs": [], + "source": [ + "from idaes.core.scaling import CustomScalerBase\n", + "\n", + "\n", + "class SolventReboilerScaler(CustomScalerBase):\n", + " def variable_scaling_routine(\n", + " self, model, overwrite: bool = False, submodel_scalers: dict = None\n", + " ):\n", + " # Empty method for now\n", + " pass\n", + "\n", + " def constraint_scaling_routine(\n", + " self, model, overwrite: bool = False, submodel_scalers: dict = None\n", + " ):\n", + " # Empty method for now\n", + " pass" + ] + }, + { + "cell_type": "markdown", + "id": "ba19563f-d285-4eba-8156-1d4ef0ad36b2", + "metadata": {}, + "source": [ + "As you know from the first scaling tutorial, the ``variable_scaling_routine`` and ``constraint_scaling_routine`` methods are used to implement subroutines for scaling the variables and constraints in the model respectively. Separately, there is a ``scale_model`` method that will call each of these in sequence in order to scale an entire model by applying the following steps:\n", + "\n", + "1. apply variable scaling routine,\n", + "2. apply first stage scaling fill-in,\n", + "3. apply constraint scaling routine,\n", + "4. apply second stage scaling fill-in.\n", + "\n", + "The second and fourth steps are intended to allow users to provide methods to fill in missing scaling information that was not provided by the first and second steps. However, these methods are prone to perform poorly on all but the simplest models (see Step 5 for more information).\n", + "\n", + "Both the ``variable_scaling_routine`` and ``constraint_scaling_routine`` are user-facing methods and take three arguments.\n", + "\n", + "1. The model to be scaled.\n", + "2. An argument indicating whether to overwrite any existing scaling factors. Generally we assume that any existing scaling factors were provided by the user for a reason, so by default we set this to ``False``. However, there will likely be cases where a user wants to overwrite their existing scaling factors so this argument exists to let us pass on those instructions.\n", + "3. A mapping of user-provided ``Scalers`` to use when scaling submodels.\n", + "\n", + "## Step 4: Apply Scaling to Sub-Models\n", + "\n", + "First, lets look at how to scale the control volume and state block sub-models. Because the property package for ``vapor_phase`` state block is specified by the user, we do not know what variables and constraints it may contain, so we cannot (and should not) scale it directly. The property package creator (hopefully) created a scaler object that we can use. The zero-dimensional control volume ``liquid_phase`` contains two state blocks, material, energy, and pressure balance constraints, and variables corresponding to additional interaction terms. Because we are choosing which terms to create in the control volume, we could, in principle, scale it at the unit model level. However, because control volumes typically should be scaled in the same way, a submodel scaler has been provided for it as well. Thus, what we want to do here is to call the variable and constraint scaling routines from the ``Scaler`` associated with each sub-model, which we can do using the ``call_submodel_scaler_method`` method." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "6a2d1c70-1608-4df6-9865-68c00193dcbe", + "metadata": {}, + "outputs": [], + "source": [ + "class SolventReboilerScaler(CustomScalerBase):\n", + " def variable_scaling_routine(\n", + " self, model, overwrite: bool = False, submodel_scalers: ComponentMap = None\n", + " ):\n", + " # Call scaling methods for sub-models\n", + " self.call_submodel_scaler_method(\n", + " submodel=model.liquid_phase,\n", + " method=\"variable_scaling_routine\",\n", + " submodel_scalers=submodel_scalers,\n", + " overwrite=overwrite,\n", + " )\n", + "\n", + " self.call_submodel_scaler_method(\n", + " submodel=model.vapor_phase,\n", + " method=\"variable_scaling_routine\",\n", + " submodel_scalers=submodel_scalers,\n", + " overwrite=overwrite,\n", + " )\n", + "\n", + " def constraint_scaling_routine(\n", + " self, model, overwrite: bool = False, submodel_scalers: ComponentMap = None\n", + " ):\n", + " # Call scaling methods for sub-models\n", + " self.call_submodel_scaler_method(\n", + " submodel=model.liquid_phase,\n", + " method=\"constraint_scaling_routine\",\n", + " submodel_scalers=submodel_scalers,\n", + " overwrite=overwrite,\n", + " )\n", + "\n", + " self.call_submodel_scaler_method(\n", + " submodel=model.vapor_phase,\n", + " method=\"constraint_scaling_routine\",\n", + " submodel_scalers=submodel_scalers,\n", + " overwrite=overwrite,\n", + " )" + ] + }, + { + "cell_type": "markdown", + "id": "c509e071-62a7-449b-a084-7e118d142ddd", + "metadata": {}, + "source": [ + "In order for the submodel scaling to function properly, default scaling factors need to be set for some variables. The property package scaler cannot know if the system is supposed to be bench scale, pilot scale, or production scale unless the user sets a default. These defaults can be set on a unit model by unit model basis by using the `submodel_scalers` argument, or they can be set at the flowsheet level on the parameter block. We will do the latter.\n", + "\n", + "First, we need to create objects using the modular property submodel scaler class." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "7ae92ba0-17d3-4aa5-ba21-d5cead039f47", + "metadata": {}, + "outputs": [], + "source": [ + "liquid_properties_scaler = m.fs.liquid_properties.default_state_scaler_class()\n", + "vapor_properties_scaler = m.fs.vapor_properties.default_state_scaler_class()" + ] + }, + { + "cell_type": "markdown", + "id": "b3ec7e7a-89a7-4182-8377-e12b21731d74", + "metadata": {}, + "source": [ + "Now, let's see what default scaling factors these scaler objects have." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "8de34555-cf86-43a1-bf56-e12ef9e7b55b", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'flow_mol_phase': ,\n", + " 'mole_frac_phase_comp': 10,\n", + " 'temperature': 0.0033333333333333335,\n", + " 'pressure': 1e-05,\n", + " 'enth_mol_phase': ,\n", + " 'visc_d_phase': ,\n", + " 'therm_cond_phase': ,\n", + " 'mole_frac_phase_comp_true': 10,\n", + " 'mole_frac_phase_comp_apparent': 10,\n", + " 'dens_mol_phase': }" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "liquid_properties_scaler.default_scaling_factors" + ] + }, + { + "cell_type": "markdown", + "id": "5194862f-71ee-4473-b68f-14b428d5138e", + "metadata": {}, + "source": [ + "We can see that we are required to set a default scaling factor for ``flow_mol_phase``. Furthermore, it is recommended to set a default scaling factor for ``enth_mol_phase``, ``visc_d_phase``, and ``therm_cond_phase``. For these latter quantities, there is a method to estimate reasonable scaling factors, but it might not be suitible for all cases.\n", + "\n", + "With a inlet flow of about 80 mol/s, a scaling factor of 1/80 is appropriate. We can ignore ``visc_d_phase`` and ``therm_cond_phase``, because the solvent reboiler model does not require dynamic viscosity or thermal conductivity (at present). Molar enthalpy is a tougher quantity to scale.\n", + "\n", + "By convention, the molar enthalpy of each element in its pure form at 25$^\\circ$ C and 1 atm is set equal to zero. In some property packages, enthalpy of formation is taken into account for compounds, while in some property packages it is not. However, the scaling factor for enthalpy should not depend on this convention---only enthalpy *differences* are meaningful. So we need to determine how to determine what constitutes a \"significant\" enthalpy difference for this property package. The way the modular property scaler object estimates this is through the temperature scaling factor, which determines what a \"significant\" temperature difference is, and the observation that a wide range of substances have a specific heat capacity around 2 $\\frac{\\text{J}}{\\text{g K}}$.\n", + "\n", + "TODO This digression can probably be cut.\n", + "~~Liquid water has a heat capacity of 4.18 $\\frac{\\text{J}}{\\text{g K}}$, steam has a heat capacity of 2.03 $\\frac{\\text{J}}{\\text{g K}}$, liquid enthanol has a heat capacity of 2.44, and air has a heat capacity of 1.01 $\\frac{\\text{J}}{\\text{g K}}$ at room temperature. The major outliers are metals and hydrogen gas. Metals tend to have heat capacities less than 1 $\\frac{\\text{J}}{\\text{g K}}$, with iron having 0.449 $\\frac{\\text{J}}{\\text{g K}}$ and gold having 0.129 $\\frac{\\text{J}}{\\text{g K}}$. Hydrogen, by contrast, has a heat capacity of 14.41 $\\frac{\\text{J}}{\\text{g K}}$; the heat capacity of a diatomic gas is about $\\frac{5}{2}R$, in which $R$ is the gas consant, so hydrogen's low molecular weight results in it having a large mass-based heat capacity.~~\n", + "\n", + "This default method is good enough for our purposes now. We can revisit it later if necessary." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "322ea374-6077-49b5-aa2f-d866ad9a3204", + "metadata": {}, + "outputs": [], + "source": [ + "liquid_properties_scaler.default_scaling_factors[\"flow_mol_phase\"] = 1 / 80\n", + "vapor_properties_scaler.default_scaling_factors[\"flow_mol_phase\"] = 1 / 10\n", + "\n", + "m.fs.liquid_properties.default_state_scaler_object = liquid_properties_scaler\n", + "m.fs.vapor_properties.default_state_scaler_object = vapor_properties_scaler" + ] + }, + { + "cell_type": "markdown", + "id": "c19f5b26-6328-4324-8555-ecc10f3f73cc", + "metadata": {}, + "source": [ + "Now we can see how much submodel scaling improves the conditioning of the unit model." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "f82e7b2c-8c98-4685-bf25-9f2dea6db0f1", + "metadata": {}, + "outputs": [], + "source": [ + "reboiler_scaler = SolventReboilerScaler()\n", + "reboiler_scaler.scale_model(m.fs.unit)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "9d10891e-082a-4a0d-82da-536b8eeb9e86", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "====================================================================================\n", + "Model Statistics\n", + "\n", + " Jacobian Condition Number: 7.165E+10\n", + "\n", + "------------------------------------------------------------------------------------\n", + "1 WARNINGS\n", + "\n", + " WARNING: 1 Constraint with large residuals (>1.0E-05)\n", + "\n", + "------------------------------------------------------------------------------------\n", + "8 Cautions\n", + "\n", + " Caution: 9 Variables with value close to their bounds (abs=1.0E-04, rel=1.0E-04)\n", + " Caution: 14 Variables with value close to zero (tol=1.0E-08)\n", + " Caution: 27 Variables with extreme value (<1.0E-04 or >1.0E+04)\n", + " Caution: 2 Constraints with mismatched terms\n", + " Caution: 1 Constraint with potential cancellation of terms\n", + " Caution: 10 Variables with extreme Jacobian column norms (<1.0E-04 or >1.0E+04)\n", + " Caution: 4 Constraints with extreme Jacobian row norms (<1.0E-04 or >1.0E+04)\n", + " Caution: 28 extreme Jacobian Entries (<1.0E-04 or >1.0E+04)\n", + "\n", + "------------------------------------------------------------------------------------\n", + "Suggested next steps:\n", + "\n", + " display_constraints_with_large_residuals()\n", + " compute_infeasibility_explanation()\n", + "\n", + "====================================================================================\n" + ] + } + ], + "source": [ + "dt = DiagnosticsToolbox(m)\n", + "dt.report_numerical_issues()" + ] + }, + { + "cell_type": "markdown", + "id": "5a146719-cac0-466f-87e4-00bbd9adffa3", + "metadata": {}, + "source": [ + "We see in this case that partly scaling the model improved the condition number of the Jacobian by only two and a half orders of magnitude. This sort of marginal improvement is common for partial scaling, and sometimes partial scaling makes the model's condition number *worse*. When variables are scaled without the constraints they appear in also being scaled, it generates new extreme Jacobian entries. If we look at the number of extreme Jacobian rows and columns, however, we see the progress we've made. Before applying submodel scaling, we had 27 variables with extreme column norms and 16 constraints with extreme row norms. Now we have only 10 variables and 4 constraints. Let's see which constraints are problematic." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "0737f98e-73c5-4fac-9215-aee2efd1942d", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "====================================================================================\n", + "The following variable(s) correspond to Jacobian columns with extreme norms(<1.0E-04 or>1.0E+04):\n", + "\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,CO2]: 3.450E+07\n", + " fs.unit.liquid_phase.enthalpy_transfer[0.0]: 1.970E+06\n", + " fs.unit.liquid_phase.properties_out[0.0].temperature: 1.586E+06\n", + " fs.unit.vapor_phase[0.0].pressure: 1.353E+05\n", + " fs.unit.vapor_phase[0.0].temperature: 1.014E+05\n", + " fs.unit.liquid_phase.properties_out[0.0].pressure: 1.000E+05\n", + " fs.unit.vapor_phase[0.0].flow_mol_phase[Vap]: 3.256E+04\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,H2O]: 1.954E+04\n", + " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]: 1.873E+04\n", + " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]: 1.863E+04\n", + "\n", + "====================================================================================\n", + "====================================================================================\n", + "The following constraint(s) correspond to Jacobian rows with extreme norms (<1.0E-04 or>1.0E+04):\n", + "\n", + " fs.unit.unit_phase_equilibrium[0.0,CO2]: 3.450E+07\n", + " fs.unit.unit_enthalpy_balance[0.0]: 1.973E+06\n", + " fs.unit.unit_phase_equilibrium[0.0,H2O]: 1.589E+06\n", + " fs.unit.unit_pressure_balance[0.0]: 1.414E+05\n", + "\n", + "====================================================================================\n" + ] + } + ], + "source": [ + "dt.display_variables_with_extreme_jacobians()\n", + "dt.display_constraints_with_extreme_jacobians()" + ] + }, + { + "cell_type": "markdown", + "id": "83bb987c-932b-4d05-9803-f646cbfdb476", + "metadata": {}, + "source": [ + "These four unit model level constraints are causing our remaining problems.\n", + "\n", + "## Step 5: Unit Model Level Scaling\n", + "\n", + "We should take a look at the constraints before determining their scaling factors. However, Pyomo's `pprint` method often prints out multiple terminal pages' worth of thermodynamic expressions, which are extremely difficult to parse. The output is so verbose because it descends into named `Expressions` and recursively subsititutes them into the constraint expression. Since IDAES makes heavy use of named `Expressions` to decrease the number of `Constraints` in a model, the output becomes unmanangable for all but the most simple constraints. The `print_compact_form` utility function usually results in much more readable output." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "6e025e22-4b18-41cf-b761-942ec50964e1", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "- fs.unit.liquid_phase.enthalpy_transfer[0.0] == (kg*m**2/J/s**2)*fs.unit.vapor_phase[0.0]._enthalpy_flow_term[Vap]" + ] + } + ], + "source": [ + "from idaes.core.util.misc import print_compact_form\n", + "print_compact_form(m.fs.unit.unit_enthalpy_balance[0.0])" + ] + }, + { + "cell_type": "markdown", + "id": "82de19a5-da64-438d-951e-0dd83413b71c", + "metadata": {}, + "source": [ + "This is a relatively straightforward constraint.\n", + "\n", + "So long as we have scaling factors set for the terms in the enthalpy balance, we can scale the constraint by the same factor. Because `liquid_phase.enthalpy_transfer[0.0]` is a `Var` created by the `ControlVolume0D`, it already has a scaling factor assigned by the `ControlVolume0DScaler`.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "54986702-39c2-40ac-b144-8a757ac324fb", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "5.076760620583219e-07" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "get_scaling_factor(m.fs.unit.liquid_phase.enthalpy_transfer[0.0])" + ] + }, + { + "cell_type": "markdown", + "id": "8fa075e5-7c16-4369-bd76-fe28b565cc9b", + "metadata": {}, + "source": [ + "However, in the modular property framework, `get_enthalpy_flow_terms(p)` returns a named `Expression`. Expressions do not need to be scaled on their own. However, scaling hints can be assigned for them to assist in determining appropriate scaling factors for other variables and constraints. When the `get_scaling_factor` function is called on an `Expression`, it will return a scaling hint if one is assigned. (This behavior is useful, because what is a `Var` in one property package can be implemented as an `Expression` in another.)\n", + "\n", + "In this case, however, no scaling hint is assigned to `vapor_phase[0.0]._enthalpy_flow_term[\"Vap\"]`." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "ed2cad19-6b46-4a97-9fc5-4332c0dea65c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "get_scaling_factor(m.fs.unit.vapor_phase[0.0]._enthalpy_flow_term[\"Vap\"]) is None" + ] + }, + { + "cell_type": "markdown", + "id": "287eb07c-51e7-4ea1-a42d-9a03e992fea3", + "metadata": {}, + "source": [ + "To get an estimate of the size of that expression, then, we can look at its constituent terms:" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "cebca2c2-a949-4120-b31a-453d28eee1ae", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "fs.unit.vapor_phase[0.0].flow_mol_phase[Vap]*fs.unit.vapor_phase[0.0].enth_mol_phase[Vap]" + ] + } + ], + "source": [ + "print_compact_form(m.fs.unit.vapor_phase[0.0]._enthalpy_flow_term[\"Vap\"])" + ] + }, + { + "cell_type": "markdown", + "id": "babca14f-656a-45e0-912f-19e72424b6fe", + "metadata": {}, + "source": [ + "The term `vapor_phase[0.0].flow_mol_phase[\"Vap\"]` *is* a `Var` and has a scaling factor applied." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "c997f5f5-9b09-48cf-a15e-3cd0cc43c52b", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.1" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "get_scaling_factor(m.fs.unit.vapor_phase[0.0].flow_mol_phase[\"Vap\"])" + ] + }, + { + "cell_type": "markdown", + "id": "d32a5206-9272-4673-953a-a3ebe7cef08e", + "metadata": {}, + "source": [ + "However, `vapor_phase[0.0].enth_mol_phase[\"Vap\"]` is a named `Expression`. Nevertheless, it has a scaling hint." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "759e6aab-ddc5-435f-9699-d9dcdf82dc52", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "5.46268982847154e-05" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "get_scaling_factor(m.fs.unit.vapor_phase[0.0].enth_mol_phase[\"Vap\"])" + ] + }, + { + "cell_type": "markdown", + "id": "b0e7e793-b649-43eb-8e16-a66f793375ed", + "metadata": {}, + "source": [ + "Because the scaling factor of the molar flow rate is $0.1$, we can estimate that the molar flow rate will be about $10$. Similarly, we can estimate the size of a significant molar enthalpy difference is around the size of `1/5.46e-5`$ \\approx 18,000$. Therefore the general size of the enthalpy flow terms should be around $180,000$." + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "c12629aa-ea76-43fd-8a87-dff2b7d2ac75", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.0125" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "get_scaling_factor(m.fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase[\"Liq\"])" + ] + }, + { + "cell_type": "markdown", + "id": "b8486746-111b-4df6-82f5-aeabe5bc2211", + "metadata": {}, + "source": [ + "The `get_sum_terms_nominal_values` method in `CustomScalerBase` which uses an expression walker to go through an expression to return a list of the expected magnitude (or \"nominal value\") of all additive terms in the expression based on the scaling factors for the variables involved. For example, suppose we have an expression\n", + "$$\n", + "a + b\\cdot c - d\\cdot (e - f)\n", + "$$\n", + "Let $\\sigma(v)$ denote the scaling factor of the variable $v$. Then `get_sum_terms_nominal_values` substitutes the inverse of the variable scaling factor into each term in the sum and returns it as a list:\n", + "$$\n", + "\\left[\\frac{1}{\\sigma(a)},\\; \\frac{1}{\\sigma(b) \\cdot \\sigma(c)}, \\frac{\\left(\\frac{1}{\\sigma(e)} - \\frac{1}{\\sigma(f)}\\right)}{\\sigma(d)} \\right]\n", + "$$\n", + "\n", + "This process can produce reliable estimates of expression magnitude for certain operations:\n", + " - Addition of positive numbers\n", + " - Multiplication and division\n", + " - Raising a variable to a fixed power\n", + "\n", + "For these operations, only an order-of-magnitude estimate for the variable is sufficient to get an order-of-magnitude estimate of the resulting expression. However, it is far less reliable for other operations:\n", + " - Subtraction (or addition of negative numbers to positive numbers)\n", + " - Functions with a variable exponent\n", + " - Trigometric functions\n", + "\n", + "For these operations, an expression's final value is highly dependent on the exact values of its included variables. For example, suppose $\\sigma(e) = \\sigma(f)$. In that case, the term $d\\cdot (e - f)$ would have an estimated magnitude of $0$, which is useless for scaling purposes. It is in cases like this that scaling hints for named expressions. If we denote $G = e - f$ and assign $\\sigma(G) = \\sigma(e)$, we have a far better estimate of the term $d\\cdot (e - f)$ in the quantity $1/(\\sigma(d)\\cdot\\sigma(G))$.\n", + "\n", + "Logarithms are a special case. Since they convert multiplication to addition, application of a scaling factor simply shifts the zero point of the resulting expression.\n", + "$$\n", + " \\log(h \\cdot \\sigma(h)) = \\log(h) + \\log(\\sigma(h))\n", + "$$\n", + "\n", + "The output of a logarithmic expression should be considered well-scaled by default, unless its argument is an absolutely enormous number (in which case floating point arithmetic is probably inappropriate anyway).\n", + "\n", + "In the case of scaling `unit.unit_enthalpy_balance[0.0]`, we only have two additive terms, one consisting of a single variable, the other consisting of the product of a variable with an expression with a scaling hint. In this case, `get_sum_terms_nominal_values` should produce a good estimate of the order-of-magnitude of each term.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "899cf853-c7a5-40b9-add6-21de075f15f2", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[1969759.9999999995, 183060.0]" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "reboiler_scaler.get_sum_terms_nominal_values(m.fs.unit.unit_enthalpy_balance[0.0])" + ] + }, + { + "cell_type": "markdown", + "id": "ef79b2c7-3187-41c1-aa33-bce79bceb11a", + "metadata": {}, + "source": [ + "The inverse of either of these numbers would be reasonable scaling factors. The `scale_constraint_by_nominal value` function automatically scales a constraint by using one of these numbers. Which number we use is selected using the `ConstraintScalingScheme` `Enum` If we take the inverse of the larger number, we are saying that the constraint needs to be satisfied with the same precision as the largest term in the sum. This corresponds to `ConstraintScalingScheme.inverseMaximum`. If we take the inverse of the smaller number, we are saying that the constraint needs to be satisfied with the same precision as the smallest term in the sum. This corresponds to `ConstraintScalingScheme.inverseMinimum`. In this case, they differ only by a factor of 10, so there isn't that large of a difference. Let's use the `inverseMinimum` method for this constraint in order to more precisely determine the vapor phase's temperature.\n", + "\n", + "The next two constraints can be dealt with together:" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "5165dd5a-f440-466a-b1e2-5e5f43846746", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[Liq,CO2] == fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,CO2]\n", + "\n", + "fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[Liq,H2O] == fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,H2O]" + ] + } + ], + "source": [ + "print_compact_form(m.fs.unit.unit_phase_equilibrium[0.0,\"CO2\"]);print(\"\\n\")\n", + "print_compact_form(m.fs.unit.unit_phase_equilibrium[0.0,\"H2O\"])" + ] + }, + { + "cell_type": "markdown", + "id": "14999184-9aa8-4ff3-8453-8bbb06f92b2d", + "metadata": {}, + "source": [ + "These are simple vapor-liquid equilibrium constraints for the volatile components. Let's see what `get_sum_terms_nominal_values` shows for them:" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "790b9691-0734-4974-9f32-0d5d4070e5c5", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[7623092.433711249, 10000.0]\n", + "[355.3596511053128, 10000.0]\n" + ] + } + ], + "source": [ + "print(reboiler_scaler.get_sum_terms_nominal_values(m.fs.unit.unit_phase_equilibrium[0.0,\"CO2\"]))\n", + "print(reboiler_scaler.get_sum_terms_nominal_values(m.fs.unit.unit_phase_equilibrium[0.0,\"H2O\"]))" + ] + }, + { + "cell_type": "markdown", + "id": "e601fb2f-6208-4c53-bd74-13bbe97b682b", + "metadata": {}, + "source": [ + "Here, we see that, while the vapor phase fugacities are associated with a nominal value of 10000, the liquid phase fugacities have wildly different nominal values. We do expect the vapor phase to be enriched in $\\text{CO}_2$, but not by a factor of $2\\cdot 10^4$. So let's unpack these values. We are using the ideal gas law for the vapor phase, so the fugacity is simply the product of the mole fraction and vapor pressure:" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "5bdb2701-c04a-4e1b-b9d2-86a673a944a9", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]*fs.unit.vapor_phase[0.0].pressure" + ] + } + ], + "source": [ + "print_compact_form(m.fs.unit.vapor_phase[0.0].fug_phase_comp[\"Vap\",\"CO2\"])" + ] + }, + { + "cell_type": "markdown", + "id": "b1e7fc38-536a-4ac3-8b02-f96ef0e58db5", + "metadata": {}, + "source": [ + "The liquid phase, by contrast, contains a complicated Henry's Law type relationship for $\\text{CO}_2$ and a slightly less complicated Antoine's Law relationship for $\\text{H}_2\\text{O}$:" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "7a316b13-1891-47fa-bb1a-fa52365f8e57", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,CO2]*(exp(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O])*log(244800.0*exp(-1348*K/fs.unit.liquid_phase.properties_out[0.0].temperature)*(3520000.0*exp(-2113*K/fs.unit.liquid_phase.properties_out[0.0].temperature)/(8449000.0*exp(-2283*K/fs.unit.liquid_phase.properties_out[0.0].temperature)))) + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O])*log(3520000.0*exp(-2113*K/fs.unit.liquid_phase.properties_out[0.0].temperature)) + fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O])*(fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]))*(fs.liquid_properties.CO2.lwm_coeff_1 + K**(-1)*fs.liquid_properties.CO2.lwm_coeff_2*(fs.unit.liquid_phase.properties_out[0.0].temperature - 273.15*K) + K**(-2)*fs.liquid_properties.CO2.lwm_coeff_3*(fs.unit.liquid_phase.properties_out[0.0].temperature - 273.15*K)**2 + fs.liquid_properties.CO2.lwm_coeff_4*(fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]))))*Pa*m**3*mol**(-1))" + ] + } + ], + "source": [ + "print_compact_form(m.fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[\"Liq\",\"CO2\"])" + ] + }, + { + "cell_type": "markdown", + "id": "df43607d-fd78-4ab2-9e40-223c595cc115", + "metadata": {}, + "source": [ + "Parsing the entire pile of thermodynamic gibberish is unnecessary to plan our next move. We can plainly see that the liquid phase fugacity expression is rife with subtraction and exponentiation, both of which are dangerous for the nominal value expression walker. Even worse, we are scaling based on a failed solution, so the values may be off anyway. It is farbetter to base the scaling factor on the vapor phase fugacity. The `get_expression_nominal_value` function allows the user to get the nominal value of a single expression." + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "7ebe7e0c-1dc5-49cc-a712-d507f2510f28", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "10000.0" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "reboiler_scaler.get_expression_nominal_value(m.fs.unit.vapor_phase[0.0].fug_phase_comp[\"Vap\",\"CO2\"])" + ] + }, + { + "cell_type": "markdown", + "id": "631e3d28-475b-480e-a4d3-98d2c0f4a0df", + "metadata": {}, + "source": [ + "While in this case this value is positive, the nominal value can be negative, so you should use the absolute value when getting a scaling factor.\n", + "\n", + "Finally, we have the last constraint---mechanical equilibrium between phases\n" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "1ad76dde-b6f4-4c26-9d78-5cc76170c399", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "fs.unit.liquid_phase.properties_out[0.0].pressure == fs.unit.vapor_phase[0.0].pressure" + ] + } + ], + "source": [ + "print_compact_form(m.fs.unit.unit_pressure_balance[0.0])" + ] + }, + { + "cell_type": "markdown", + "id": "8c9ceb71-2018-4dd2-879e-e9a95ffce583", + "metadata": {}, + "source": [ + "Pressure should always have a scaling factor applied, so the inverse maximum method should be good.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "9e8f7776-21b3-4e43-a76d-f250a55ac31e", + "metadata": {}, + "source": [ + "In addition to these problematic unit model level constraints, there are some additional constraints that need scaling factors. Although they might not be problematic under these process conditions, they may be for a scaled-up flowsheet. If they are well-scaled already, we should Let's use the `report_scaling_factors` function to show what they are:" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "715c1ead-2d0e-4b4f-97ef-bdd8fb0bb2d0", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Scaling Factors for block fs.unit\n", + "\n", + "Variable Scaling Factor Value Scaled Value\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol 1.250E-02 8.389E+01 1.049E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[H2O] 1.000E+01 8.589E-01 8.589E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[MEA] 1.000E+01 1.085E-01 1.085E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[CO2] 1.000E+01 3.260E-02 3.260E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].temperature 3.333E-03 3.925E+02 1.308E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol 1.250E-02 7.424E+01 9.279E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O] 1.000E+01 8.527E-01 8.527E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] 1.000E+01 1.226E-01 1.226E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[CO2] 1.000E+01 2.471E-02 2.471E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].temperature 3.333E-03 3.926E+02 1.309E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", + "fs.unit.vapor_phase[0.0].flow_mol 1.000E-01 9.654E+00 9.654E-01\n", + "fs.unit.vapor_phase[0.0].mole_frac_comp[CO2] 1.000E+01 9.329E-02 9.329E-01\n", + "fs.unit.vapor_phase[0.0].mole_frac_comp[H2O] 1.000E+01 9.067E-01 9.067E+00\n", + "fs.unit.vapor_phase[0.0].mole_frac_comp[N2] 1.000E+01 1.055E-09 1.055E-08\n", + "fs.unit.vapor_phase[0.0].mole_frac_comp[O2] 1.000E+01 1.055E-09 1.055E-08\n", + "fs.unit.vapor_phase[0.0].temperature 3.333E-03 3.926E+02 1.309E+00\n", + "fs.unit.vapor_phase[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", + "fs.unit.liquid_phase.heat[0.0] 5.077E-07 4.306E+05 2.186E-01\n", + "\n", + "Constraint Scaling Factor\n", + "fs.unit.unit_material_balance[0.0,CO2] None\n", + "fs.unit.unit_material_balance[0.0,H2O] None\n", + "fs.unit.unit_material_balance[0.0,N2] None\n", + "fs.unit.unit_material_balance[0.0,O2] None\n", + "fs.unit.unit_material_balance[0.0,MEA] None\n", + "fs.unit.unit_phase_equilibrium[0.0,CO2] None\n", + "fs.unit.unit_phase_equilibrium[0.0,H2O] None\n", + "fs.unit.unit_temperature_equality[0.0] None\n", + "fs.unit.unit_enthalpy_balance[0.0] None\n", + "fs.unit.unit_pressure_balance[0.0] None\n" + ] + } + ], + "source": [ + "from idaes.core.scaling.util import report_scaling_factors\n", + "report_scaling_factors(m.fs.unit, descend_into=False)" + ] + }, + { + "cell_type": "markdown", + "id": "d6b5ad41-2c25-449e-b083-03351516fd41", + "metadata": {}, + "source": [ + "We have yet to scale the `unit_temperature_equality` and `unit_material_balance`constraints. The temperature equality constraint is simple." + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "7f5f85f4-33ec-42a4-a700-c9744b25d6f4", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "fs.unit.liquid_phase.properties_out[0.0].temperature == fs.unit.vapor_phase[0.0].temperature" + ] + } + ], + "source": [ + "print_compact_form(m.fs.unit.unit_temperature_equality[0.0])" + ] + }, + { + "cell_type": "markdown", + "id": "40b09e54-30db-4082-ae85-5a5d4f445116", + "metadata": {}, + "source": [ + "Either inverse maximum or inverse minimum scaling would work just fine. The material balance constraints have different forms depending on whether a component occurs in the liquid phase, the vapor phase, or both:" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "0f62396b-94de-4f92-b7c9-4d6cae1e83b5", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "- fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,CO2] == fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,CO2]\n", + "\n", + "fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,MEA] == 0*(mol*s**(-1))\n", + "\n", + "fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,N2] == fs.unit.zero_flow_param" + ] + } + ], + "source": [ + "print_compact_form(m.fs.unit.unit_material_balance[0.0,\"CO2\"]); print(\"\\n\")\n", + "print_compact_form(m.fs.unit.unit_material_balance[0.0,\"MEA\"]); print(\"\\n\")\n", + "print_compact_form(m.fs.unit.unit_material_balance[0.0,\"N2\"])" + ] + }, + { + "cell_type": "markdown", + "id": "b1fc2994-0a80-4530-816a-76e025c49706", + "metadata": {}, + "source": [ + "The first constraint equates the vapor flow rate to the mass transfer from the liquid phase. Either inverse maximum or inverse minimum would work. The next two are a bit trickier. For $\\text{MEA}$, which is considered nonvolatile in this property package, there is no mass transfer to the vapor phase. A common misconception is that variables should always be scaled to be order one. That is incorrect. We only need to calculate `mass_transfer_term[0.0,\"Liq\",\"MEA\"]` to the same precision as the other (nonzero) terms of the mass balance (and the `ControlVolume0D` submodel scaler does just that). Similarly, `flow_mol_phase_comp[\"Vap\",\"N2\"]` is set to a tiny nonzero value (because flows that are exactly zero often cause problems for property calculations). We do not need more significant figures for either of those variables than the rest of the terms in their correspoding material balances. Therefore we want to use *inverse maximum* becuase inverse minimum would produce bad results.\n", + "\n", + "
\n", + "NOTE\n", + "\n", + "If we had relied on autoscaling methods to fill in scaling factors for these variables and constraints, we would have ended up with enormous scaling factors for `flow_mol_phase_comp[\"Vap\",\"N2\"]` and `flow_mol_phase_comp[\"Vap\",\"O2\"]` because they are not-quite equal to zero at the model solution.\n", + "\n", + "Similarly, `m.fs.unit.unit_phase_equilibrium[0.0,\"CO2\"]` would have been overscaled due to the enormous nominal value given by the expression walker for the liquid phase fugacity\n", + "\n", + "
\n", + "\n", + "Finally, we can complete the scaler object." + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "164ad598-7e44-43ad-b6e6-726721a66f21", + "metadata": {}, + "outputs": [], + "source": [ + "from idaes.core.scaling.custom_scaler_base import ConstraintScalingScheme\n", + "\n", + "class SolventReboilerScaler(CustomScalerBase):\n", + " def variable_scaling_routine(\n", + " self, model, overwrite: bool = False, submodel_scalers: dict = None\n", + " ):\n", + " # Call scaling methods for sub-models\n", + " self.call_submodel_scaler_method(\n", + " submodel=model.liquid_phase,\n", + " method=\"variable_scaling_routine\",\n", + " submodel_scalers=submodel_scalers,\n", + " overwrite=overwrite,\n", + " )\n", + "\n", + " self.call_submodel_scaler_method(\n", + " submodel=model.vapor_phase,\n", + " method=\"variable_scaling_routine\",\n", + " submodel_scalers=submodel_scalers,\n", + " overwrite=overwrite,\n", + " )\n", + "\n", + " def constraint_scaling_routine(\n", + " self, model, overwrite: bool = False, submodel_scalers: dict = None\n", + " ):\n", + " # Call scaling methods for sub-models\n", + " self.call_submodel_scaler_method(\n", + " submodel=model.liquid_phase,\n", + " method=\"constraint_scaling_routine\",\n", + " submodel_scalers=submodel_scalers,\n", + " overwrite=overwrite,\n", + " )\n", + "\n", + " self.call_submodel_scaler_method(\n", + " submodel=model.vapor_phase,\n", + " method=\"constraint_scaling_routine\",\n", + " submodel_scalers=submodel_scalers,\n", + " overwrite=overwrite,\n", + " )\n", + " # Note: scaling factors cannot be applied directly to indexed objects.\n", + " # They should be applied to VarData/ConstraintData/ExpressionData children instead.\n", + " for condata in model.unit_material_balance.values():\n", + " self.scale_constraint_by_nominal_value(condata, scheme=ConstraintScalingScheme.inverseMaximum, overwrite=overwrite)\n", + " for condata in model.unit_temperature_equality.values():\n", + " self.scale_constraint_by_nominal_value(condata, scheme=ConstraintScalingScheme.inverseMaximum, overwrite=overwrite)\n", + " for condata in model.unit_enthalpy_balance.values():\n", + " self.scale_constraint_by_nominal_value(condata, scheme=ConstraintScalingScheme.inverseMinimum, overwrite=overwrite)\n", + " for condata in model.unit_pressure_balance.values():\n", + " self.scale_constraint_by_nominal_value(condata, scheme=ConstraintScalingScheme.inverseMaximum, overwrite=overwrite)\n", + " for (t, j), condata in m.fs.unit.unit_phase_equilibrium.items():\n", + " nom = abs(self.get_expression_nominal_value(m.fs.unit.vapor_phase[t].fug_phase_comp[\"Vap\",j]))\n", + " self.set_constraint_scaling_factor(condata, 1/nom, overwrite=overwrite)" + ] + }, + { + "cell_type": "markdown", + "id": "9d5e8f3f-94fa-49be-a213-30cb976798e2", + "metadata": {}, + "source": [ + "Now we can see how this works on the model. We'll pass `overwrite=True` config option when creating the scaler object to ensure we have up-to-date scaling factors." + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "a319f9b5-4c27-4416-9c8e-41be2d9badd3", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2026-04-24 15:46:20 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Starting initialization routine\n", + "2026-04-24 15:46:20 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Bubble, dew, and critical point initialization completed.\n", + "2026-04-24 15:46:20 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Equilibrium temperature initialization completed.\n", + "2026-04-24 15:46:20 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: State variable initialization completed.\n", + "2026-04-24 15:46:20 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Phase equilibrium initialization completed.\n", + "2026-04-24 15:46:20 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Property initialization routine finished.\n", + "2026-04-24 15:46:20 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Starting initialization routine\n", + "2026-04-24 15:46:20 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Bubble, dew, and critical point initialization completed.\n", + "2026-04-24 15:46:20 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Equilibrium temperature initialization completed.\n", + "2026-04-24 15:46:20 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: State variable initialization completed.\n", + "2026-04-24 15:46:20 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Phase equilibrium initialization completed.\n", + "2026-04-24 15:46:20 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Property initialization routine finished.\n", + "2026-04-24 15:46:20 [INFO] idaes.init.fs.unit.vapor_phase: Starting initialization routine\n", + "2026-04-24 15:46:20 [INFO] idaes.init.fs.unit.vapor_phase: Bubble, dew, and critical point initialization completed.\n", + "2026-04-24 15:46:20 [INFO] idaes.init.fs.unit.vapor_phase: Equilibrium temperature initialization completed.\n", + "2026-04-24 15:46:20 [INFO] idaes.init.fs.unit.vapor_phase: State variable initialization completed.\n", + "2026-04-24 15:46:20 [INFO] idaes.init.fs.unit.vapor_phase: Phase equilibrium initialization completed.\n", + "2026-04-24 15:46:20 [INFO] idaes.init.fs.unit.vapor_phase: Property initialization routine finished.\n", + "2026-04-24 15:46:20 [INFO] idaes.init.fs.unit: Initialization Complete: optimal - \n" + ] + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "scaler_obj = SolventReboilerScaler(overwrite=True)\n", + "scaler_obj.scale_model(m.fs.unit)\n", + "reboiler_init.initialize(m.fs.unit)" + ] + }, + { + "cell_type": "markdown", + "id": "c7e05d0d-7dc8-4de9-b87d-059b3779b71c", + "metadata": {}, + "source": [ + "We see that scaling improved the model enough so that initialization could succeed. Now let's look at the numerical issues." + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "a2e3a35e-165e-4687-a0ef-5330557fdb16", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "====================================================================================\n", + "Model Statistics\n", + "\n", + " Jacobian Condition Number: 5.400E+06\n", + "\n", + "------------------------------------------------------------------------------------\n", + "0 WARNINGS\n", + "\n", + " No warnings found!\n", + "\n", + "------------------------------------------------------------------------------------\n", + "6 Cautions\n", + "\n", + " Caution: 9 Variables with value close to their bounds (abs=1.0E-04, rel=1.0E-04)\n", + " Caution: 14 Variables with value close to zero (tol=1.0E-08)\n", + " Caution: 27 Variables with extreme value (<1.0E-04 or >1.0E+04)\n", + " Caution: 2 Constraints with mismatched terms\n", + " Caution: 1 Constraint with potential cancellation of terms\n", + " Caution: 15 extreme Jacobian Entries (<1.0E-04 or >1.0E+04)\n", + "\n", + "------------------------------------------------------------------------------------\n", + "Suggested next steps:\n", + "\n", + " If you still have issues converging your model consider:\n", + "\n", + " prepare_degeneracy_hunter()\n", + " prepare_svd_toolbox()\n", + "\n", + "====================================================================================\n" + ] + } + ], + "source": [ + "dt = DiagnosticsToolbox(m)\n", + "dt.report_numerical_issues()" + ] + }, + { + "cell_type": "markdown", + "id": "a51f00e4-e26d-4569-9689-97c1851ccd24", + "metadata": {}, + "source": [ + "We have reduced the Jacobian condition number by another four orders of magnitude, as well as eliminating all extreme Jacobian rows and columns. A condition number of $5\\cdot 10^6$ is still higher than we'd like for a single unit model, especially for a simple unit model like this one, because connecting units together as part of a flowsheet inevitably increases the condition number. \n", + "\n", + "## Step 6: No More Low-hanging Fruit\n", + "\n", + "We have two avenues to proceed:\n", + "1. Check the extreme Jacobian *entries*\n", + "2. Check the singular value decomposition (SVD) of the Jacobian\n", + "\n", + "Let's try checking the SVD first." + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "8b62a78b-d7f3-455e-b2c2-4d3ff609f101", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "====================================================================================\n", + "Constraints and Variables associated with smallest singular values\n", + "\n", + " Smallest Singular Value 1:\n", + "\n", + " Variables:\n", + "\n", + " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_comp[CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_comp[H2O]\n", + "\n", + " Constraints:\n", + "\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2]\n", + "\n", + " Smallest Singular Value 2:\n", + "\n", + " Variables:\n", + "\n", + " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_comp[CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_comp[H2O]\n", + "\n", + " Constraints:\n", + "\n", + " fs.unit.unit_material_balance[0.0,CO2]\n", + " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", + "\n", + " Smallest Singular Value 3:\n", + "\n", + " Variables:\n", + "\n", + " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_comp[CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_comp[H2O]\n", + "\n", + " Constraints:\n", + "\n", + " fs.unit.unit_material_balance[0.0,CO2]\n", + " fs.unit.liquid_phase.material_balances[0.0,MEA]\n", + " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", + " fs.unit.liquid_phase.enthalpy_balances[0.0]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", + " fs.unit.unit_material_balance[0.0,MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,HCO3_-]\n", + " fs.unit.vapor_phase[0.0].sum_mole_frac_out\n", + "\n", + " Smallest Singular Value 4:\n", + "\n", + " Variables:\n", + "\n", + " fs.unit.vapor_phase[0.0].flow_mol_phase[Vap]\n", + " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,H2O]\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]\n", + " fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,H2O]\n", + " fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,H2O]\n", + " fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,H2O]\n", + " fs.unit.vapor_phase[0.0].mole_frac_comp[H2O]\n", + " fs.unit.vapor_phase[0.0].flow_mol\n", + "\n", + " Constraints:\n", + "\n", + " fs.unit.unit_material_balance[0.0,CO2]\n", + " fs.unit.liquid_phase.material_balances[0.0,MEA]\n", + " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", + " fs.unit.liquid_phase.enthalpy_balances[0.0]\n", + " fs.unit.unit_material_balance[0.0,MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].total_flow_balance\n", + " fs.unit.vapor_phase[0.0].sum_mole_frac_out\n", + "\n", + " Smallest Singular Value 5:\n", + "\n", + " Variables:\n", + "\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,H2O]\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]\n", + " fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,H2O]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_k_eq[bicarbonate]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_k_eq[carbamate]\n", + "\n", + " Constraints:\n", + "\n", + " fs.unit.liquid_phase.material_balances[0.0,MEA]\n", + " fs.unit.unit_material_balance[0.0,MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].total_flow_balance\n", + " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[MEA]\n", + " fs.unit.liquid_phase.properties_out[0.0].sum_mole_frac_out\n", + "\n", + "====================================================================================\n" + ] + }, + { + "data": { + "text/plain": [ + "array([0.00063559, 0.02780866, 0.03679008, 0.06841867, 0.07702857,\n", + " 0.09285582, 0.11369371, 0.11731412, 0.1479692 , 0.19043286])" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "st = dt.prepare_svd_toolbox()\n", + "# The SVD toolbox displays 10 singular values by default, but we are going to\n", + "# look at just the first five to reduce the amount of output.\n", + "st.display_underdetermined_variables_and_constraints(singular_values=[1, 2, 3, 4, 5])\n", + "st.s" + ] + }, + { + "cell_type": "markdown", + "id": "78dc41a4-65e6-4f1e-8f85-087533c40157", + "metadata": {}, + "source": [ + "The smallest singular value is 40 times smaller than the second smallest singular value. This usually means that we can significantly improve the matrix conditioning by scaling only a small number of variables and constraints. There is only one constraint strongly associated with the smallest singular value, so let's start with that." + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "43b2dd6a-e71b-48ea-a3a8-36d6f73f9f80", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "exp(fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]) == fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,CO2]/(mol/m**3)" + ] + } + ], + "source": [ + "print_compact_form(m.fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[\"Liq\",\"CO2\"])" + ] + }, + { + "cell_type": "markdown", + "id": "37ba698d-b22a-48d4-b436-f2ea0f2d0fd7", + "metadata": {}, + "source": [ + "This constraint converts between the $\\text{CO}_2$ concentration and its logarithm. Using these sorts of log-form variables can increase the number of significant digits when dealing with reactions involving components in small quantities. (They can also introduce degeneracy when dealing with trace quantities that *do not* appear in reactions.)\n", + "\n", + "The SVD Toolbox also has two helper functions: `display_variables_in_constraint`, which displays the Jacobian row corresponding to a constraint, and `display_constraints_including_variable`, which displays the Jacobian column corresponding to a variable." + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "5900b815-9725-4334-a108-ae70088b3962", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "====================================================================================\n", + "The following variables are involved in fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2]:\n", + "\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,H2O]: 4.280e-05\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,MEA]: 1.492e-04\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,CO2]: 6.126e-05\n", + " fs.unit.liquid_phase.properties_out[0.0].temperature: 1.576e-04\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,CO2]: -1.648e+00\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]: 5.621e-04\n", + "\n", + "====================================================================================\n" + ] + } + ], + "source": [ + "st.display_variables_in_constraint(m.fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[\"Liq\",\"CO2\"])" + ] + }, + { + "cell_type": "markdown", + "id": "0a56f473-f557-4558-84d1-bde67fd6cd65", + "metadata": {}, + "source": [ + "
\n", + "NOTE At this point of the process, the original author found a shortcoming in the modular properties scaler. No scaling hint was set for the molar density expression, so the expression walker descended into it and came back with an inappropriate nominal value. Revising the scaler to estimate the phase density resulted in a condition number improvement of 1-2 orders of magnitude.\n", + "\n", + "Remember:\n", + "1. Scaling is an iterative process.\n", + "2. Submodel scalers may need to be revised to fix scaling issues.\n", + "3. Using the expression walker in an expression tree that involves subtraction or exponential functions is dangerous.\n", + "
\n", + "\n", + "From our knowledge of the physical properties, `mole_frac_phase_comp_true[\"Liq\",\"CO2\"]` and `log_conc_mol_phase_comp_true[\"Liq\",\"CO2\"]` should have the largest effects on this equation. The other variables affect the concentration indirectly through the phase density. But while `mole_frac_phase_comp_true[\"Liq\",\"CO2\"]` does have an appropriately-sized impact, `log_conc_mol_phase_comp_true[\"Liq\",\"CO2\"]` is several orders-of-magnitude too small. A naive approach might be to decrease the scaling factor on `log_conc_mol_phase_comp_true[\"Liq\",\"CO2\"]` until it has an appropriately-sized effect in the equation. Remember, though, that log variables are well-scaled by default. Something else must be wrong.\n", + "\n", + "Let's take a look at the values on both sides of the equation." + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "id": "7f9156a6-dbd0-4902-9fa2-ebb4e487f365", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Left hand side value: 1.3698e+00\n", + "CO2 true concentration value: 1.3698e+00\n" + ] + } + ], + "source": [ + "print(f\"Left hand side value: {value(exp(m.fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[\"Liq\",\"CO2\"])):.4e}\")\n", + "print(f\"CO2 true concentration value: {value(m.fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[\"Liq\",\"CO2\"]):.4e}\")" + ] + }, + { + "cell_type": "markdown", + "id": "8f73803d-63b8-4893-9509-d48c986b3c83", + "metadata": {}, + "source": [ + "Since the left hand side and right hand side both have values of order one, we expect the equation to have a similar scaling factor." + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "id": "5166b5b9-99cb-4a21-95d3-ead5992a40ed", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.0004103666666666667\n" + ] + } + ], + "source": [ + "print(get_scaling_factor((m.fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[\"Liq\",\"CO2\"])))" + ] + }, + { + "cell_type": "markdown", + "id": "91eafe99-00b2-4351-a231-9deead449779", + "metadata": {}, + "source": [ + "However, it actually has an extremely small scaling factor. To what can we attribute this?\n", + "\n", + "It is a result of not setting good default values for the true species mole fractions in the liquid phase. Although the apparent $\\text{CO}_2$ mole fraction is about 0.03, almost all of that is in the form of a carbamate salt formed through reaction with $\\text{MEA}$. The true mole fraction is significantly lower." + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "id": "ef7e9960-da1f-43a5-a1f6-6fd84be6896a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True CO2 mole fraction: 3.410357e-05\n", + "True MEACOO- mole fraction: 2.796223e-02\n" + ] + } + ], + "source": [ + "print(f\"True CO2 mole fraction: {m.fs.unit.liquid_phase.properties_out[0].mole_frac_phase_comp_true[\"Liq\",\"CO2\"].value:4e}\")\n", + "print(f\"True MEACOO- mole fraction: {m.fs.unit.liquid_phase.properties_out[0].mole_frac_phase_comp_true[\"Liq\",\"MEACOO_-\"].value:4e}\")" + ] + }, + { + "cell_type": "markdown", + "id": "1c6801be-a670-412b-a746-fef01ca25757", + "metadata": {}, + "source": [ + "Nevertheless, the true value of the $\\text{CO}_2$ mole fraction is important because it is used in the calculation of fugacity. It should therefore be assigned a larger scaling factor. Therefore, let's revisit the default scaling factors for the liquid properties:" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "id": "f519aee0-4a23-4d3c-a705-e7135ea6fd27", + "metadata": {}, + "outputs": [], + "source": [ + "default_scaling_factors = m.fs.liquid_properties.default_state_scaler_object.default_scaling_factors\n", + "# Dictionaries are mutable, so changing its value here also changes it on the scaler object\n", + "# First scale the apparent mole fractions\n", + "default_scaling_factors[\"mole_frac_phase_comp[Liq, H2O]\"] = 1\n", + "default_scaling_factors[\"mole_frac_phase_comp[Liq, CO2]\"] = 10\n", + "default_scaling_factors[\"mole_frac_phase_comp[Liq, MEA]\"] = 10\n", + "# Next scale the true mole fractions\n", + "default_scaling_factors[\"mole_frac_phase_comp_true[Liq, H2O]\"] = 1\n", + "default_scaling_factors[\"mole_frac_phase_comp_true[Liq, CO2]\"] = 1e4\n", + "default_scaling_factors[\"mole_frac_phase_comp_true[Liq, MEA]\"] = 10\n", + "default_scaling_factors[\"mole_frac_phase_comp_true[Liq, MEA_+]\"] = 10\n", + "default_scaling_factors[\"mole_frac_phase_comp_true[Liq, MEACOO_-]\"] = 10\n", + "default_scaling_factors[\"mole_frac_phase_comp_true[Liq, HCO3_-]\"] = 100" + ] + }, + { + "cell_type": "markdown", + "id": "26d9d52d-3f27-4fa9-949b-764553252132", + "metadata": {}, + "source": [ + "With these new scaling factors, let's rescale and resolve the mode, then check the new condition number" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "id": "ae81a354-ba6e-452a-bb7d-37edbf850d05", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2026-04-24 15:46:21 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Starting initialization routine\n", + "2026-04-24 15:46:21 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Bubble, dew, and critical point initialization completed.\n", + "2026-04-24 15:46:21 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Equilibrium temperature initialization completed.\n", + "2026-04-24 15:46:21 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: State variable initialization completed.\n", + "2026-04-24 15:46:21 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Phase equilibrium initialization completed.\n", + "2026-04-24 15:46:21 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Property initialization routine finished.\n", + "2026-04-24 15:46:21 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Starting initialization routine\n", + "2026-04-24 15:46:21 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Bubble, dew, and critical point initialization completed.\n", + "2026-04-24 15:46:21 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Equilibrium temperature initialization completed.\n", + "2026-04-24 15:46:21 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: State variable initialization completed.\n", + "2026-04-24 15:46:21 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Phase equilibrium initialization completed.\n", + "2026-04-24 15:46:21 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Property initialization routine finished.\n", + "2026-04-24 15:46:21 [INFO] idaes.init.fs.unit.vapor_phase: Starting initialization routine\n", + "2026-04-24 15:46:21 [INFO] idaes.init.fs.unit.vapor_phase: Bubble, dew, and critical point initialization completed.\n", + "2026-04-24 15:46:21 [INFO] idaes.init.fs.unit.vapor_phase: Equilibrium temperature initialization completed.\n", + "2026-04-24 15:46:21 [INFO] idaes.init.fs.unit.vapor_phase: State variable initialization completed.\n", + "2026-04-24 15:46:21 [INFO] idaes.init.fs.unit.vapor_phase: Phase equilibrium initialization completed.\n", + "2026-04-24 15:46:21 [INFO] idaes.init.fs.unit.vapor_phase: Property initialization routine finished.\n", + "2026-04-24 15:46:21 [INFO] idaes.init.fs.unit: Initialization Complete: optimal - \n", + "====================================================================================\n", + "Model Statistics\n", + "\n", + " Jacobian Condition Number: 2.914E+05\n", + "\n", + "------------------------------------------------------------------------------------\n", + "0 WARNINGS\n", + "\n", + " No warnings found!\n", + "\n", + "------------------------------------------------------------------------------------\n", + "6 Cautions\n", + "\n", + " Caution: 9 Variables with value close to their bounds (abs=1.0E-04, rel=1.0E-04)\n", + " Caution: 14 Variables with value close to zero (tol=1.0E-08)\n", + " Caution: 27 Variables with extreme value (<1.0E-04 or >1.0E+04)\n", + " Caution: 2 Constraints with mismatched terms\n", + " Caution: 1 Constraint with potential cancellation of terms\n", + " Caution: 14 extreme Jacobian Entries (<1.0E-04 or >1.0E+04)\n", + "\n", + "------------------------------------------------------------------------------------\n", + "Suggested next steps:\n", + "\n", + " If you still have issues converging your model consider:\n", + "\n", + " prepare_degeneracy_hunter()\n", + " prepare_svd_toolbox()\n", + "\n", + "====================================================================================\n" + ] + } + ], + "source": [ + "scaler_obj = SolventReboilerScaler(overwrite=True)\n", + "scaler_obj.scale_model(m.fs.unit)\n", + "reboiler_init.initialize(m.fs.unit)\n", + "dt = DiagnosticsToolbox(m)\n", + "dt.report_numerical_issues()" + ] + }, + { + "cell_type": "markdown", + "id": "a94bcc79-523e-4a54-9659-0da85ab98dac", + "metadata": {}, + "source": [ + "The condition number decreased by a factor of 18, which is less than what we might have hoped for. Let's check out the SVD toolbox again." + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "id": "baeb6028-71fb-46c9-ac73-ddaf75f1f7d4", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "====================================================================================\n", + "Constraints and Variables associated with smallest singular values\n", + "\n", + " Smallest Singular Value 1:\n", + "\n", + " Variables:\n", + "\n", + " fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[bicarbonate]\n", + " fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[carbamate]\n", + " fs.unit.liquid_phase.properties_out[0.0].apparent_inherent_reaction_extent[carbamate]\n", + "\n", + " Constraints:\n", + "\n", + " fs.unit.unit_material_balance[0.0,CO2]\n", + " fs.unit.unit_material_balance[0.0,H2O]\n", + " fs.unit.liquid_phase.material_balances[0.0,H2O]\n", + " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].total_flow_balance\n", + " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", + "\n", + " Smallest Singular Value 2:\n", + "\n", + " Variables:\n", + "\n", + " fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[carbamate]\n", + " fs.unit.liquid_phase.properties_out[0.0].apparent_inherent_reaction_extent[carbamate]\n", + "\n", + " Constraints:\n", + "\n", + " fs.unit.unit_material_balance[0.0,CO2]\n", + " fs.unit.unit_material_balance[0.0,H2O]\n", + " fs.unit.liquid_phase.material_balances[0.0,H2O]\n", + " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEA_+]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA_+]\n", + "\n", + " Smallest Singular Value 3:\n", + "\n", + " Variables:\n", + "\n", + " fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[bicarbonate]\n", + " fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[carbamate]\n", + "\n", + " Constraints:\n", + "\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,H2O]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,H2O]\n", + " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].total_flow_balance\n", + " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_k_eq_constraint[bicarbonate]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_k_eq_constraint[carbamate]\n", + " fs.unit.liquid_phase.properties_in[0.0].inherent_equilibrium_constraint[bicarbonate]\n", + " fs.unit.liquid_phase.properties_in[0.0].inherent_equilibrium_constraint[carbamate]\n", + "\n", + " Smallest Singular Value 4:\n", + "\n", + " Variables:\n", + "\n", + " fs.unit.liquid_phase.properties_out[0.0].apparent_inherent_reaction_extent[bicarbonate]\n", + "\n", + " Constraints:\n", + "\n", + " fs.unit.unit_material_balance[0.0,CO2]\n", + " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,HCO3_-]\n", + "\n", + " Smallest Singular Value 5:\n", + "\n", + " Variables:\n", + "\n", + " fs.unit.vapor_phase[0.0].flow_mol_phase[Vap]\n", + " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_comp[CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_comp[H2O]\n", + " fs.unit.vapor_phase[0.0].flow_mol\n", + "\n", + " Constraints:\n", + "\n", + " fs.unit.unit_material_balance[0.0,CO2]\n", + " fs.unit.unit_material_balance[0.0,H2O]\n", + " fs.unit.liquid_phase.material_balances[0.0,H2O]\n", + " fs.unit.liquid_phase.material_balances[0.0,MEA]\n", + " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEA_+]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA_+]\n", + " fs.unit.unit_material_balance[0.0,MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].total_flow_balance\n", + " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA_+]\n", + " fs.unit.liquid_phase.properties_out[0.0].sum_mole_frac_out\n", + " fs.unit.vapor_phase[0.0].sum_mole_frac_out\n", + "\n", + "====================================================================================\n" + ] + }, + { + "data": { + "text/plain": [ + "array([0.00069966, 0.00106482, 0.00451863, 0.00578932, 0.05431777,\n", + " 0.06674241, 0.06777552, 0.08956049, 0.14336208, 0.17607054])" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "st = dt.prepare_svd_toolbox()\n", + "st.display_underdetermined_variables_and_constraints([1,2,3,4,5])\n", + "st.s" + ] + }, + { + "cell_type": "markdown", + "id": "3a4af7db-20de-482b-b1a5-5745c14e731f", + "metadata": {}, + "source": [ + "We can see an order-of-magnitude difference between the first four smallest singular values and the fifth-smallest singular value. Inspecting the variables and constraints involved, they all involve the inherent reaction calculations for ionic speciation. Improving the scaling of those variables and constraints might improve the condition number by another one to two orders of magnitude. However, we are reaching the point of diminishing returns for scaling. We can leave the scaler here unless a solver failure forces us to revisit it again.\n", + "\n", + "## Step 7: Reviewing Model Scaling\n", + "\n", + "Before we conclude entirely, let's take a look at all the variable and constraint scaling factors used." + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "id": "28633b75-9a64-4fe6-b27c-c93498413f47", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Scaling Factors for block fs.unit\n", + "\n", + "Variable Scaling Factor Value Scaled Value\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol 1.250E-02 8.389E+01 1.049E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[H2O] 1.000E+00 8.589E-01 8.589E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[MEA] 1.000E+01 1.085E-01 1.085E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[CO2] 1.000E+01 3.260E-02 3.260E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].temperature 3.333E-03 3.925E+02 1.308E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol 1.250E-02 7.410E+01 9.263E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O] 1.000E+00 8.487E-01 8.487E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] 1.000E+01 1.228E-01 1.228E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[CO2] 1.000E+01 2.851E-02 2.851E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].temperature 3.333E-03 3.938E+02 1.313E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", + "fs.unit.vapor_phase[0.0].flow_mol 1.000E-01 9.785E+00 9.785E-01\n", + "fs.unit.vapor_phase[0.0].mole_frac_comp[CO2] 1.000E+01 6.361E-02 6.361E-01\n", + "fs.unit.vapor_phase[0.0].mole_frac_comp[H2O] 1.000E+01 9.364E-01 9.364E+00\n", + "fs.unit.vapor_phase[0.0].mole_frac_comp[N2] 1.000E+01 1.022E-09 1.022E-08\n", + "fs.unit.vapor_phase[0.0].mole_frac_comp[O2] 1.000E+01 1.022E-09 1.022E-08\n", + "fs.unit.vapor_phase[0.0].temperature 3.333E-03 3.938E+02 1.313E+00\n", + "fs.unit.vapor_phase[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", + "fs.unit.liquid_phase.heat[0.0] 8.763E-07 4.306E+05 3.773E-01\n", + "fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,H2O] 1.250E-02 -9.163E+00 -1.145E-01\n", + "fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,MEA] 1.250E-01 0.000E+00 0.000E+00\n", + "fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,CO2] 1.250E-01 -6.224E-01 -7.780E-02\n", + "fs.unit.liquid_phase.enthalpy_transfer[0.0] 8.763E-07 -3.209E+04 -2.812E-02\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase[Liq] 1.250E-02 8.389E+01 1.049E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp[Liq,H2O] 1.000E+00 8.589E-01 8.589E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp[Liq,MEA] 1.000E+01 1.085E-01 1.085E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp[Liq,CO2] 1.000E+01 3.260E-02 3.260E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].phase_frac[Liq] 1.000E+00 1.000E+00 1.000E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,MEACOO_-] 1.250E-01 2.550E+00 3.187E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,HCO3_-] 1.250E+00 1.785E-01 2.231E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,MEA_+] 1.250E-01 2.728E+00 3.410E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,H2O] 1.250E-02 7.187E+01 8.984E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,MEA] 1.250E-01 3.825E+00 4.781E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,CO2] 1.250E+02 6.803E-03 8.504E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,MEACOO_-] 1.000E+01 3.141E-02 3.141E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,HCO3_-] 1.000E+02 2.199E-03 2.199E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,MEA_+] 1.000E+01 3.361E-02 3.361E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,H2O] 1.000E+00 8.856E-01 8.856E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,MEA] 1.000E+01 4.712E-02 4.712E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,CO2] 1.000E+04 8.383E-05 8.383E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[bicarbonate] 1.250E+02 1.785E-01 2.231E+01\n", + "fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[carbamate] 1.250E+02 2.550E+00 3.187E+02\n", + "fs.unit.liquid_phase.properties_in[0.0].log_k_eq[bicarbonate] None -7.578E+00 -7.578E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].log_k_eq[carbamate] None -1.985E+00 -1.985E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-] 1.000E+00 7.168E+00 7.168E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-] 1.000E+00 4.509E+00 4.509E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+] 1.000E+00 7.236E+00 7.236E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,H2O] 1.000E+00 1.051E+01 1.051E+01\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEA] 1.000E+00 7.573E+00 7.573E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,CO2] 1.000E+00 1.242E+00 1.242E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase[Liq] 1.250E-02 7.410E+01 9.263E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,H2O] 1.000E+00 8.487E-01 8.487E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,MEA] 1.000E+01 1.228E-01 1.228E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,CO2] 1.000E+01 2.851E-02 2.851E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].phase_frac[Liq] 1.000E+00 1.000E+00 1.000E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,MEACOO_-] 1.250E-01 2.013E+00 2.516E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,HCO3_-] 1.250E+00 9.684E-02 1.210E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,MEA_+] 1.250E-01 2.110E+00 2.637E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,H2O] 1.250E-02 6.279E+01 7.849E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,MEA] 1.250E-01 4.979E+00 6.224E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,CO2] 1.250E+02 2.455E-03 3.069E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,MEACOO_-] 1.000E+01 2.796E-02 2.796E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,HCO3_-] 1.000E+02 1.345E-03 1.345E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,MEA_+] 1.000E+01 2.931E-02 2.931E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,H2O] 1.000E+00 8.722E-01 8.722E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,MEA] 1.000E+01 6.916E-02 6.916E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,CO2] 1.000E+04 3.410E-05 3.410E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].apparent_inherent_reaction_extent[bicarbonate] 1.250E+02 9.684E-02 1.210E+01\n", + "fs.unit.liquid_phase.properties_out[0.0].apparent_inherent_reaction_extent[carbamate] 1.250E+02 2.013E+00 2.516E+02\n", + "fs.unit.liquid_phase.properties_out[0.0].log_k_eq[bicarbonate] None -7.648E+00 -7.648E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].log_k_eq[carbamate] None -2.079E+00 -2.079E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-] 1.000E+00 7.024E+00 7.024E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-] 1.000E+00 3.989E+00 3.989E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+] 1.000E+00 7.071E+00 7.071E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,H2O] 1.000E+00 1.046E+01 1.046E+01\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA] 1.000E+00 7.929E+00 7.929E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2] 1.000E+00 3.147E-01 3.147E-01\n", + "fs.unit.vapor_phase[0.0].flow_mol_phase[Vap] 1.000E-01 9.785E+00 9.785E-01\n", + "fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2] 1.000E+01 6.361E-02 6.361E-01\n", + "fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O] 1.000E+01 9.364E-01 9.364E+00\n", + "fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,N2] 1.000E+01 1.022E-09 1.022E-08\n", + "fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,O2] 1.000E+01 1.022E-09 1.022E-08\n", + "fs.unit.vapor_phase[0.0].phase_frac[Vap] 1.000E+00 1.000E+00 1.000E+00\n", + "\n", + "Constraint Scaling Factor\n", + "fs.unit.unit_material_balance[0.0,CO2] 1.250E-01\n", + "fs.unit.unit_material_balance[0.0,H2O] 1.250E-02\n", + "fs.unit.unit_material_balance[0.0,N2] 1.000E+00\n", + "fs.unit.unit_material_balance[0.0,O2] 1.000E+00\n", + "fs.unit.unit_material_balance[0.0,MEA] 1.250E-01\n", + "fs.unit.unit_phase_equilibrium[0.0,CO2] 1.000E-04\n", + "fs.unit.unit_phase_equilibrium[0.0,H2O] 1.000E-04\n", + "fs.unit.unit_temperature_equality[0.0] 3.333E-03\n", + "fs.unit.unit_enthalpy_balance[0.0] 5.463E-06\n", + "fs.unit.unit_pressure_balance[0.0] 1.000E-05\n", + "fs.unit.liquid_phase.material_balances[0.0,H2O] 1.250E-02\n", + "fs.unit.liquid_phase.material_balances[0.0,MEA] 1.250E-01\n", + "fs.unit.liquid_phase.material_balances[0.0,CO2] 1.250E-01\n", + "fs.unit.liquid_phase.enthalpy_balances[0.0] 8.763E-07\n", + "fs.unit.liquid_phase.pressure_balance[0.0] 1.000E-05\n", + "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEACOO_-] 1.250E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,HCO3_-] 1.250E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEA_+] 1.250E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,H2O] 1.250E-02\n", + "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEA] 1.250E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2] 1.250E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEACOO_-] 1.250E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,HCO3_-] 1.250E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEA_+] 1.250E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,H2O] 1.250E-02\n", + "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEA] 1.250E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,CO2] 1.250E+02\n", + "fs.unit.liquid_phase.properties_in[0.0].total_flow_balance 1.250E-02\n", + "fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[H2O] 1.000E+01\n", + "fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[MEA] 1.000E+01\n", + "fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2] 1.000E+01\n", + "fs.unit.liquid_phase.properties_in[0.0].phase_fraction_constraint[Liq] 1.000E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].log_k_eq_constraint[bicarbonate] None\n", + "fs.unit.liquid_phase.properties_in[0.0].log_k_eq_constraint[carbamate] None\n", + "fs.unit.liquid_phase.properties_in[0.0].inherent_equilibrium_constraint[bicarbonate] 1.000E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].inherent_equilibrium_constraint[carbamate] 1.000E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-] 4.104E-04\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-] 4.104E-03\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA_+] 4.104E-04\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,H2O] 4.104E-05\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA] 4.104E-04\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2] 4.104E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEACOO_-] 1.250E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,HCO3_-] 1.250E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA_+] 1.250E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,H2O] 1.250E-02\n", + "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA] 1.250E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2] 1.250E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEACOO_-] 1.250E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,HCO3_-] 1.250E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEA_+] 1.250E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,H2O] 1.250E-02\n", + "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEA] 1.250E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,CO2] 1.250E+02\n", + "fs.unit.liquid_phase.properties_out[0.0].sum_mole_frac_out 1.000E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].total_flow_balance 1.250E-02\n", + "fs.unit.liquid_phase.properties_out[0.0].component_flow_balances[H2O] 1.000E+01\n", + "fs.unit.liquid_phase.properties_out[0.0].component_flow_balances[MEA] 1.000E+01\n", + "fs.unit.liquid_phase.properties_out[0.0].component_flow_balances[CO2] 1.000E+01\n", + "fs.unit.liquid_phase.properties_out[0.0].phase_fraction_constraint[Liq] 1.000E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].log_k_eq_constraint[bicarbonate] None\n", + "fs.unit.liquid_phase.properties_out[0.0].log_k_eq_constraint[carbamate] None\n", + "fs.unit.liquid_phase.properties_out[0.0].inherent_equilibrium_constraint[bicarbonate] 1.000E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].inherent_equilibrium_constraint[carbamate] 1.000E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-] 4.104E-04\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-] 4.104E-03\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA_+] 4.104E-04\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,H2O] 4.104E-05\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA] 4.104E-04\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2] 4.104E-01\n", + "fs.unit.vapor_phase[0.0].sum_mole_frac_out 1.000E+00\n", + "fs.unit.vapor_phase[0.0].total_flow_balance 1.000E-01\n", + "fs.unit.vapor_phase[0.0].component_flow_balances[CO2] 1.000E+01\n", + "fs.unit.vapor_phase[0.0].component_flow_balances[H2O] 1.000E+01\n", + "fs.unit.vapor_phase[0.0].component_flow_balances[N2] 1.000E+01\n", + "fs.unit.vapor_phase[0.0].component_flow_balances[O2] 1.000E+01\n", + "fs.unit.vapor_phase[0.0].phase_fraction_constraint[Vap] 1.000E+00\n", + "\n", + "Expression Scaling Hint\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp[Liq,H2O] 1.250E-02\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp[Liq,MEA] 1.250E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp[Liq,CO2] 1.250E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].k_eq[bicarbonate] None\n", + "fs.unit.liquid_phase.properties_in[0.0].k_eq[carbamate] None\n", + "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,MEACOO_-] None\n", + "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,HCO3_-] None\n", + "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,MEA_+] None\n", + "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,H2O] None\n", + "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,MEA] None\n", + "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,CO2] None\n", + "fs.unit.liquid_phase.properties_in[0.0].dens_mol_phase[Liq] 4.104E-05\n", + "fs.unit.liquid_phase.properties_in[0.0].vol_mol_phase[Liq] None\n", + "fs.unit.liquid_phase.properties_in[0.0]._enthalpy_flow_term[Liq] None\n", + "fs.unit.liquid_phase.properties_in[0.0].enth_mol_phase[Liq] 7.010E-05\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_comp[H2O] 1.250E-02\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_comp[MEA] 1.250E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_comp[CO2] 1.250E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp[Liq,H2O] 1.250E-02\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp[Liq,MEA] 1.250E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp[Liq,CO2] 1.250E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].k_eq[bicarbonate] None\n", + "fs.unit.liquid_phase.properties_out[0.0].k_eq[carbamate] None\n", + "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,MEACOO_-] None\n", + "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,HCO3_-] None\n", + "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,MEA_+] None\n", + "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,H2O] None\n", + "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,MEA] None\n", + "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,CO2] None\n", + "fs.unit.liquid_phase.properties_out[0.0].dens_mol_phase[Liq] 4.104E-05\n", + "fs.unit.liquid_phase.properties_out[0.0].vol_mol_phase[Liq] None\n", + "fs.unit.liquid_phase.properties_out[0.0]._enthalpy_flow_term[Liq] None\n", + "fs.unit.liquid_phase.properties_out[0.0].enth_mol_phase[Liq] 7.010E-05\n", + "fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[Liq,H2O] None\n", + "fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[Liq,MEA] None\n", + "fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[Liq,CO2] None\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_comp[H2O] 1.250E-02\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_comp[MEA] 1.250E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_comp[CO2] 1.250E-01\n", + "fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,CO2] 1.000E+00\n", + "fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,H2O] 1.000E+00\n", + "fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,N2] 1.000E+00\n", + "fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,O2] 1.000E+00\n", + "fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,CO2] None\n", + "fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,H2O] None\n", + "fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,N2] None\n", + "fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,O2] None\n", + "fs.unit.vapor_phase[0.0]._enthalpy_flow_term[Vap] None\n", + "fs.unit.vapor_phase[0.0].enth_mol_phase[Vap] 5.463E-05\n", + "fs.unit.vapor_phase[0.0].enth_mol_phase_comp[Vap,CO2] 3.787E-05\n", + "fs.unit.vapor_phase[0.0].enth_mol_phase_comp[Vap,H2O] 9.249E-05\n", + "fs.unit.vapor_phase[0.0].enth_mol_phase_comp[Vap,N2] 5.950E-05\n", + "fs.unit.vapor_phase[0.0].enth_mol_phase_comp[Vap,O2] 5.208E-05\n", + "fs.unit.vapor_phase[0.0].flow_mol_comp[CO2] 1.000E+00\n", + "fs.unit.vapor_phase[0.0].flow_mol_comp[H2O] 1.000E+00\n", + "fs.unit.vapor_phase[0.0].flow_mol_comp[N2] 1.000E+00\n", + "fs.unit.vapor_phase[0.0].flow_mol_comp[O2] 1.000E+00\n" + ] + } + ], + "source": [ + "from idaes.core.scaling.util import report_scaling_factors\n", + "report_scaling_factors(m.fs.unit, descend_into=True)" + ] + }, + { + "cell_type": "markdown", + "id": "31cf3ac5-612f-46db-96b8-044057bbd808", + "metadata": {}, + "source": [ + "Most variable values have scaled values within a couple orders of magnitude of one, which is what we like. The outliers are inherent reaction extents, which we already know are a bit problematic, and variables corresponding to the components $\\text{N}_2$ and $\\text{O}_2$, which are present in the vapor property package but not the vapor stream.\n", + "\n", + "We have reduced the condition number to $3 \\cdot 10^5$, which is not quite as low as we would have liked, but is a vast improvement over the value $3 \\cdot 10^{13}$, which we started out with. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "56bb9ab1-9ca6-4b7c-9072-ab6abb734361", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.12" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From bf36ed6a1d20ffdf4fe588851855a21d78f32aab Mon Sep 17 00:00:00 2001 From: dallan-keylogic <88728506+dallan-keylogic@users.noreply.github.com> Date: Mon, 27 Apr 2026 12:06:37 -0400 Subject: [PATCH 2/7] Suggested changes from Marcus's review Co-authored-by: MarcusHolly <96305519+MarcusHolly@users.noreply.github.com> Co-authored-by: dallan-keylogic <88728506+dallan-keylogic@users.noreply.github.com> --- .../notebooks/docs/scaling/scaling_201.ipynb | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/idaes_examples/notebooks/docs/scaling/scaling_201.ipynb b/idaes_examples/notebooks/docs/scaling/scaling_201.ipynb index 4a601bb3..9a9c10db 100644 --- a/idaes_examples/notebooks/docs/scaling/scaling_201.ipynb +++ b/idaes_examples/notebooks/docs/scaling/scaling_201.ipynb @@ -12,7 +12,7 @@ "# Framework (IDAES IP) was produced under the DOE Institute for the\n", "# Design of Advanced Energy Systems (IDAES).\n", "#\n", - "# Copyright (c) 2018-2023 by the software owners: The Regents of the\n", + "# Copyright (c) 2018-2026 by the software owners: The Regents of the\n", "# University of California, through Lawrence Berkeley National Laboratory,\n", "# National Technology & Engineering Solutions of Sandia, LLC, Carnegie Mellon\n", "# University, West Virginia University Research Corporation, et al.\n", @@ -583,7 +583,7 @@ "\n", "## Step 4: Apply Scaling to Sub-Models\n", "\n", - "First, lets look at how to scale the control volume and state block sub-models. Because the property package for ``vapor_phase`` state block is specified by the user, we do not know what variables and constraints it may contain, so we cannot (and should not) scale it directly. The property package creator (hopefully) created a scaler object that we can use. The zero-dimensional control volume ``liquid_phase`` contains two state blocks, material, energy, and pressure balance constraints, and variables corresponding to additional interaction terms. Because we are choosing which terms to create in the control volume, we could, in principle, scale it at the unit model level. However, because control volumes typically should be scaled in the same way, a submodel scaler has been provided for it as well. Thus, what we want to do here is to call the variable and constraint scaling routines from the ``Scaler`` associated with each sub-model, which we can do using the ``call_submodel_scaler_method`` method." + "First, let's look at how to scale the control volume and state block sub-models. Because the property package for the ``vapor_phase`` state block is specified by the user, we do not know what variables and constraints it may contain, so we cannot (and should not) scale it directly. The property package creator (hopefully) created a scaler object that we can use. The zero-dimensional control volume ``liquid_phase`` contains two state blocks, material, energy, and pressure balance constraints, and variables corresponding to additional interaction terms. Because we are choosing which terms to create in the control volume, we could, in principle, scale it at the unit model level. However, because control volumes typically should be scaled in the same way, a submodel scaler has been provided for it as well. Thus, what we want to do here is to call the variable and constraint scaling routines from the ``Scaler`` associated with each sub-model, which we can do using the ``call_submodel_scaler_method`` method." ] }, { @@ -636,7 +636,7 @@ "id": "c509e071-62a7-449b-a084-7e118d142ddd", "metadata": {}, "source": [ - "In order for the submodel scaling to function properly, default scaling factors need to be set for some variables. The property package scaler cannot know if the system is supposed to be bench scale, pilot scale, or production scale unless the user sets a default. These defaults can be set on a unit model by unit model basis by using the `submodel_scalers` argument, or they can be set at the flowsheet level on the parameter block. We will do the latter.\n", + "In order for the submodel scaling to function properly, default scaling factors need to be set for some variables. The property package scaler cannot know if the system is supposed to be bench scale, pilot scale, or production scale unless the user sets a default for flow rate. These defaults can be set on a unit model by unit model basis by using the `submodel_scalers` argument, or they can be set at the flowsheet level on the parameter block. We will do the latter.\n", "\n", "First, we need to create objects using the modular property submodel scaler class." ] @@ -697,14 +697,14 @@ "source": [ "We can see that we are required to set a default scaling factor for ``flow_mol_phase``. Furthermore, it is recommended to set a default scaling factor for ``enth_mol_phase``, ``visc_d_phase``, and ``therm_cond_phase``. For these latter quantities, there is a method to estimate reasonable scaling factors, but it might not be suitible for all cases.\n", "\n", - "With a inlet flow of about 80 mol/s, a scaling factor of 1/80 is appropriate. We can ignore ``visc_d_phase`` and ``therm_cond_phase``, because the solvent reboiler model does not require dynamic viscosity or thermal conductivity (at present). Molar enthalpy is a tougher quantity to scale.\n", + "With an inlet flow of about 80 mol/s, a scaling factor of 1/80 is appropriate. We can ignore ``visc_d_phase`` and ``therm_cond_phase``, because the solvent reboiler model does not require dynamic viscosity or thermal conductivity (at present). Molar enthalpy is a tougher quantity to scale.\n", "\n", "By convention, the molar enthalpy of each element in its pure form at 25$^\\circ$ C and 1 atm is set equal to zero. In some property packages, enthalpy of formation is taken into account for compounds, while in some property packages it is not. However, the scaling factor for enthalpy should not depend on this convention---only enthalpy *differences* are meaningful. So we need to determine how to determine what constitutes a \"significant\" enthalpy difference for this property package. The way the modular property scaler object estimates this is through the temperature scaling factor, which determines what a \"significant\" temperature difference is, and the observation that a wide range of substances have a specific heat capacity around 2 $\\frac{\\text{J}}{\\text{g K}}$.\n", "\n", "TODO This digression can probably be cut.\n", "~~Liquid water has a heat capacity of 4.18 $\\frac{\\text{J}}{\\text{g K}}$, steam has a heat capacity of 2.03 $\\frac{\\text{J}}{\\text{g K}}$, liquid enthanol has a heat capacity of 2.44, and air has a heat capacity of 1.01 $\\frac{\\text{J}}{\\text{g K}}$ at room temperature. The major outliers are metals and hydrogen gas. Metals tend to have heat capacities less than 1 $\\frac{\\text{J}}{\\text{g K}}$, with iron having 0.449 $\\frac{\\text{J}}{\\text{g K}}$ and gold having 0.129 $\\frac{\\text{J}}{\\text{g K}}$. Hydrogen, by contrast, has a heat capacity of 14.41 $\\frac{\\text{J}}{\\text{g K}}$; the heat capacity of a diatomic gas is about $\\frac{5}{2}R$, in which $R$ is the gas consant, so hydrogen's low molecular weight results in it having a large mass-based heat capacity.~~\n", "\n", - "This default method is good enough for our purposes now. We can revisit it later if necessary." + "This default method is good enough for our purposes now. We can revisit it later, if necessary." ] }, { @@ -928,7 +928,7 @@ } ], "source": [ - "get_scaling_factor(m.fs.unit.vapor_phase[0.0]._enthalpy_flow_term[\"Vap\"]) is None" + "print(get_scaling_factor(m.fs.unit.vapor_phase[0.0]._enthalpy_flow_term[\"Vap\"]))" ] }, { @@ -1217,7 +1217,7 @@ "id": "df43607d-fd78-4ab2-9e40-223c595cc115", "metadata": {}, "source": [ - "Parsing the entire pile of thermodynamic gibberish is unnecessary to plan our next move. We can plainly see that the liquid phase fugacity expression is rife with subtraction and exponentiation, both of which are dangerous for the nominal value expression walker. Even worse, we are scaling based on a failed solution, so the values may be off anyway. It is farbetter to base the scaling factor on the vapor phase fugacity. The `get_expression_nominal_value` function allows the user to get the nominal value of a single expression." + "Parsing the entire pile of thermodynamic gibberish is unnecessary to plan our next move. We can plainly see that the liquid phase fugacity expression is rife with subtraction and exponentiation, both of which are dangerous for the nominal value expression walker. Even worse, we are scaling based on a failed solution, so the values may be off anyway. It is far better to base the scaling factor on the vapor phase fugacity. The `get_expression_nominal_value` function allows the user to get the nominal value of a single expression." ] }, { @@ -1283,7 +1283,7 @@ "id": "9e8f7776-21b3-4e43-a76d-f250a55ac31e", "metadata": {}, "source": [ - "In addition to these problematic unit model level constraints, there are some additional constraints that need scaling factors. Although they might not be problematic under these process conditions, they may be for a scaled-up flowsheet. If they are well-scaled already, we should Let's use the `report_scaling_factors` function to show what they are:" + "In addition to these problematic unit model level constraints, there are some additional constraints that need scaling factors. Although they might not be problematic under these process conditions, they may be for a scaled-up flowsheet. If we suspect they are well-scaled already, we should use the `report_scaling_factors` function to show what they are:" ] }, { From 4599c1bcbf3ecdb1766a85bf3b3ce013c380376d Mon Sep 17 00:00:00 2001 From: Doug A Date: Wed, 29 Apr 2026 17:19:39 -0400 Subject: [PATCH 3/7] advanced scaling techniques --- ...pynb => advanced_scaling_techniques.ipynb} | 1402 +++++++++++++---- 1 file changed, 1101 insertions(+), 301 deletions(-) rename idaes_examples/notebooks/docs/scaling/{scaling_201.ipynb => advanced_scaling_techniques.ipynb} (55%) diff --git a/idaes_examples/notebooks/docs/scaling/scaling_201.ipynb b/idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques.ipynb similarity index 55% rename from idaes_examples/notebooks/docs/scaling/scaling_201.ipynb rename to idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques.ipynb index 9a9c10db..e5d61ff0 100644 --- a/idaes_examples/notebooks/docs/scaling/scaling_201.ipynb +++ b/idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques.ipynb @@ -26,22 +26,22 @@ "id": "80fb4087-ae32-4ca1-9ec1-7fc8b60d3613", "metadata": {}, "source": [ - "# Scaling 201\n", + "# Advanced Scaling Techniques\n", "\n", - "Author: Doug Allan\n", - "Maintainer: Doug Allan\n", - "Updated: 2026-04-24\n", + "Author: Doug Allan\\\n", + "Maintainer: Doug Allan\\\n", + "Updated: 2026-04-30\n", "\n", "## Introduction\n", "\n", - "This notebook is intended to give the user further insight into how the scaling toolbox can be used to improve robustness. By the end of this study, the user should understand:\n", - "* how a default scaler object can be specified for a property pacakge\n", - "* how to set default scaling factors for property package variables\n", - "* the strengths and weaknesses of the ``NominalValueExpressionWalker`` used in ``CustomScalerBase.get_sum_terms_nominal_values`` and ``CustomScalerBase.get_expression_nominal_value`` for use in constraint scaling\n", - "* how to use the ``SVDToolbox`` to troubleshoot scaling issues\n", + "This notebook is intended to give the user further insight into how the scaling toolbox can be used to improve robustness. A large portion of the material is an adaptation of [Allan, Ostace, and Polly (2025)](#references). By the end of this study, the user should understand:\n", + "* How a default scaler object can be specified for a property package\n", + "* How to set default scaling factors for property package variables\n", + "* The strengths and weaknesses of the ``NominalValueExpressionWalker`` used in ``CustomScalerBase.get_sum_terms_nominal_values`` and ``CustomScalerBase.get_expression_nominal_value`` for use in constraint scaling\n", + "* How to use the ``SVDToolbox`` to troubleshoot scaling issues\n", "\n", "## Step 1: Set Up Test Case\n", - "We will use the `SolventReboiler` unit model as a case study. It is a component in a stripping column used for solvent regeneration. It is modeled as a single equilibrium stage with an external heat duty. A completely liquid phase is the inlet stream, with boilup and bottoms outlet streams. The liquid and vapor phases use different configurations of the modular property framework.\n", + "We will use the `SolventReboiler` unit model as a case study. It is a component in a stripping column used for solvent regeneration. It is modeled as a single equilibrium stage with an external heat duty. The inlet stream is entirely liquid, while it has both boilup and bottoms outlet streams. The liquid and vapor phases use different configurations of the modular property framework.\n", "\n", "First, we set up and attempt to initialize the unit model." ] @@ -56,56 +56,531 @@ "name": "stdout", "output_type": "stream", "text": [ - "2026-04-24 15:46:18 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Starting initialization routine\n", - "2026-04-24 15:46:18 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Bubble, dew, and critical point initialization completed.\n", - "2026-04-24 15:46:18 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Equilibrium temperature initialization completed.\n", - "2026-04-24 15:46:18 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: State variable initialization completed.\n", - "2026-04-24 15:46:18 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Phase equilibrium initialization completed.\n", - "2026-04-24 15:46:19 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Property initialization routine finished.\n", - "2026-04-24 15:46:19 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Starting initialization routine\n", - "2026-04-24 15:46:19 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Bubble, dew, and critical point initialization completed.\n", - "2026-04-24 15:46:19 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Equilibrium temperature initialization completed.\n", - "2026-04-24 15:46:19 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: State variable initialization completed.\n", - "2026-04-24 15:46:19 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Phase equilibrium initialization completed.\n", - "2026-04-24 15:46:19 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Property initialization routine finished.\n", - "2026-04-24 15:46:19 [INFO] idaes.init.fs.unit.vapor_phase: Starting initialization routine\n", - "2026-04-24 15:46:19 [INFO] idaes.init.fs.unit.vapor_phase: Bubble, dew, and critical point initialization completed.\n", - "2026-04-24 15:46:19 [INFO] idaes.init.fs.unit.vapor_phase: Equilibrium temperature initialization completed.\n", - "2026-04-24 15:46:19 [INFO] idaes.init.fs.unit.vapor_phase: State variable initialization completed.\n", - "2026-04-24 15:46:19 [INFO] idaes.init.fs.unit.vapor_phase: Phase equilibrium initialization completed.\n", - "2026-04-24 15:46:19 [INFO] idaes.init.fs.unit.vapor_phase: Property initialization routine finished.\n", - "2026-04-24 15:46:19 [INFO] idaes.init.fs.unit: Initialization Complete: maxIterations - \n", + "2026-04-29 17:11:54 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Starting initialization routine\n", + "2026-04-29 17:11:54 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Bubble, dew, and critical point initialization completed.\n", + "2026-04-29 17:11:54 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Equilibrium temperature initialization completed.\n", + "2026-04-29 17:11:54 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: State variable initialization completed.\n", + "2026-04-29 17:11:54 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Phase equilibrium initialization completed.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Ipopt 3.13.2: linear_solver=\"ma57\"\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: max_iter=200\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: nlp_scaling_method=\"gradient-based\"\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: tol=1e-06\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: ******************************************************************************\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: For more information visit http://projects.coin-or.org/Ipopt\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: This version of Ipopt was compiled from source code available at\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: for large-scale scientific computation. All technical papers, sales and\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: publicity material resulting from use of the HSL codes within IPOPT must\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: contain the following acknowledgement:\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: HSL, a collection of Fortran codes for large-scale scientific\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: computation. See http://www.hsl.rl.ac.uk.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: ******************************************************************************\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of nonzeros in equality constraint Jacobian...: 74\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of nonzeros in inequality constraint Jacobian.: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of nonzeros in Lagrangian Hessian.............: 42\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Total number of variables............................: 18\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: variables with only lower bounds: 6\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: variables with lower and upper bounds: 12\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: variables with only upper bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Total number of equality constraints.................: 18\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Total number of inequality constraints...............: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: inequality constraints with only lower bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: inequality constraints with lower and upper bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: inequality constraints with only upper bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 0 0.0000000e+00 4.13e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Reallocating memory for MA57: lfact (1377)\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 1 0.0000000e+00 4.05e+02 1.89e+12 -1.0 6.07e+01 - 1.92e-01 1.98e-02H 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 2 0.0000000e+00 1.62e+04 1.56e+17 -1.0 8.76e+01 - 1.69e-01 5.07e-01H 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 3 0.0000000e+00 1.62e+04 1.55e+17 -1.0 4.59e+01 - 1.21e-07 3.23e-03H 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 4 0.0000000e+00 2.15e+04 1.93e+17 -1.0 4.88e+01 - 1.06e-02 9.12e-01h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Reallocating memory for MA57: lfact (1542)\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 5 0.0000000e+00 2.15e+04 1.93e+17 -1.0 3.05e+02 - 4.08e-04 6.58e-04h 2\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Reallocating memory for MA57: lfact (1662)\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 6 0.0000000e+00 2.09e+04 1.87e+17 -1.0 1.11e+01 - 4.04e-03 3.08e-02h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 7 0.0000000e+00 1.50e+04 1.37e+17 -1.0 1.37e+01 - 1.44e-04 3.14e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 8 0.0000000e+00 1.49e+04 1.36e+17 -1.0 4.21e+00 - 5.37e-01 9.11e-03h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 9 0.0000000e+00 1.49e+04 1.36e+17 -1.0 4.10e+00 - 9.86e-01 9.35e-05h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 10r 0.0000000e+00 1.49e+04 1.00e+03 1.6 0.00e+00 - 0.00e+00 4.68e-07R 2\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 11r 0.0000000e+00 5.25e+03 2.22e+03 1.6 3.13e+04 - 3.88e-03 1.14e-03f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 12r 0.0000000e+00 5.08e+03 4.24e+04 1.6 1.22e+03 - 1.88e-01 5.18e-03f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 13r 0.0000000e+00 4.77e+03 3.36e+04 1.6 6.27e+01 - 3.06e-02 6.76e-02f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 14r 0.0000000e+00 4.33e+03 1.32e+05 1.6 8.06e+00 - 5.05e-01 9.81e-02f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 15r 0.0000000e+00 4.19e+03 1.12e+05 1.6 9.20e+00 - 3.38e-01 3.25e-02f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 16r 0.0000000e+00 1.89e+03 5.50e+04 1.6 2.54e+00 - 8.42e-02 7.08e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 17r 0.0000000e+00 1.72e+03 4.73e+04 1.6 7.82e+00 - 2.36e-01 1.01e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 18r 0.0000000e+00 1.14e+03 2.84e+04 1.6 1.92e+00 - 7.10e-01 4.02e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 19r 0.0000000e+00 1.06e+03 2.92e+04 1.6 5.12e+00 - 7.85e-01 7.79e-02f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 20r 0.0000000e+00 2.69e+02 3.66e+03 1.6 5.52e-01 - 1.00e+00 9.33e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 21r 0.0000000e+00 1.64e+01 3.96e+02 0.9 1.63e-01 - 9.76e-01 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 22r 0.0000000e+00 6.87e-01 1.09e+02 0.2 3.52e-02 - 1.00e+00 9.59e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 23r 0.0000000e+00 2.05e-01 8.47e+03 -0.5 2.72e-03 - 1.00e+00 6.98e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 24r 0.0000000e+00 1.34e-03 2.18e-01 -0.5 1.87e-03 - 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 25r 0.0000000e+00 1.29e-02 1.88e+02 -2.9 3.36e-04 - 1.00e+00 9.47e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 26r 0.0000000e+00 2.90e-06 4.04e-05 -2.9 7.48e-05 - 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of Iterations....: 26\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: (scaled) (unscaled)\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Constraint violation....: 2.1131334015933589e-08 2.8957967970200116e-06\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Overall NLP error.......: 2.1131334015933589e-08 2.8957967970200116e-06\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of objective function evaluations = 34\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of objective gradient evaluations = 12\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of equality constraint evaluations = 36\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of inequality constraint evaluations = 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of equality constraint Jacobian evaluations = 28\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of inequality constraint Jacobian evaluations = 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of Lagrangian Hessian evaluations = 26\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Total CPU secs in IPOPT (w/o function evaluations) = 0.006\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Total CPU secs in NLP function evaluations = 0.000\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: EXIT: Optimal Solution Found.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Property initialization routine finished.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Starting initialization routine\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Bubble, dew, and critical point initialization completed.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Equilibrium temperature initialization completed.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: State variable initialization completed.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Phase equilibrium initialization completed.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Ipopt 3.13.2: linear_solver=\"ma57\"\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: max_iter=200\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: nlp_scaling_method=\"gradient-based\"\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: tol=1e-06\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: ******************************************************************************\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: For more information visit http://projects.coin-or.org/Ipopt\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: This version of Ipopt was compiled from source code available at\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: for large-scale scientific computation. All technical papers, sales and\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: publicity material resulting from use of the HSL codes within IPOPT must\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: contain the following acknowledgement:\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: HSL, a collection of Fortran codes for large-scale scientific\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: computation. See http://www.hsl.rl.ac.uk.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: ******************************************************************************\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of nonzeros in equality constraint Jacobian...: 74\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of nonzeros in inequality constraint Jacobian.: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of nonzeros in Lagrangian Hessian.............: 42\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Total number of variables............................: 18\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: variables with only lower bounds: 6\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: variables with lower and upper bounds: 12\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: variables with only upper bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Total number of equality constraints.................: 18\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Total number of inequality constraints...............: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: inequality constraints with only lower bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: inequality constraints with lower and upper bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: inequality constraints with only upper bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 0 0.0000000e+00 4.13e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Reallocating memory for MA57: lfact (1377)\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 1 0.0000000e+00 4.05e+02 1.89e+12 -1.0 6.07e+01 - 1.92e-01 1.98e-02H 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 2 0.0000000e+00 1.62e+04 1.56e+17 -1.0 8.76e+01 - 1.69e-01 5.07e-01H 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 3 0.0000000e+00 1.62e+04 1.55e+17 -1.0 4.59e+01 - 1.21e-07 3.23e-03H 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 4 0.0000000e+00 2.15e+04 1.93e+17 -1.0 4.88e+01 - 1.06e-02 9.12e-01h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Reallocating memory for MA57: lfact (1542)\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 5 0.0000000e+00 2.15e+04 1.93e+17 -1.0 3.05e+02 - 4.08e-04 6.58e-04h 2\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Reallocating memory for MA57: lfact (1662)\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 6 0.0000000e+00 2.09e+04 1.87e+17 -1.0 1.11e+01 - 4.04e-03 3.08e-02h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 7 0.0000000e+00 1.50e+04 1.37e+17 -1.0 1.37e+01 - 1.44e-04 3.14e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 8 0.0000000e+00 1.49e+04 1.36e+17 -1.0 4.21e+00 - 5.37e-01 9.11e-03h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 9 0.0000000e+00 1.49e+04 1.36e+17 -1.0 4.10e+00 - 9.86e-01 9.35e-05h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 10r 0.0000000e+00 1.49e+04 1.00e+03 1.6 0.00e+00 - 0.00e+00 4.68e-07R 2\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 11r 0.0000000e+00 5.25e+03 2.22e+03 1.6 3.13e+04 - 3.88e-03 1.14e-03f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 12r 0.0000000e+00 5.08e+03 4.24e+04 1.6 1.22e+03 - 1.88e-01 5.18e-03f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 13r 0.0000000e+00 4.77e+03 3.36e+04 1.6 6.27e+01 - 3.06e-02 6.76e-02f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 14r 0.0000000e+00 4.33e+03 1.32e+05 1.6 8.06e+00 - 5.05e-01 9.81e-02f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 15r 0.0000000e+00 4.19e+03 1.12e+05 1.6 9.20e+00 - 3.38e-01 3.25e-02f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 16r 0.0000000e+00 1.89e+03 5.50e+04 1.6 2.54e+00 - 8.42e-02 7.08e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 17r 0.0000000e+00 1.72e+03 4.73e+04 1.6 7.82e+00 - 2.36e-01 1.01e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 18r 0.0000000e+00 1.14e+03 2.84e+04 1.6 1.92e+00 - 7.10e-01 4.02e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 19r 0.0000000e+00 1.06e+03 2.92e+04 1.6 5.12e+00 - 7.85e-01 7.79e-02f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 20r 0.0000000e+00 2.69e+02 3.66e+03 1.6 5.52e-01 - 1.00e+00 9.33e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 21r 0.0000000e+00 1.64e+01 3.96e+02 0.9 1.63e-01 - 9.76e-01 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 22r 0.0000000e+00 6.87e-01 1.09e+02 0.2 3.52e-02 - 1.00e+00 9.59e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 23r 0.0000000e+00 2.05e-01 8.47e+03 -0.5 2.72e-03 - 1.00e+00 6.98e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 24r 0.0000000e+00 1.34e-03 2.18e-01 -0.5 1.87e-03 - 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 25r 0.0000000e+00 1.29e-02 1.88e+02 -2.9 3.36e-04 - 1.00e+00 9.47e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 26r 0.0000000e+00 2.90e-06 4.04e-05 -2.9 7.48e-05 - 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of Iterations....: 26\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: (scaled) (unscaled)\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Constraint violation....: 2.1131334015933589e-08 2.8957967970200116e-06\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Overall NLP error.......: 2.1131334015933589e-08 2.8957967970200116e-06\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of objective function evaluations = 34\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of objective gradient evaluations = 12\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of equality constraint evaluations = 36\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of inequality constraint evaluations = 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of equality constraint Jacobian evaluations = 28\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of inequality constraint Jacobian evaluations = 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of Lagrangian Hessian evaluations = 26\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Total CPU secs in IPOPT (w/o function evaluations) = 0.008\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Total CPU secs in NLP function evaluations = 0.000\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: EXIT: Optimal Solution Found.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Property initialization routine finished.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase: Control volume properties initialization complete\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase: Control volume reactions initialization complete\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit: Initialization Step 1 Complete.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: Starting initialization routine\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: Bubble, dew, and critical point initialization completed.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: Equilibrium temperature initialization completed.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: State variable initialization completed.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: Phase equilibrium initialization completed.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: Property initialization routine finished.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit: Initialization Step 2 Complete.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Ipopt 3.13.2: linear_solver=\"ma57\"\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: max_iter=200\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: nlp_scaling_method=\"gradient-based\"\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: tol=1e-06\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: ******************************************************************************\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: For more information visit http://projects.coin-or.org/Ipopt\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: This version of Ipopt was compiled from source code available at\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: for large-scale scientific computation. All technical papers, sales and\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: publicity material resulting from use of the HSL codes within IPOPT must\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: contain the following acknowledgement:\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: HSL, a collection of Fortran codes for large-scale scientific\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: computation. See http://www.hsl.rl.ac.uk.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: ******************************************************************************\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of nonzeros in equality constraint Jacobian...: 231\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of nonzeros in inequality constraint Jacobian.: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of nonzeros in Lagrangian Hessian.............: 149\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Total number of variables............................: 51\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: variables with only lower bounds: 12\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: variables with lower and upper bounds: 34\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: variables with only upper bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Total number of equality constraints.................: 51\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Total number of inequality constraints...............: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: inequality constraints with only lower bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: inequality constraints with lower and upper bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: inequality constraints with only upper bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 0 0.0000000e+00 3.62e+06 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Reallocating memory for MA57: lfact (3323)\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 1 0.0000000e+00 3.00e+06 1.18e+02 -1.0 3.71e+04 - 5.00e-01 1.73e-01h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 2 0.0000000e+00 2.99e+06 3.06e+03 -1.0 2.81e+04 - 8.76e-01 3.30e-03h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 3 0.0000000e+00 2.99e+06 8.95e+07 -1.0 2.80e+04 - 9.79e-01 3.34e-05h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 4r 0.0000000e+00 2.99e+06 1.00e+03 1.9 0.00e+00 - 0.00e+00 1.74e-07R 2\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 5r 0.0000000e+00 2.93e+06 9.98e+02 1.9 3.19e+04 - 2.43e-03 2.43e-03f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 6r 0.0000000e+00 2.86e+06 1.02e+03 1.2 3.69e+02 - 3.26e-01 2.09e-03f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 7r 0.0000000e+00 2.23e+06 1.04e+03 1.2 2.85e+02 - 1.93e-01 8.65e-02f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 8r 0.0000000e+00 1.90e+06 1.12e+05 1.2 2.94e+02 - 7.31e-02 2.42e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 9r 0.0000000e+00 1.44e+06 7.08e+04 1.2 1.51e+02 - 7.79e-01 2.13e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 10r 0.0000000e+00 1.21e+06 3.79e+04 1.2 1.60e+00 2.0 4.46e-01 1.46e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 11r 0.0000000e+00 7.63e+04 1.14e+04 1.2 9.97e+01 - 3.46e-01 9.00e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 12r 0.0000000e+00 4.57e+04 2.79e+04 1.2 8.49e+01 - 1.00e+00 2.61e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 13r 0.0000000e+00 5.79e+04 9.55e+03 1.2 3.35e+01 - 1.00e+00 7.44e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 14r 0.0000000e+00 1.21e+05 1.45e+04 1.2 2.11e+01 - 1.00e+00 1.00e+00h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 15r 0.0000000e+00 2.24e+05 6.34e+02 1.2 7.86e+00 - 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 16r 0.0000000e+00 2.19e+05 4.22e+03 0.5 1.77e+00 - 1.00e+00 9.43e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 17r 0.0000000e+00 3.93e+05 6.53e+02 0.5 1.02e+02 - 5.02e-01 4.46e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 18r 0.0000000e+00 4.24e+05 4.17e+03 0.5 1.55e+01 - 1.00e+00 2.17e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 19r 0.0000000e+00 4.87e+05 1.47e+01 0.5 7.37e+00 - 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 20r 0.0000000e+00 5.23e+05 2.31e+03 -0.9 1.53e+00 - 9.40e-01 7.50e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 21r 0.0000000e+00 5.39e+05 7.30e+03 -0.9 2.08e+02 - 8.07e-01 3.86e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 22r 0.0000000e+00 5.39e+05 5.05e+03 -0.9 1.37e+02 - 1.00e+00 4.43e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 23r 0.0000000e+00 5.38e+05 7.93e+00 -0.9 7.27e+01 - 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 24r 0.0000000e+00 5.39e+05 1.75e-03 -0.9 2.41e-01 - 1.00e+00 1.00e+00h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 25r 0.0000000e+00 5.44e+05 2.59e+01 -3.6 3.79e+00 - 9.90e-01 9.73e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 26r 0.0000000e+00 4.44e+05 3.73e+02 -3.6 6.08e+03 - 7.62e-02 6.44e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 27r 0.0000000e+00 3.34e+05 7.09e+02 -3.6 2.85e+03 - 5.42e-02 9.37e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 28r 0.0000000e+00 2.87e+03 9.51e+02 -3.6 1.42e+03 - 1.73e-01 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 29r 0.0000000e+00 8.65e+04 2.35e+02 -3.6 1.10e+03 - 1.00e+00 1.00e+00H 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 30r 0.0000000e+00 8.28e+04 4.88e-01 -3.6 1.19e+02 - 1.00e+00 1.00e+00h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 31r 0.0000000e+00 8.28e+04 9.25e-05 -3.6 2.69e-01 - 1.00e+00 1.00e+00h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 32r 0.0000000e+00 8.28e+04 2.10e+00 -5.4 5.64e-02 - 1.00e+00 9.70e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 33r 0.0000000e+00 8.28e+04 2.49e+02 -5.4 1.00e-03 1.5 8.85e-01 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 34r 0.0000000e+00 8.27e+04 3.33e-02 -5.4 3.00e-03 1.0 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 35r 0.0000000e+00 8.27e+04 3.31e-02 -5.4 8.93e-03 0.6 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 36r 0.0000000e+00 8.26e+04 3.24e-02 -5.4 2.63e-02 0.1 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 37r 0.0000000e+00 8.23e+04 3.06e-02 -5.4 7.43e-02 -0.4 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 38r 0.0000000e+00 8.16e+04 2.59e-02 -5.4 1.89e-01 -0.9 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 39r 0.0000000e+00 8.02e+04 4.92e-02 -5.4 3.67e-01 -1.3 1.00e+00 1.00e+00h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 40r 0.0000000e+00 7.85e+04 6.76e-02 -5.4 1.01e+00 -1.8 1.00e+00 1.00e+00h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 41r 0.0000000e+00 7.76e+04 2.21e-02 -5.4 3.03e+00 -2.3 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 42r 0.0000000e+00 7.73e+04 1.54e-02 -5.4 9.07e+00 -2.8 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 43r 0.0000000e+00 7.69e+04 1.54e-02 -5.4 2.72e+01 -3.2 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 44r 0.0000000e+00 7.57e+04 9.45e-02 -5.4 8.16e+01 -3.7 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 45r 0.0000000e+00 7.21e+04 7.98e-01 -5.4 2.45e+02 -4.2 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 46r 0.0000000e+00 6.17e+04 5.91e+00 -5.4 7.40e+02 -4.7 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 47r 0.0000000e+00 3.69e+04 5.13e+01 -5.4 2.31e+03 -5.2 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 48r 0.0000000e+00 7.15e+04 1.47e+02 -5.4 1.10e+04 -5.6 1.00e+00 2.17e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 49r 0.0000000e+00 7.15e+04 4.98e+02 -5.4 4.07e+03 -5.2 1.00e+00 5.56e-06h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 50r 0.0000000e+00 2.07e+05 4.58e+03 -5.4 2.01e+04 -5.7 4.61e-01 1.75e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 51r 0.0000000e+00 1.19e+06 4.31e+04 -5.4 9.31e+03 -5.3 2.11e-06 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 52r 0.0000000e+00 1.16e+06 3.63e+04 -5.4 1.14e+02 -0.3 4.01e-01 1.23e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 53r 0.0000000e+00 1.16e+06 3.63e+04 -5.4 2.83e+01 0.1 7.36e-01 7.74e-07h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 54r 0.0000000e+00 1.16e+06 3.63e+04 -5.4 3.94e+03 - 1.59e-01 7.41e-06h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 55r 0.0000000e+00 7.95e+05 2.50e+04 -5.4 4.00e+03 - 7.84e-01 3.17e-01h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 56r 0.0000000e+00 3.83e+05 1.19e+04 -5.4 1.69e+03 - 1.35e-05 5.23e-01h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 57r 0.0000000e+00 2.95e+05 9.19e+03 -5.4 9.94e+00 -0.4 5.56e-01 2.31e-01h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 58r 0.0000000e+00 1.29e+04 7.45e+02 -5.4 1.55e+03 - 2.88e-06 1.00e+00h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 59r 0.0000000e+00 1.05e+04 3.57e+00 -5.4 8.95e-02 -0.8 1.00e+00 1.00e+00h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 60r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 7.60e-02 -1.3 1.00e+00 1.00e+00h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 61r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 2.28e-01 -1.8 1.00e+00 2.50e-01h 3\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 62r 0.0000000e+00 1.05e+04 1.03e-02 -5.4 6.84e-01 -2.3 1.00e+00 1.56e-02h 7\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 63r 0.0000000e+00 1.05e+04 3.12e-02 -5.4 2.05e+00 -2.8 1.00e+00 9.77e-04h 11\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 64r 0.0000000e+00 1.05e+04 9.35e-02 -5.4 6.16e+00 -3.2 1.00e+00 1.22e-04h 14\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 65r 0.0000000e+00 1.05e+04 2.81e-01 -5.4 1.85e+01 -3.7 1.00e+00 7.45e-09h 28\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 66r 0.0000000e+00 1.05e+04 8.49e-01 -5.4 5.60e+01 -4.2 1.00e+00 1.86e-09h 30\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 67r 0.0000000e+00 1.05e+04 2.61e+00 -5.4 1.72e+02 -4.7 1.00e+00 1.16e-10h 34\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 68r 0.0000000e+00 1.05e+04 8.40e+00 -5.4 5.54e+02 -5.1 1.00e+00 3.64e-12h 39\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 69r 0.0000000e+00 1.05e+04 8.40e+00 -5.4 2.14e+03 -5.6 0.00e+00 3.59e-18R 58\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 70r 0.0000000e+00 1.05e+04 1.94e+01 -5.4 4.50e+04 -6.1 1.63e-02 1.43e-12f 35\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 71r 0.0000000e+00 1.05e+04 3.85e+01 -5.4 2.54e+03 -5.7 1.00e+00 1.27e-11f 36\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 72r 0.0000000e+00 1.05e+04 1.11e+01 -5.4 7.22e+02 -5.2 9.93e-01 2.91e-11f 36\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 73r 0.0000000e+00 1.05e+04 3.70e+01 -5.4 3.05e+03 -5.7 7.35e-01 1.32e-12f 39\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 74r 0.0000000e+00 1.05e+04 1.25e+01 -5.4 8.27e+02 -5.3 1.00e+00 3.64e-12f 39\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 75r 0.0000000e+00 1.05e+04 3.60e+01 -5.4 3.72e+03 -5.8 5.36e-01 1.35e-13f 42\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 76r 0.0000000e+00 1.05e+04 1.44e+01 -5.4 9.51e+02 -5.3 1.00e+00 1.14e-13f 44\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 77r 0.0000000e+00 1.05e+04 2.35e+01 -5.4 4.61e+03 -5.8 1.64e-01 1.36e-14f 45\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 78r 0.0000000e+00 1.05e+04 1.66e+01 -5.4 1.10e+03 -5.4 1.00e+00 3.55e-15f 49\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 79r 0.0000000e+00 1.05e+04 2.55e+01 -5.4 5.86e+03 -5.9 1.22e-01 3.35e-16f 50\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 80r 0.0000000e+00 2.67e+04 5.84e+01 -5.4 1.27e+03 -5.4 1.00e+00 8.72e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 81r 0.0000000e+00 2.67e+04 2.19e+03 -5.4 1.28e+03 - 4.11e-03 2.62e-05w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 82r 0.0000000e+00 4.42e+04 8.23e+02 -5.4 3.84e+03 -5.9 5.02e-01 4.78e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 83r 0.0000000e+00 1.05e+04 1.92e+01 -5.4 1.21e+04 - 1.00e+00 7.74e-16f 50\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 84r 0.0000000e+00 1.05e+04 2.07e+01 -5.4 1.47e+03 -5.5 4.87e-01 3.33e-16h 52\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 85r 0.0000000e+00 1.05e+04 5.09e+01 -5.4 1.08e+04 -6.0 2.11e-01 1.14e-17f 54\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 86r 0.0000000e+00 1.05e+04 6.78e+01 -5.4 1.72e+03 -5.5 1.00e+00 1.78e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 87r 0.0000000e+00 1.05e+04 1.11e+02 -5.4 1.65e+04 -6.0 4.54e-02 1.86e-18f 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 88r 0.0000000e+00 1.05e+04 2.03e+02 -5.4 2.02e+03 -5.6 1.00e+00 1.52e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 89r 0.0000000e+00 1.05e+04 3.30e+02 -5.4 3.06e+04 -6.1 2.34e-02 1.00e-18f 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 90r 0.0000000e+00 1.05e+04 7.12e+02 -5.4 2.38e+03 -5.7 1.00e+00 1.29e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 91r 0.0000000e+00 1.05e+04 7.29e+02 -5.4 9.01e+04 -6.1 3.00e-04 3.41e-19f 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 92r 0.0000000e+00 1.05e+04 3.99e+01 -5.4 2.95e+03 -5.7 3.70e-01 2.84e-18h 59\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 93r 0.0000000e+00 2.20e+04 3.07e+01 -5.4 7.91e+02 -5.3 1.00e+00 1.00e+00w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 94r 0.0000000e+00 3.01e+04 4.20e+01 -5.4 2.61e+03 -5.8 7.22e-01 2.55e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 95r 0.0000000e+00 3.01e+04 1.37e+03 -5.4 1.07e+03 - 1.99e-03 3.17e-05w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 96r 0.0000000e+00 1.05e+04 1.20e+01 -5.4 7.00e+03 -6.2 1.00e+00 1.78e-15h 49\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 97r 0.0000000e+00 1.05e+04 2.31e+01 -5.4 4.29e+03 -5.8 2.10e-01 6.00e-11f 33\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 98r 0.0000000e+00 1.05e+04 1.59e+01 -5.4 1.05e+03 -5.4 1.00e+00 7.28e-12f 38\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 99r 0.0000000e+00 1.05e+04 2.46e+01 -5.4 5.40e+03 -5.9 1.33e-01 4.76e-11f 33\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 100r 0.0000000e+00 1.05e+04 1.83e+01 -5.4 1.21e+03 -5.4 1.00e+00 1.07e-10f 34\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 101r 0.0000000e+00 1.05e+04 2.73e+01 -5.4 7.03e+03 -5.9 1.02e-01 3.66e-11f 33\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 102r 0.0000000e+00 1.05e+04 2.77e+01 -5.4 1.40e+03 -5.5 1.00e+00 1.43e-12f 40\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 103r 0.0000000e+00 1.05e+04 4.37e+01 -5.4 9.60e+03 -6.0 7.47e-02 5.24e-14f 42\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 104r 0.0000000e+00 1.05e+04 6.49e+01 -5.4 1.63e+03 -5.5 1.00e+00 7.69e-14f 44\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 105r 0.0000000e+00 1.05e+04 1.04e+02 -5.4 1.42e+04 -6.0 5.06e-02 1.11e-15f 47\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 106r 0.0000000e+00 2.67e+04 1.58e+01 -5.4 1.91e+03 -5.6 1.00e+00 5.77e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 107r 0.0000000e+00 2.67e+04 1.40e+03 -5.4 9.67e+02 - 2.90e-03 3.66e-04w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 108r 0.0000000e+00 4.39e+04 4.78e+02 -5.4 5.57e+03 -6.1 3.84e-01 3.25e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 109r 0.0000000e+00 1.05e+04 1.80e+02 -5.4 6.38e+03 - 1.00e+00 4.10e-15f 47\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 110r 0.0000000e+00 1.05e+04 2.40e+02 -5.4 2.26e+03 -5.6 3.17e-01 3.47e-15f 48\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 111r 0.0000000e+00 1.05e+04 5.44e+02 -5.4 6.90e+04 -6.1 2.06e-02 1.14e-16f 48\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 112r 0.0000000e+00 1.05e+04 4.95e+01 -5.4 2.79e+03 -5.7 2.55e-01 7.69e-16f 51\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 113r 0.0000000e+00 1.05e+04 1.15e+01 -5.4 7.57e+02 -5.3 1.00e+00 7.11e-15f 48\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 114r 0.0000000e+00 1.05e+04 2.06e+01 -5.4 3.26e+03 -5.7 2.41e-01 6.02e-16f 50\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 115r 0.0000000e+00 1.05e+04 1.32e+01 -5.4 8.68e+02 -5.3 1.00e+00 2.22e-16h 53\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 116r 0.0000000e+00 1.05e+04 2.17e+01 -5.4 3.99e+03 -5.8 1.79e-01 3.07e-17h 54\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 117r 0.0000000e+00 1.05e+04 1.51e+01 -5.4 9.98e+02 -5.4 1.00e+00 2.78e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 118r 0.0000000e+00 1.05e+04 2.38e+01 -5.4 4.99e+03 -5.8 1.44e-01 6.14e-18h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 119r 0.0000000e+00 2.67e+04 5.98e+01 -5.4 1.15e+03 -5.4 1.00e+00 9.60e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 120r 0.0000000e+00 2.67e+04 2.31e+03 -5.4 1.66e+03 - 4.25e-03 1.30e-05w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 121r 0.0000000e+00 4.43e+04 8.41e+02 -5.4 3.52e+03 -5.9 5.33e-01 5.24e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 122r 0.0000000e+00 1.05e+04 1.75e+01 -5.4 1.31e+04 - 1.00e+00 2.66e-17h 55\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 123r 0.0000000e+00 1.05e+04 1.89e+01 -5.4 1.33e+03 -5.5 5.38e-01 2.30e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 124r 0.0000000e+00 1.05e+04 4.92e+01 -5.4 8.61e+03 -5.9 2.71e-01 3.56e-18h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 125r 0.0000000e+00 1.05e+04 2.98e+01 -5.4 1.55e+03 -5.5 1.00e+00 1.98e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 126r 0.0000000e+00 1.05e+04 4.92e+01 -5.4 1.23e+04 -6.0 6.33e-02 2.48e-18h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 127r 0.0000000e+00 1.05e+04 8.12e+01 -5.4 1.82e+03 -5.6 1.00e+00 1.69e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 128r 0.0000000e+00 1.05e+04 1.31e+02 -5.4 2.00e+04 -6.0 3.59e-02 1.53e-18f 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 129r 0.0000000e+00 1.05e+04 2.54e+02 -5.4 2.14e+03 -5.6 1.00e+00 1.43e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 130r 0.0000000e+00 1.05e+04 4.15e+02 -5.4 4.32e+04 -6.1 1.66e-02 7.10e-19f 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 131r 0.0000000e+00 1.05e+04 9.52e+02 -5.4 2.53e+03 -5.7 1.00e+00 1.21e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 132r 0.0000000e+00 2.67e+04 2.24e+01 -5.4 4.51e+05 -6.1 1.18e-04 2.45e-03w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 133r 0.0000000e+00 4.32e+04 1.53e+02 -5.4 4.75e+04 -6.6 3.50e-02 3.68e-02w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 134r 0.0000000e+00 4.32e+04 3.80e+02 -5.4 3.44e+03 - 1.99e-02 3.86e-06w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 135r 0.0000000e+00 1.05e+04 9.98e+02 -5.4 8.04e+02 - 1.18e-04 6.81e-20f 55\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 136r 0.0000000e+00 1.05e+04 2.21e+01 -5.4 8.37e+02 -5.3 6.52e-01 5.55e-17h 55\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 137r 0.0000000e+00 1.05e+04 2.91e+01 -5.4 3.73e+03 -5.8 2.04e-01 8.22e-18h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 138r 0.0000000e+00 1.05e+04 1.45e+01 -5.4 9.53e+02 -5.3 1.00e+00 5.55e-17h 55\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 139r 0.0000000e+00 1.05e+04 2.31e+01 -5.4 4.63e+03 -5.8 1.55e-01 6.62e-18h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 140r 0.0000000e+00 1.05e+04 1.67e+01 -5.4 1.10e+03 -5.4 1.00e+00 2.78e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 141r 0.0000000e+00 1.05e+04 2.55e+01 -5.4 5.89e+03 -5.9 1.22e-01 5.20e-18h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 142r 0.0000000e+00 1.05e+04 1.93e+01 -5.4 1.27e+03 -5.4 1.00e+00 2.41e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 143r 0.0000000e+00 1.05e+04 2.84e+01 -5.4 7.78e+03 -5.9 9.22e-02 3.94e-18h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 144r 0.0000000e+00 1.05e+04 3.40e+01 -5.4 1.48e+03 -5.5 1.00e+00 2.08e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 145r 0.0000000e+00 2.67e+04 4.04e+01 -5.4 1.09e+04 -6.0 6.60e-02 1.02e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 146r 0.0000000e+00 2.67e+04 1.47e+03 -5.4 1.02e+03 - 2.88e-03 1.10e-04w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 147r 0.0000000e+00 4.33e+04 7.00e+02 -5.4 1.97e+04 -6.5 1.24e-01 8.93e-02w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 148r 0.0000000e+00 1.05e+04 5.40e+01 -5.4 6.24e+03 - 6.60e-02 2.82e-18h 55\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 149r 0.0000000e+00 1.05e+04 1.51e+02 -5.4 1.68e+04 -6.0 1.26e-01 1.83e-18h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 150r 0.0000000e+00 1.05e+04 5.58e+01 -5.4 2.10e+03 -5.6 1.51e-01 9.25e-19h 60\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 151r 0.0000000e+00 1.05e+04 6.31e+01 -5.4 3.28e+04 -6.1 1.66e-02 9.36e-19f 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 152r 0.0000000e+00 1.05e+04 6.32e+01 -5.4 3.63e+03 -5.7 8.61e-03 1.56e-18h 54\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 153r 0.0000000e+00 1.05e+04 6.33e+01 -5.4 2.10e+05 -6.1 1.98e-05 1.48e-19f 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 154r 0.0000000e+00 1.05e+04 8.87e-01 -5.4 1.46e-02 -0.3 1.00e+00 1.43e-06h 4\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 155r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 2.09e-02 -0.8 1.00e+00 5.00e-01f 2\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 156r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 6.26e-02 -1.2 1.00e+00 2.44e-04h 13\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 157r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 1.88e-01 -1.7 1.00e+00 1.53e-05h 17\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 158r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 5.64e-01 -2.2 1.00e+00 1.00e+00w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 159r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 1.69e+00 -2.7 1.00e+00 1.00e+00w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 160r 0.0000000e+00 1.06e+04 3.62e-03 -5.4 5.08e+00 -3.1 1.00e+00 1.00e+00w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 161r 0.0000000e+00 1.05e+04 8.60e-03 -5.4 1.53e+01 -3.6 1.00e+00 7.45e-09h 27\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 162r 0.0000000e+00 1.05e+04 6.99e-01 -5.4 4.61e+01 -4.1 1.00e+00 1.14e-13h 44\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 163r 0.0000000e+00 1.05e+04 2.14e+00 -5.4 1.41e+02 -4.6 1.00e+00 2.84e-14h 46\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 164r 0.0000000e+00 1.05e+04 6.79e+00 -5.4 4.48e+02 -5.1 1.00e+00 4.66e-10f 32\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 165r 0.0000000e+00 1.05e+04 2.13e+01 -5.4 1.64e+03 -5.5 8.03e-01 1.96e-11f 36\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 166r 0.0000000e+00 1.05e+04 5.45e+01 -5.4 1.44e+04 -6.0 1.69e-01 5.60e-13f 38\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 167r 0.0000000e+00 1.05e+04 2.91e+01 -5.4 1.92e+03 -5.6 1.00e+00 1.31e-13f 43\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 168r 0.0000000e+00 1.05e+04 3.94e+01 -5.4 2.52e+04 -6.1 2.91e-02 3.11e-16f 48\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 169r 0.0000000e+00 1.05e+04 3.44e+01 -5.4 2.27e+03 -5.6 1.00e+00 3.46e-15h 48\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 170r 0.0000000e+00 1.05e+04 4.50e+01 -5.4 7.69e+04 -6.1 9.32e-03 1.28e-17f 51\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 171r 0.0000000e+00 2.67e+04 3.33e+01 -5.4 2.71e+03 -5.7 1.00e+00 4.08e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 172r 0.0000000e+00 2.67e+04 9.73e+02 -5.4 1.12e+03 - 1.93e-03 9.14e-05w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 173r 0.0000000e+00 4.37e+04 5.94e+02 -5.4 7.46e+03 -6.2 2.29e-01 2.40e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 174r 0.0000000e+00 1.05e+04 4.51e+01 -5.4 3.87e+03 - 1.00e+00 2.97e-12f 37\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 175r 0.0000000e+00 1.05e+04 6.47e+01 -5.4 3.27e+03 -5.7 2.19e-01 7.69e-14f 43\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 176r 0.0000000e+00 1.05e+04 5.10e+01 -5.4 8.69e+02 -5.3 1.00e+00 1.14e-13h 44\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 177r 0.0000000e+00 1.05e+04 7.51e+01 -5.4 4.00e+03 -5.8 1.79e-01 6.43e-11f 33\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 178r 0.0000000e+00 1.05e+04 6.82e+01 -5.4 1.00e+03 -5.4 1.00e+00 4.66e-10f 32\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 179r 0.0000000e+00 1.05e+04 1.03e+02 -5.4 5.00e+03 -5.8 1.43e-01 1.29e-11f 35\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 180r 0.0000000e+00 1.05e+04 1.08e+02 -5.4 1.15e+03 -5.4 1.00e+00 1.39e-11f 37\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 181r 0.0000000e+00 1.05e+04 1.65e+02 -5.4 6.42e+03 -5.9 1.12e-01 5.01e-12f 36\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 182r 0.0000000e+00 1.05e+04 2.00e+02 -5.4 1.34e+03 -5.5 1.00e+00 1.20e-11f 37\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 183r 0.0000000e+00 1.05e+04 3.13e+02 -5.4 8.54e+03 -5.9 8.39e-02 9.41e-13f 38\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 184r 0.0000000e+00 2.67e+04 6.63e+01 -5.4 1.55e+03 -5.5 1.00e+00 7.13e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 185r 0.0000000e+00 2.67e+04 8.09e+02 -5.4 1.01e+03 - 2.25e-03 8.90e-04w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 186r 0.0000000e+00 4.40e+04 1.17e+02 -5.4 4.65e+03 -6.0 4.39e-01 3.92e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 187r 0.0000000e+00 1.05e+04 4.40e+02 -5.4 8.89e+03 - 1.00e+00 2.07e-11f 35\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 188r 0.0000000e+00 1.05e+04 5.51e+02 -5.4 1.81e+03 -5.6 3.96e-01 8.88e-12f 37\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 189r 0.0000000e+00 1.05e+04 8.25e+02 -5.4 1.87e+04 -6.0 3.12e-02 1.08e-13f 40\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 190r 0.0000000e+00 1.05e+04 3.35e+01 -5.4 2.20e+03 -5.6 4.67e-01 2.27e-13f 43\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 191r 0.0000000e+00 1.05e+04 4.40e+01 -5.4 4.69e+04 -6.1 1.56e-02 5.36e-15f 43\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 192r 0.0000000e+00 1.05e+04 3.87e+01 -5.4 2.56e+03 -5.7 1.00e+00 2.46e-14f 45\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 193r 0.0000000e+00 1.05e+04 1.92e+01 -5.4 7.26e+02 -5.2 9.88e-01 1.14e-13h 44\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 194r 0.0000000e+00 1.05e+04 4.68e+01 -5.4 3.07e+03 -5.7 7.96e-01 1.68e-10f 32\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 195r 0.0000000e+00 1.05e+04 3.54e+01 -5.4 8.31e+02 -5.3 1.00e+00 5.82e-11f 35\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 196r 0.0000000e+00 1.05e+04 8.07e+01 -5.4 3.74e+03 -5.8 5.32e-01 6.87e-11f 33\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 197r 0.0000000e+00 2.44e+04 4.51e+01 -5.4 9.55e+02 -5.3 1.00e+00 1.00e+00w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 198r 0.0000000e+00 2.90e+04 1.83e+02 -5.4 3.03e+03 -5.8 6.02e-01 1.26e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 199r 0.0000000e+00 2.90e+04 3.65e+02 -5.4 1.03e+03 - 1.58e-03 1.30e-03w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 200r 0.0000000e+00 1.05e+04 6.99e+01 -5.4 9.09e+03 -6.3 1.00e+00 2.91e-11f 35\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of Iterations....: 200\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: (scaled) (unscaled)\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Dual infeasibility......: 6.9908071367141474e+01 6.9908071367141474e+01\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Constraint violation....: 2.8645094423111342e-03 1.0458847092153306e+04\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Complementarity.........: 1.3579265591895737e-03 1.3579265591895737e-03\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Overall NLP error.......: 2.8645094423111342e-03 1.0458847092153306e+04\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of objective function evaluations = 5209\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of objective gradient evaluations = 6\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of equality constraint evaluations = 5210\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of inequality constraint evaluations = 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of equality constraint Jacobian evaluations = 203\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of inequality constraint Jacobian evaluations = 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of Lagrangian Hessian evaluations = 200\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Total CPU secs in IPOPT (w/o function evaluations) = 0.176\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Total CPU secs in NLP function evaluations = 0.014\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: EXIT: Maximum Number of Iterations Exceeded.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit: Initialization Step 3 maxIterations - .\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit: Initialization Complete: maxIterations - \n", "Initialization failed.\n" ] } ], "source": [ "import logging\n", - "import pytest\n", "from pyomo.environ import (\n", - " check_optimal_termination,\n", " ComponentMap,\n", " ConcreteModel,\n", " Constraint,\n", " exp,\n", " Param,\n", - " units,\n", + " Reference,\n", + " units as pyunits,\n", " value,\n", ")\n", - "from pyomo.util.check_units import assert_units_consistent, assert_units_equivalent\n", "\n", - "from idaes.core import FlowsheetBlock\n", - "from idaes.core.scaling.util import get_scaling_factor\n", - "from idaes.core.solvers import get_solver\n", - "from idaes.core.util.model_statistics import (\n", - " degrees_of_freedom,\n", - " number_variables,\n", - " number_total_constraints,\n", - " number_unused_variables,\n", + "from idaes.core import (\n", + " ControlVolume0DBlock,\n", + " FlowsheetBlock,\n", + " MaterialFlowBasis,\n", + " MomentumBalanceType,\n", ")\n", - "from idaes.core.util.testing import initialization_tester\n", - "from idaes.core.util import scaling as iscale\n", - "from idaes.core.util.exceptions import InitializationError\n", + "import idaes.logger as idaeslog\n", + "from idaes.core.scaling.util import get_scaling_factor\n", + "from idaes.core.util.exceptions import ConfigurationError, InitializationError\n", "\n", "from idaes.models.properties.modular_properties.base.generic_property import (\n", " GenericParameterBlock,\n", @@ -117,7 +592,8 @@ ")\n", "from idaes.models_extra.column_models.properties.MEA_vapor import flue_gas\n", "\n", - "logging.getLogger('pyomo.repn.plugins.nl_writer').setLevel(logging.ERROR)\n", + "logging.getLogger(\"pyomo.repn.plugins.nl_writer\").setLevel(logging.ERROR)\n", + "\n", "\n", "def create_model():\n", " m = ConcreteModel()\n", @@ -138,18 +614,16 @@ " m.fs.unit.inlet.mole_frac_comp[0, \"H2O\"].fix(0.8589)\n", " m.fs.unit.inlet.mole_frac_comp[0, \"MEA\"].fix(0.1085)\n", "\n", - " # m.fs.unit.vapor_reboil.flow_mol[0].fix(9.56)\n", " m.fs.unit.heat_duty.fix(430.61e3)\n", " return m\n", "\n", + "\n", "if __name__ == \"__main__\":\n", " m = create_model()\n", "\n", - " reboiler_init = m.fs.unit.default_initializer(\n", - " always_estimate_states=True,\n", - " )\n", + " reboiler_init = m.fs.unit.default_initializer(always_estimate_states=True)\n", " try:\n", - " reboiler_init.initialize(m.fs.unit)\n", + " reboiler_init.initialize(m.fs.unit, output_level=idaeslog.DEBUG)\n", " except InitializationError:\n", " print(\"Initialization failed.\")" ] @@ -192,7 +666,7 @@ "------------------------------------------------------------------------------------\n", "1 WARNINGS\n", "\n", - " WARNING: Found 17 potential evaluation errors.\n", + " WARNING: Found 9 potential evaluation errors.\n", "\n", "------------------------------------------------------------------------------------\n", "2 Cautions\n", @@ -211,6 +685,7 @@ ], "source": [ "from idaes.core.util import DiagnosticsToolbox\n", + "\n", "dt = DiagnosticsToolbox(m)\n", "dt.report_structural_issues()" ] @@ -220,9 +695,9 @@ "id": "c08b1da8-20da-4291-b555-7d78cf565f67", "metadata": {}, "source": [ - "The density relationship is being flagged for potential evaluation errors. The interval arithmatic used to identify potential evaluation errors can produce relatively loose bounds, especially for the sort of large polynomial expressions favored in the literature. Independent testing of the density relationship over a wide range of values has demonstrated that no evaluation errors occur, so we can ignore these warnings.\n", + "The density relationship is being flagged for potential evaluation errors. The interval arithmetic used to identify potential evaluation errors can produce relatively loose bounds, especially for the sort of large polynomial expressions favored in the literature. Independent testing of the density relationship over a wide range of values has demonstrated that no evaluation errors occur, so we can ignore these warnings.\n", "\n", - "The next step is determining which numerical issues exist:" + "The next step is determining which numerical issues exist." ] }, { @@ -275,21 +750,131 @@ "dt.report_numerical_issues()" ] }, + { + "cell_type": "code", + "execution_count": 5, + "id": "51b9a50d", + "metadata": { + "tags": [ + "testing" + ] + }, + "outputs": [], + "source": [ + "import pytest\n", + "from idaes.core.scaling.util import jacobian_cond\n", + "\n", + "dt.assert_no_structural_warnings(ignore_evaluation_errors=True)\n", + "assert jacobian_cond(m.fs.unit) == pytest.approx(2.718e13, rel=1e-2)" + ] + }, { "cell_type": "markdown", "id": "b247949c-c8cf-48b7-9266-033db87a908a", "metadata": {}, "source": [ - "We see that there are some constraints with large residuals, which is what we expect since the model did not initialize successfully. We also see that the system has a condition number of $2.718\\cdot 10^{13}$, there is one variable associated with a Jacobian column with an extreme norm, and one constraint associated with a Jacobian row with an extreme norm.\n", + "In order to help interpret this output, we need to review the solution of systems of nonlinear equations.\n", "\n", - "A condition number on the order of $10^{13}$ is significantly higher than we'd like. Ideally, we want unit models to have condition numbers less than $10^4$ and flowsheets with condition numbers less than $10^8$.\n", + "When we try to solve a square problem (i.e., a problem with zero degrees of freedom) using IPOPT, we are asking it to solve an equation of the form\n", + "$$\n", + "\\mathbf{f}(\\mathbf{x}) = \\mathbf{0}\n", + "$$\n", + "in which $\\mathbf{f}(\\cdot)$ is a vector-valued function of length $n$, and $\\mathbf{x}$ is a vector also of length $n$. Due to the finite accuracy of floating point arithmetic, the most we can ask for is $||\\mathbf{f}(\\mathbf{x})|| < \\varepsilon$, for some small value of $\\varepsilon$. The IDAES default solver configuration sets $\\varepsilon = 10^{-6}$. For some constraint $j$, the value of $f_j(x_k)$ is the called its *residual*, i.e., the remaining error in constraint satisfaction. IPOPT displays the infinity norm of the constraint residual,\n", + "$$\n", + "\\lvert\\lvert \\mathbf{f}(\\mathbf{x}_k)\\rvert\\rvert_{\\infty} := \\max_j \\lvert f_j(\\mathbf{x}_k)\\rvert\n", + "$$\n", + "i.e., the constraint residual with largest magnitude, for each step $k$ in the primal infeasibility (`inf_pr`) column.\n", + "\n", + "Problems of this form are typically solved with some variation on Newton's method. We denote the Jacobian matrix for function $\\mathbf{f}(\\mathbf{x})$ as\n", + "$$\n", + "\\mathbf{J}(\\mathbf{x}) := \\begin{bmatrix}\n", + " \\frac{\\partial f_1}{\\partial x_1} & \\dots & \\frac{\\partial f_1}{\\partial x_n} \\\\\n", + " \\vdots & \\ddots & \\vdots \\\\\n", + " \\frac{\\partial f_n}{\\partial x_1} & \\dots & \\frac{\\partial f_n}{\\partial x_n}\n", + "\\end{bmatrix}\n", + "$$\n", + "Note that each row of $\\mathbf{J}(\\cdot)$ is associated with a constraint and every column is associated with a variable.\n", + "\n", + "In the classical form of Newton's method, we start with an initial guess $\\mathbf{x}_0$, then iterate using the relationship\n", + "\n", + "\\begin{align}\n", + "\\mathbf{J}(\\mathbf{x}_k)\\cdot\\mathbf{\\delta x}_k &= -\\mathbf{f}(\\mathbf{x}_k) \\\\\n", + "\\mathbf{x}_{k+1} &= \\mathbf{x}_k + \\mathbf{\\delta x}_k\n", + "\\end{align}\n", + "\n", + "IPOPT incorporates additional features, such as a line search, in order to enhance its robustness to bad initial guesses, but it is designed to take full Newton steps in the neighborhood of a solution (for the full details, refer to [Wächter and Biegler (2006)](#references)).\n", + "\n", + "The condition number $\\kappa_2(\\cdot)$ (for the Euclidean norm) is a worst-case error bound in the solution of a system of linear equations. In this case, we have\n", + "$$\n", + "\\lvert\\lvert\\mathbf{\\delta x}_k\\rvert\\rvert_2 \\leq \\kappa(\\mathbf{J}(\\mathbf{x}_k)) \\cdot \\lvert\\lvert \\mathbf{f}(\\mathbf{x}_k)\\rvert\\rvert_2\n", + "$$\n", + "If we terminate under the condition $||\\mathbf{f}(\\mathbf{x}_f)||_2 < \\varepsilon$, then\n", + "$$\n", + "\\lvert\\lvert\\mathbf{\\delta x}_f\\rvert\\rvert_2 \\leq \\kappa(\\mathbf{J}(\\mathbf{x}_f)) \\cdot \\varepsilon\n", + "$$\n", + "With a condition number on the order of $10^{13}$ and the default tolerance $\\varepsilon = 10^{-6}$, then the difference between the computed solution $x_f$ and the true solution $x$ could be on the order of $10^7$.\n", "\n", - "Before beginning to write a scaler, however, we should look at the structure of the unit model." + "In practice, however, we frequently end up with much better results than those predicted by this worst-case bound. Frequently, we find that most constraints have residuals on the order of $10^{-10}$ or less, with a few problematic constraints having larger residuals. That is the case here." ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, + "id": "3a75813b-2b5e-44d9-9676-1f26871ecf37", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Number of constraints: 77\n", + "====================================================================================\n", + "The following constraint(s) have large residuals (>1.0E-10):\n", + "\n", + " fs.unit.unit_material_balance[0.0,CO2]: 1.84866E-10\n", + " fs.unit.unit_material_balance[0.0,N2]: 1.89950E-10\n", + " fs.unit.unit_material_balance[0.0,O2]: 1.87656E-10\n", + " fs.unit.unit_phase_equilibrium[0.0,CO2]: 1.04588E+04\n", + " fs.unit.unit_phase_equilibrium[0.0,H2O]: 8.88278E-07\n", + " fs.unit.unit_enthalpy_balance[0.0]: 5.05679E-10\n", + " fs.unit.liquid_phase.material_balances[0.0,CO2]: 1.70459E-10\n", + " fs.unit.liquid_phase.enthalpy_balances[0.0]: 1.17285E-05\n", + " fs.unit.liquid_phase.properties_out[0.0].sum_mole_frac_out: 2.08134E-10\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-]: 8.83857E-06\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]: 1.54414E-07\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA_+]: 7.69821E-06\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,H2O]: 2.50511E-08\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA]: 4.55346E-06\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2]: 4.42749E-05\n", + " fs.unit.vapor_phase[0.0].sum_mole_frac_out: 1.71144E-10\n", + "\n", + "====================================================================================\n" + ] + } + ], + "source": [ + "import idaes.core.util.model_statistics as mstat\n", + "\n", + "print(f\"Number of constraints: {mstat.number_activated_constraints(m)}\")\n", + "dt.config.constraint_residual_tolerance = 1e-10\n", + "dt.display_constraints_with_large_residuals()" + ] + }, + { + "cell_type": "markdown", + "id": "e31bcd98-a4f8-46fe-a32d-7e2f83356eb3", + "metadata": {}, + "source": [ + "Even with a non-optimal termination, we have only three constraints with residuals greater than $10^{-5}$ for a model with 77 active constraints. Two of those constraints are on the order of $10^{-5}$, but the third is on the order of $10^4$.\n", + "\n", + "Nevertheless, a condition number on the order of $10^{13}$ is significantly higher than we'd like, because large condition numbers can degrade the convergence of Newton's method or even prevent it from converging entirely. Ideally, we want flowsheets to have condition numbers less than $10^8$. Connecting unit models together with things like recycle streams can amplify the overall flowsheet condition number to be multiple orders of magnitude greater than that of its individual components. Consequently, we want unit models to have condition numbers less than $10^4$.\n", + "\n", + "Model scaling can both reduce the Jacobian's condition number and help ensure that constraints are satisfied to an appropriate precision. Both of those effects can help the model initialization to converge. Before beginning to write a scaler object, however, we should look at the structure of the unit model." + ] + }, + { + "cell_type": "code", + "execution_count": 7, "id": "1da2f90e-e562-4f2a-b066-c635c88b0d78", "metadata": {}, "outputs": [], @@ -384,9 +969,7 @@ " # ---------------------------------------------------------------------\n", " # Add Ports for the reboiler\n", " self.add_inlet_port(name=\"inlet\", block=self.liquid_phase, doc=\"Liquid feed\")\n", - " self.add_outlet_port(\n", - " name=\"bottoms\", block=self.liquid_phase, doc=\"Bottoms stream\"\n", - " )\n", + " self.add_outlet_port(name=\"bottoms\", block=self.liquid_phase, doc=\"Bottoms stream\")\n", " self.add_outlet_port(\n", " name=\"vapor_reboil\",\n", " block=self.vapor_phase,\n", @@ -430,9 +1013,7 @@ " if j in common_comps:\n", " # Component is in equilibrium\n", " # Mass transfer equals vapor flowrate\n", - " return -blk.liquid_phase.mass_transfer_term[\n", - " t, \"Liq\", j\n", - " ] == pyunits.convert(\n", + " return -blk.liquid_phase.mass_transfer_term[t, \"Liq\", j] == pyunits.convert(\n", " blk.vapor_phase[t].get_material_flow_terms(\"Vap\", j),\n", " to_units=lunits(fb),\n", " )\n", @@ -447,9 +1028,7 @@ " else:\n", " # Non-vaporisable component\n", " # Mass transfer term is zero, no vapor flowrate\n", - " return blk.liquid_phase.mass_transfer_term[t, \"Liq\", j] == 0 * lunits(\n", - " fb\n", - " )\n", + " return blk.liquid_phase.mass_transfer_term[t, \"Liq\", j] == 0 * lunits(fb)\n", "\n", " self.unit_material_balance = Constraint(\n", " self.flowsheet().time,\n", @@ -539,7 +1118,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 8, "id": "6910d881-8875-4529-bd30-5807aa15f400", "metadata": {}, "outputs": [], @@ -575,12 +1154,6 @@ "\n", "The second and fourth steps are intended to allow users to provide methods to fill in missing scaling information that was not provided by the first and second steps. However, these methods are prone to perform poorly on all but the simplest models (see Step 5 for more information).\n", "\n", - "Both the ``variable_scaling_routine`` and ``constraint_scaling_routine`` are user-facing methods and take three arguments.\n", - "\n", - "1. The model to be scaled.\n", - "2. An argument indicating whether to overwrite any existing scaling factors. Generally we assume that any existing scaling factors were provided by the user for a reason, so by default we set this to ``False``. However, there will likely be cases where a user wants to overwrite their existing scaling factors so this argument exists to let us pass on those instructions.\n", - "3. A mapping of user-provided ``Scalers`` to use when scaling submodels.\n", - "\n", "## Step 4: Apply Scaling to Sub-Models\n", "\n", "First, let's look at how to scale the control volume and state block sub-models. Because the property package for the ``vapor_phase`` state block is specified by the user, we do not know what variables and constraints it may contain, so we cannot (and should not) scale it directly. The property package creator (hopefully) created a scaler object that we can use. The zero-dimensional control volume ``liquid_phase`` contains two state blocks, material, energy, and pressure balance constraints, and variables corresponding to additional interaction terms. Because we are choosing which terms to create in the control volume, we could, in principle, scale it at the unit model level. However, because control volumes typically should be scaled in the same way, a submodel scaler has been provided for it as well. Thus, what we want to do here is to call the variable and constraint scaling routines from the ``Scaler`` associated with each sub-model, which we can do using the ``call_submodel_scaler_method`` method." @@ -588,7 +1161,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 9, "id": "6a2d1c70-1608-4df6-9865-68c00193dcbe", "metadata": {}, "outputs": [], @@ -643,7 +1216,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 10, "id": "7ae92ba0-17d3-4aa5-ba21-d5cead039f47", "metadata": {}, "outputs": [], @@ -662,7 +1235,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 11, "id": "8de34555-cf86-43a1-bf56-e12ef9e7b55b", "metadata": {}, "outputs": [ @@ -678,10 +1251,11 @@ " 'therm_cond_phase': ,\n", " 'mole_frac_phase_comp_true': 10,\n", " 'mole_frac_phase_comp_apparent': 10,\n", - " 'dens_mol_phase': }" + " 'dens_mol_phase': ,\n", + " 'vol_mol_phase': }" ] }, - "execution_count": 9, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -695,21 +1269,18 @@ "id": "5194862f-71ee-4473-b68f-14b428d5138e", "metadata": {}, "source": [ - "We can see that we are required to set a default scaling factor for ``flow_mol_phase``. Furthermore, it is recommended to set a default scaling factor for ``enth_mol_phase``, ``visc_d_phase``, and ``therm_cond_phase``. For these latter quantities, there is a method to estimate reasonable scaling factors, but it might not be suitible for all cases.\n", + "We can see that we are required to set a default scaling factor for ``flow_mol_phase``. Furthermore, it is recommended to set a default scaling factor for ``enth_mol_phase``, ``visc_d_phase``, ``therm_cond_phase``, `dens_mol_phase`, and`vol_mol_phase`. For these latter quantities, there is a method to estimate reasonable scaling factors, but it might not be suitible for all cases.\n", "\n", - "With an inlet flow of about 80 mol/s, a scaling factor of 1/80 is appropriate. We can ignore ``visc_d_phase`` and ``therm_cond_phase``, because the solvent reboiler model does not require dynamic viscosity or thermal conductivity (at present). Molar enthalpy is a tougher quantity to scale.\n", + "With an inlet flow of about 80 mol/s, a scaling factor of 1/80 is appropriate. We can ignore ``visc_d_phase`` and ``therm_cond_phase``, because this unit model does not require dynamic viscosity or thermal conductivity. Molar enthalpy is a tougher quantity to scale.\n", "\n", - "By convention, the molar enthalpy of each element in its pure form at 25$^\\circ$ C and 1 atm is set equal to zero. In some property packages, enthalpy of formation is taken into account for compounds, while in some property packages it is not. However, the scaling factor for enthalpy should not depend on this convention---only enthalpy *differences* are meaningful. So we need to determine how to determine what constitutes a \"significant\" enthalpy difference for this property package. The way the modular property scaler object estimates this is through the temperature scaling factor, which determines what a \"significant\" temperature difference is, and the observation that a wide range of substances have a specific heat capacity around 2 $\\frac{\\text{J}}{\\text{g K}}$.\n", - "\n", - "TODO This digression can probably be cut.\n", - "~~Liquid water has a heat capacity of 4.18 $\\frac{\\text{J}}{\\text{g K}}$, steam has a heat capacity of 2.03 $\\frac{\\text{J}}{\\text{g K}}$, liquid enthanol has a heat capacity of 2.44, and air has a heat capacity of 1.01 $\\frac{\\text{J}}{\\text{g K}}$ at room temperature. The major outliers are metals and hydrogen gas. Metals tend to have heat capacities less than 1 $\\frac{\\text{J}}{\\text{g K}}$, with iron having 0.449 $\\frac{\\text{J}}{\\text{g K}}$ and gold having 0.129 $\\frac{\\text{J}}{\\text{g K}}$. Hydrogen, by contrast, has a heat capacity of 14.41 $\\frac{\\text{J}}{\\text{g K}}$; the heat capacity of a diatomic gas is about $\\frac{5}{2}R$, in which $R$ is the gas consant, so hydrogen's low molecular weight results in it having a large mass-based heat capacity.~~\n", + "By convention, the molar enthalpy of each element in its pure form at $25^\\circ\\text{C}$ and $1\\:\\text{atm}$ is set equal to zero. In some property packages, enthalpy of formation is taken into account for compounds, while in some property packages it is not. However, the scaling factor for enthalpy should not depend on this convention---only enthalpy *differences* are meaningful. So we need to determine how to determine what constitutes a \"significant\" enthalpy difference for this property package. The way the modular property scaler object estimates this is through the temperature scaling factor, which determines what a \"significant\" temperature difference is, and the observation that a wide range of substances have a specific heat capacity around $2\\:\\frac{\\text{J}}{\\text{g K}}$.\n", "\n", "This default method is good enough for our purposes now. We can revisit it later, if necessary." ] }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 12, "id": "322ea374-6077-49b5-aa2f-d866ad9a3204", "metadata": {}, "outputs": [], @@ -731,20 +1302,9 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 13, "id": "f82e7b2c-8c98-4685-bf25-9f2dea6db0f1", "metadata": {}, - "outputs": [], - "source": [ - "reboiler_scaler = SolventReboilerScaler()\n", - "reboiler_scaler.scale_model(m.fs.unit)" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "9d10891e-082a-4a0d-82da-536b8eeb9e86", - "metadata": {}, "outputs": [ { "name": "stdout", @@ -770,7 +1330,7 @@ " Caution: 1 Constraint with potential cancellation of terms\n", " Caution: 10 Variables with extreme Jacobian column norms (<1.0E-04 or >1.0E+04)\n", " Caution: 4 Constraints with extreme Jacobian row norms (<1.0E-04 or >1.0E+04)\n", - " Caution: 28 extreme Jacobian Entries (<1.0E-04 or >1.0E+04)\n", + " Caution: 33 extreme Jacobian Entries (<1.0E-04 or >1.0E+04)\n", "\n", "------------------------------------------------------------------------------------\n", "Suggested next steps:\n", @@ -783,21 +1343,57 @@ } ], "source": [ + "reboiler_scaler = SolventReboilerScaler()\n", + "reboiler_scaler.scale_model(m.fs.unit)\n", "dt = DiagnosticsToolbox(m)\n", "dt.report_numerical_issues()" ] }, + { + "cell_type": "code", + "execution_count": 14, + "id": "a8ba1d58", + "metadata": { + "tags": [ + "testing" + ] + }, + "outputs": [], + "source": [ + "assert jacobian_cond(m.fs.unit) == pytest.approx(7.165e10, rel=1e-2)" + ] + }, { "cell_type": "markdown", "id": "5a146719-cac0-466f-87e4-00bbd9adffa3", "metadata": {}, "source": [ - "We see in this case that partly scaling the model improved the condition number of the Jacobian by only two and a half orders of magnitude. This sort of marginal improvement is common for partial scaling, and sometimes partial scaling makes the model's condition number *worse*. When variables are scaled without the constraints they appear in also being scaled, it generates new extreme Jacobian entries. If we look at the number of extreme Jacobian rows and columns, however, we see the progress we've made. Before applying submodel scaling, we had 27 variables with extreme column norms and 16 constraints with extreme row norms. Now we have only 10 variables and 4 constraints. Let's see which constraints are problematic." + "We see in this case that partly scaling the model improved the condition number of the Jacobian by only two and a half orders of magnitude. This sort of marginal improvement is common for partial scaling, and sometimes partial scaling makes the model's condition number *worse*. When variables are scaled without the constraints they appear in also being scaled, it generates new extreme Jacobian entries. If we look at the number of extreme Jacobian rows and columns, however, we see the progress we've made. Before applying submodel scaling, we had 27 variables with extreme column norms and 16 constraints with extreme row norms. Now we have only 10 variables and 4 constraints.\n", + "\n", + "We are concerned with Jacobian rows and columns with extreme values because they allow us to estimate the Jacobian condition number. Determining the (Euclidean) condition number requires the computation of the *singular value decomposition* (SVD) of $\\mathbf{J}(\\mathbf{x})$. However, that process is computationally expensive for large models, and it does not identify individual variables and constraints as problematic (instead, it identifies *combinations* of variables and constraints as problematic). However, we have a lower bound to the condition number in terms of the norms of rows and columns of the Jacobian matrix:\n", + "$$\n", + "\\max\\left(\\frac{||\\mathbf{r}_\\text{max}||_2}{||\\mathbf{r}_\\text{min}||_2}, \\frac{||\\mathbf{c}_\\text{max}||_2}{||\\mathbf{c}_\\text{min}||_2}\\right) \\leq \\kappa(\\mathbf{J}(\\mathbf{x}))\n", + "$$\n", + "Consequently, Jacobian rows or columns with extremely large or extremely small norms indicate that the Jacobian is ill-conditioned. Each row is associated with a constraint and each column is associated with a variable. So the extreme Jacobian rows and columns give us a list of variables and constraints to investigate for scaling.\n", + "\n", + "
\n", + "Just because a variable or constraint has a Jacobian column or row with an extreme norm does not mean it is badly-scaled. Frequently, either a constraint containing the variable or a variable present in a constraint is the actual problem. \n", + "
\n", + "\n", + "
\n", + "NOTE\n", + "\n", + "Jacobian rows and columns with extreme norms reveal that the Jacobian matrix is ill-conditioned, but the converse is not true. A Jacobian matrix can have no rows and columns with extreme norms but still be singular or ill-conditioned.\n", + "\n", + "
\n", + "\n", + "\n", + "Let's see which variables and constraints are problematic." ] }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 15, "id": "0737f98e-73c5-4fac-9215-aee2efd1942d", "metadata": {}, "outputs": [ @@ -851,7 +1447,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 16, "id": "6e025e22-4b18-41cf-b761-942ec50964e1", "metadata": {}, "outputs": [ @@ -859,12 +1455,13 @@ "name": "stdout", "output_type": "stream", "text": [ - "- fs.unit.liquid_phase.enthalpy_transfer[0.0] == (kg*m**2/J/s**2)*fs.unit.vapor_phase[0.0]._enthalpy_flow_term[Vap]" + "- fs.unit.liquid_phase.enthalpy_transfer[0.0] == (kg*m**2/J/s**2)*fs.unit.vapor_phase[0.0]._enthalpy_flow_term[Vap]\n" ] } ], "source": [ "from idaes.core.util.misc import print_compact_form\n", + "\n", "print_compact_form(m.fs.unit.unit_enthalpy_balance[0.0])" ] }, @@ -881,7 +1478,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 17, "id": "54986702-39c2-40ac-b144-8a757ac324fb", "metadata": {}, "outputs": [ @@ -891,7 +1488,7 @@ "5.076760620583219e-07" ] }, - "execution_count": 15, + "execution_count": 17, "metadata": {}, "output_type": "execute_result" } @@ -912,19 +1509,16 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 18, "id": "ed2cad19-6b46-4a97-9fc5-4332c0dea65c", "metadata": {}, "outputs": [ { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" + "name": "stdout", + "output_type": "stream", + "text": [ + "None\n" + ] } ], "source": [ @@ -941,7 +1535,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 19, "id": "cebca2c2-a949-4120-b31a-453d28eee1ae", "metadata": {}, "outputs": [ @@ -949,7 +1543,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "fs.unit.vapor_phase[0.0].flow_mol_phase[Vap]*fs.unit.vapor_phase[0.0].enth_mol_phase[Vap]" + "fs.unit.vapor_phase[0.0].flow_mol_phase[Vap]*fs.unit.vapor_phase[0.0].enth_mol_phase[Vap]\n" ] } ], @@ -967,7 +1561,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 20, "id": "c997f5f5-9b09-48cf-a15e-3cd0cc43c52b", "metadata": {}, "outputs": [ @@ -977,7 +1571,7 @@ "0.1" ] }, - "execution_count": 18, + "execution_count": 20, "metadata": {}, "output_type": "execute_result" } @@ -996,7 +1590,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 21, "id": "759e6aab-ddc5-435f-9699-d9dcdf82dc52", "metadata": {}, "outputs": [ @@ -1006,7 +1600,7 @@ "5.46268982847154e-05" ] }, - "execution_count": 19, + "execution_count": 21, "metadata": {}, "output_type": "execute_result" } @@ -1025,7 +1619,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 22, "id": "c12629aa-ea76-43fd-8a87-dff2b7d2ac75", "metadata": {}, "outputs": [ @@ -1035,7 +1629,7 @@ "0.0125" ] }, - "execution_count": 20, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" } @@ -1067,6 +1661,7 @@ " - Subtraction (or addition of negative numbers to positive numbers)\n", " - Functions with a variable exponent\n", " - Trigometric functions\n", + " - Logarithms\n", "\n", "For these operations, an expression's final value is highly dependent on the exact values of its included variables. For example, suppose $\\sigma(e) = \\sigma(f)$. In that case, the term $d\\cdot (e - f)$ would have an estimated magnitude of $0$, which is useless for scaling purposes. It is in cases like this that scaling hints for named expressions. If we denote $G = e - f$ and assign $\\sigma(G) = \\sigma(e)$, we have a far better estimate of the term $d\\cdot (e - f)$ in the quantity $1/(\\sigma(d)\\cdot\\sigma(G))$.\n", "\n", @@ -1082,7 +1677,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 23, "id": "899cf853-c7a5-40b9-add6-21de075f15f2", "metadata": {}, "outputs": [ @@ -1092,7 +1687,7 @@ "[1969759.9999999995, 183060.0]" ] }, - "execution_count": 21, + "execution_count": 23, "metadata": {}, "output_type": "execute_result" } @@ -1106,14 +1701,16 @@ "id": "ef79b2c7-3187-41c1-aa33-bce79bceb11a", "metadata": {}, "source": [ - "The inverse of either of these numbers would be reasonable scaling factors. The `scale_constraint_by_nominal value` function automatically scales a constraint by using one of these numbers. Which number we use is selected using the `ConstraintScalingScheme` `Enum` If we take the inverse of the larger number, we are saying that the constraint needs to be satisfied with the same precision as the largest term in the sum. This corresponds to `ConstraintScalingScheme.inverseMaximum`. If we take the inverse of the smaller number, we are saying that the constraint needs to be satisfied with the same precision as the smallest term in the sum. This corresponds to `ConstraintScalingScheme.inverseMinimum`. In this case, they differ only by a factor of 10, so there isn't that large of a difference. Let's use the `inverseMinimum` method for this constraint in order to more precisely determine the vapor phase's temperature.\n", + "The inverse of either of these numbers would be reasonable scaling factors. The `scale_constraint_by_nominal value` function automatically scales a constraint by using one of these numbers. Which number we use is selected using the `ConstraintScalingScheme` `Enum` If we take the inverse of the larger number, we are saying that the constraint needs to be satisfied with the same precision as the largest term in the sum. This corresponds to `ConstraintScalingScheme.inverseMaximum`. If we take the inverse of the smaller number, we are saying that the constraint needs to be satisfied with the same precision as the smallest term in the sum. This corresponds to `ConstraintScalingScheme.inverseMinimum`.\n", + "\n", + "In general, the `inverseMinimum` scheme is the safest to use, because it demands the most precision. Let's use the `inverseMinimum` method for this constraint in order to more precisely determine the vapor phase's temperature.\n", "\n", "The next two constraints can be dealt with together:" ] }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 24, "id": "5165dd5a-f440-466a-b1e2-5e5f43846746", "metadata": {}, "outputs": [ @@ -1123,13 +1720,15 @@ "text": [ "fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[Liq,CO2] == fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,CO2]\n", "\n", - "fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[Liq,H2O] == fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,H2O]" + "\n", + "fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[Liq,H2O] == fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,H2O]\n" ] } ], "source": [ - "print_compact_form(m.fs.unit.unit_phase_equilibrium[0.0,\"CO2\"]);print(\"\\n\")\n", - "print_compact_form(m.fs.unit.unit_phase_equilibrium[0.0,\"H2O\"])" + "print_compact_form(m.fs.unit.unit_phase_equilibrium[0.0, \"CO2\"])\n", + "print(\"\\n\")\n", + "print_compact_form(m.fs.unit.unit_phase_equilibrium[0.0, \"H2O\"])" ] }, { @@ -1142,7 +1741,33 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 25, + "id": "222d92b4", + "metadata": { + "tags": [ + "testing" + ] + }, + "outputs": [], + "source": [ + "CO2_nom = reboiler_scaler.get_sum_terms_nominal_values(\n", + " m.fs.unit.unit_phase_equilibrium[0.0, \"CO2\"]\n", + ")\n", + "CO2_nom.sort()\n", + "assert CO2_nom[0] == pytest.approx(1e4, rel=1e-2)\n", + "assert CO2_nom[1] == pytest.approx(7623000, rel=1e-2)\n", + "\n", + "H2O_nom = reboiler_scaler.get_sum_terms_nominal_values(\n", + " m.fs.unit.unit_phase_equilibrium[0.0, \"H2O\"]\n", + ")\n", + "H2O_nom.sort()\n", + "assert H2O_nom[0] == pytest.approx(355.4, rel=1e-2)\n", + "assert H2O_nom[1] == pytest.approx(1e4, rel=1e-2)" + ] + }, + { + "cell_type": "code", + "execution_count": 26, "id": "790b9691-0734-4974-9f32-0d5d4070e5c5", "metadata": {}, "outputs": [ @@ -1156,8 +1781,16 @@ } ], "source": [ - "print(reboiler_scaler.get_sum_terms_nominal_values(m.fs.unit.unit_phase_equilibrium[0.0,\"CO2\"]))\n", - "print(reboiler_scaler.get_sum_terms_nominal_values(m.fs.unit.unit_phase_equilibrium[0.0,\"H2O\"]))" + "print(\n", + " reboiler_scaler.get_sum_terms_nominal_values(\n", + " m.fs.unit.unit_phase_equilibrium[0.0, \"CO2\"]\n", + " )\n", + ")\n", + "print(\n", + " reboiler_scaler.get_sum_terms_nominal_values(\n", + " m.fs.unit.unit_phase_equilibrium[0.0, \"H2O\"]\n", + " )\n", + ")" ] }, { @@ -1165,12 +1798,12 @@ "id": "e601fb2f-6208-4c53-bd74-13bbe97b682b", "metadata": {}, "source": [ - "Here, we see that, while the vapor phase fugacities are associated with a nominal value of 10000, the liquid phase fugacities have wildly different nominal values. We do expect the vapor phase to be enriched in $\\text{CO}_2$, but not by a factor of $2\\cdot 10^4$. So let's unpack these values. We are using the ideal gas law for the vapor phase, so the fugacity is simply the product of the mole fraction and vapor pressure:" + "Here, we see that, while the vapor phase fugacities are associated with a nominal value of 10000, the liquid phase fugacities have wildly different nominal values. We do expect the vapor phase to be enriched in $\\text{CO}_2$, but not by a factor of $2\\cdot 10^4$. Let's unpack these values. We are using the ideal gas law for the vapor phase, so the fugacity is simply the product of the mole fraction and vapor pressure:" ] }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 27, "id": "5bdb2701-c04a-4e1b-b9d2-86a673a944a9", "metadata": {}, "outputs": [ @@ -1178,12 +1811,12 @@ "name": "stdout", "output_type": "stream", "text": [ - "fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]*fs.unit.vapor_phase[0.0].pressure" + "fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]*fs.unit.vapor_phase[0.0].pressure\n" ] } ], "source": [ - "print_compact_form(m.fs.unit.vapor_phase[0.0].fug_phase_comp[\"Vap\",\"CO2\"])" + "print_compact_form(m.fs.unit.vapor_phase[0.0].fug_phase_comp[\"Vap\", \"CO2\"])" ] }, { @@ -1196,7 +1829,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 28, "id": "7a316b13-1891-47fa-bb1a-fa52365f8e57", "metadata": {}, "outputs": [ @@ -1204,12 +1837,14 @@ "name": "stdout", "output_type": "stream", "text": [ - "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,CO2]*(exp(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O])*log(244800.0*exp(-1348*K/fs.unit.liquid_phase.properties_out[0.0].temperature)*(3520000.0*exp(-2113*K/fs.unit.liquid_phase.properties_out[0.0].temperature)/(8449000.0*exp(-2283*K/fs.unit.liquid_phase.properties_out[0.0].temperature)))) + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O])*log(3520000.0*exp(-2113*K/fs.unit.liquid_phase.properties_out[0.0].temperature)) + fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O])*(fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]))*(fs.liquid_properties.CO2.lwm_coeff_1 + K**(-1)*fs.liquid_properties.CO2.lwm_coeff_2*(fs.unit.liquid_phase.properties_out[0.0].temperature - 273.15*K) + K**(-2)*fs.liquid_properties.CO2.lwm_coeff_3*(fs.unit.liquid_phase.properties_out[0.0].temperature - 273.15*K)**2 + fs.liquid_properties.CO2.lwm_coeff_4*(fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]))))*Pa*m**3*mol**(-1))" + "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,CO2]*(exp(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O])*log(244800.0*exp(-1348*K/fs.unit.liquid_phase.properties_out[0.0].temperature)*(3520000.0*exp(-2113*K/fs.unit.liquid_phase.properties_out[0.0].temperature)/(8449000.0*exp(-2283*K/fs.unit.liquid_phase.properties_out[0.0].temperature)))) + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O])*log(3520000.0*exp(-2113*K/fs.unit.liquid_phase.properties_out[0.0].temperature)) + fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O])*(fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]))*(fs.liquid_properties.CO2.lwm_coeff_1 + K**(-1)*fs.liquid_properties.CO2.lwm_coeff_2*(fs.unit.liquid_phase.properties_out[0.0].temperature - 273.15*K) + K**(-2)*fs.liquid_properties.CO2.lwm_coeff_3*(fs.unit.liquid_phase.properties_out[0.0].temperature - 273.15*K)**2 + fs.liquid_properties.CO2.lwm_coeff_4*(fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]))))*Pa*m**3*mol**(-1))\n" ] } ], "source": [ - "print_compact_form(m.fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[\"Liq\",\"CO2\"])" + "print_compact_form(\n", + " m.fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[\"Liq\", \"CO2\"]\n", + ")" ] }, { @@ -1222,7 +1857,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 29, "id": "7ebe7e0c-1dc5-49cc-a712-d507f2510f28", "metadata": {}, "outputs": [ @@ -1232,13 +1867,15 @@ "10000.0" ] }, - "execution_count": 26, + "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "reboiler_scaler.get_expression_nominal_value(m.fs.unit.vapor_phase[0.0].fug_phase_comp[\"Vap\",\"CO2\"])" + "reboiler_scaler.get_expression_nominal_value(\n", + " m.fs.unit.vapor_phase[0.0].fug_phase_comp[\"Vap\", \"CO2\"]\n", + ")" ] }, { @@ -1248,12 +1885,12 @@ "source": [ "While in this case this value is positive, the nominal value can be negative, so you should use the absolute value when getting a scaling factor.\n", "\n", - "Finally, we have the last constraint---mechanical equilibrium between phases\n" + "Finally, we have the last constraint: mechanical equilibrium between phases.\n" ] }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 30, "id": "1ad76dde-b6f4-4c26-9d78-5cc76170c399", "metadata": {}, "outputs": [ @@ -1261,7 +1898,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "fs.unit.liquid_phase.properties_out[0.0].pressure == fs.unit.vapor_phase[0.0].pressure" + "fs.unit.liquid_phase.properties_out[0.0].pressure == fs.unit.vapor_phase[0.0].pressure\n" ] } ], @@ -1269,26 +1906,19 @@ "print_compact_form(m.fs.unit.unit_pressure_balance[0.0])" ] }, - { - "cell_type": "markdown", - "id": "8c9ceb71-2018-4dd2-879e-e9a95ffce583", - "metadata": {}, - "source": [ - "Pressure should always have a scaling factor applied, so the inverse maximum method should be good.\n", - "\n" - ] - }, { "cell_type": "markdown", "id": "9e8f7776-21b3-4e43-a76d-f250a55ac31e", "metadata": {}, "source": [ + "The `inverseMinimum` scheme will work here as well.\n", + "\n", "In addition to these problematic unit model level constraints, there are some additional constraints that need scaling factors. Although they might not be problematic under these process conditions, they may be for a scaled-up flowsheet. If we suspect they are well-scaled already, we should use the `report_scaling_factors` function to show what they are:" ] }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 31, "id": "715c1ead-2d0e-4b4f-97ef-bdd8fb0bb2d0", "metadata": {}, "outputs": [ @@ -1336,6 +1966,7 @@ ], "source": [ "from idaes.core.scaling.util import report_scaling_factors\n", + "\n", "report_scaling_factors(m.fs.unit, descend_into=False)" ] }, @@ -1349,7 +1980,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 32, "id": "7f5f85f4-33ec-42a4-a700-c9744b25d6f4", "metadata": {}, "outputs": [ @@ -1357,7 +1988,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "fs.unit.liquid_phase.properties_out[0.0].temperature == fs.unit.vapor_phase[0.0].temperature" + "fs.unit.liquid_phase.properties_out[0.0].temperature == fs.unit.vapor_phase[0.0].temperature\n" ] } ], @@ -1370,12 +2001,14 @@ "id": "40b09e54-30db-4082-ae85-5a5d4f445116", "metadata": {}, "source": [ - "Either inverse maximum or inverse minimum scaling would work just fine. The material balance constraints have different forms depending on whether a component occurs in the liquid phase, the vapor phase, or both:" + "`inverseMinimum` works fine here.\n", + "\n", + "The material balance constraints have different forms depending on whether a component occurs in the liquid phase, the vapor phase, or both:" ] }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 33, "id": "0f62396b-94de-4f92-b7c9-4d6cae1e83b5", "metadata": {}, "outputs": [ @@ -1385,16 +2018,20 @@ "text": [ "- fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,CO2] == fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,CO2]\n", "\n", + "\n", "fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,MEA] == 0*(mol*s**(-1))\n", "\n", - "fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,N2] == fs.unit.zero_flow_param" + "\n", + "fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,N2] == fs.unit.zero_flow_param\n" ] } ], "source": [ - "print_compact_form(m.fs.unit.unit_material_balance[0.0,\"CO2\"]); print(\"\\n\")\n", - "print_compact_form(m.fs.unit.unit_material_balance[0.0,\"MEA\"]); print(\"\\n\")\n", - "print_compact_form(m.fs.unit.unit_material_balance[0.0,\"N2\"])" + "print_compact_form(m.fs.unit.unit_material_balance[0.0, \"CO2\"])\n", + "print(\"\\n\")\n", + "print_compact_form(m.fs.unit.unit_material_balance[0.0, \"MEA\"])\n", + "print(\"\\n\")\n", + "print_compact_form(m.fs.unit.unit_material_balance[0.0, \"N2\"])" ] }, { @@ -1402,7 +2039,7 @@ "id": "b1fc2994-0a80-4530-816a-76e025c49706", "metadata": {}, "source": [ - "The first constraint equates the vapor flow rate to the mass transfer from the liquid phase. Either inverse maximum or inverse minimum would work. The next two are a bit trickier. For $\\text{MEA}$, which is considered nonvolatile in this property package, there is no mass transfer to the vapor phase. A common misconception is that variables should always be scaled to be order one. That is incorrect. We only need to calculate `mass_transfer_term[0.0,\"Liq\",\"MEA\"]` to the same precision as the other (nonzero) terms of the mass balance (and the `ControlVolume0D` submodel scaler does just that). Similarly, `flow_mol_phase_comp[\"Vap\",\"N2\"]` is set to a tiny nonzero value (because flows that are exactly zero often cause problems for property calculations). We do not need more significant figures for either of those variables than the rest of the terms in their correspoding material balances. Therefore we want to use *inverse maximum* becuase inverse minimum would produce bad results.\n", + "The first constraint equates the vapor flow rate to the mass transfer from the liquid phase. Either inverse maximum or inverse minimum would work. The next two are a bit trickier. For $\\text{MEA}$, which is considered nonvolatile in this property package, there is no mass transfer to the vapor phase. A common misconception is that variables should always be scaled to be order one. That is incorrect. We only need to calculate `mass_transfer_term[0.0,\"Liq\",\"MEA\"]` to the same precision as the other (nonzero) terms of the mass balance (and the `ControlVolume0D` submodel scaler does just that). Similarly, `flow_mol_phase_comp[\"Vap\",\"N2\"]` is set to a tiny nonzero value (because flows that are exactly zero often cause problems for property calculations). We do not need more significant figures for either of those variables than the rest of the terms in their correspoding material balances. Therefore we want to use the `inverseMaximum` becuase `inverseMinimum` would demand unnecessary precision.\n", "\n", "
\n", "NOTE\n", @@ -1418,13 +2055,14 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 34, "id": "164ad598-7e44-43ad-b6e6-726721a66f21", "metadata": {}, "outputs": [], "source": [ "from idaes.core.scaling.custom_scaler_base import ConstraintScalingScheme\n", "\n", + "\n", "class SolventReboilerScaler(CustomScalerBase):\n", " def variable_scaling_routine(\n", " self, model, overwrite: bool = False, submodel_scalers: dict = None\n", @@ -1464,16 +2102,36 @@ " # Note: scaling factors cannot be applied directly to indexed objects.\n", " # They should be applied to VarData/ConstraintData/ExpressionData children instead.\n", " for condata in model.unit_material_balance.values():\n", - " self.scale_constraint_by_nominal_value(condata, scheme=ConstraintScalingScheme.inverseMaximum, overwrite=overwrite)\n", + " self.scale_constraint_by_nominal_value(\n", + " condata,\n", + " scheme=ConstraintScalingScheme.inverseMaximum,\n", + " overwrite=overwrite,\n", + " )\n", " for condata in model.unit_temperature_equality.values():\n", - " self.scale_constraint_by_nominal_value(condata, scheme=ConstraintScalingScheme.inverseMaximum, overwrite=overwrite)\n", + " self.scale_constraint_by_nominal_value(\n", + " condata,\n", + " scheme=ConstraintScalingScheme.inverseMinimum,\n", + " overwrite=overwrite,\n", + " )\n", " for condata in model.unit_enthalpy_balance.values():\n", - " self.scale_constraint_by_nominal_value(condata, scheme=ConstraintScalingScheme.inverseMinimum, overwrite=overwrite)\n", + " self.scale_constraint_by_nominal_value(\n", + " condata,\n", + " scheme=ConstraintScalingScheme.inverseMinimum,\n", + " overwrite=overwrite,\n", + " )\n", " for condata in model.unit_pressure_balance.values():\n", - " self.scale_constraint_by_nominal_value(condata, scheme=ConstraintScalingScheme.inverseMaximum, overwrite=overwrite)\n", + " self.scale_constraint_by_nominal_value(\n", + " condata,\n", + " scheme=ConstraintScalingScheme.inverseMinimum,\n", + " overwrite=overwrite,\n", + " )\n", " for (t, j), condata in m.fs.unit.unit_phase_equilibrium.items():\n", - " nom = abs(self.get_expression_nominal_value(m.fs.unit.vapor_phase[t].fug_phase_comp[\"Vap\",j]))\n", - " self.set_constraint_scaling_factor(condata, 1/nom, overwrite=overwrite)" + " nom = abs(\n", + " self.get_expression_nominal_value(\n", + " m.fs.unit.vapor_phase[t].fug_phase_comp[\"Vap\", j]\n", + " )\n", + " )\n", + " self.set_constraint_scaling_factor(condata, 1 / nom, overwrite=overwrite)" ] }, { @@ -1486,7 +2144,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 35, "id": "a319f9b5-4c27-4416-9c8e-41be2d9badd3", "metadata": {}, "outputs": [ @@ -1494,25 +2152,25 @@ "name": "stdout", "output_type": "stream", "text": [ - "2026-04-24 15:46:20 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Starting initialization routine\n", - "2026-04-24 15:46:20 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Bubble, dew, and critical point initialization completed.\n", - "2026-04-24 15:46:20 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Equilibrium temperature initialization completed.\n", - "2026-04-24 15:46:20 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: State variable initialization completed.\n", - "2026-04-24 15:46:20 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Phase equilibrium initialization completed.\n", - "2026-04-24 15:46:20 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Property initialization routine finished.\n", - "2026-04-24 15:46:20 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Starting initialization routine\n", - "2026-04-24 15:46:20 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Bubble, dew, and critical point initialization completed.\n", - "2026-04-24 15:46:20 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Equilibrium temperature initialization completed.\n", - "2026-04-24 15:46:20 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: State variable initialization completed.\n", - "2026-04-24 15:46:20 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Phase equilibrium initialization completed.\n", - "2026-04-24 15:46:20 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Property initialization routine finished.\n", - "2026-04-24 15:46:20 [INFO] idaes.init.fs.unit.vapor_phase: Starting initialization routine\n", - "2026-04-24 15:46:20 [INFO] idaes.init.fs.unit.vapor_phase: Bubble, dew, and critical point initialization completed.\n", - "2026-04-24 15:46:20 [INFO] idaes.init.fs.unit.vapor_phase: Equilibrium temperature initialization completed.\n", - "2026-04-24 15:46:20 [INFO] idaes.init.fs.unit.vapor_phase: State variable initialization completed.\n", - "2026-04-24 15:46:20 [INFO] idaes.init.fs.unit.vapor_phase: Phase equilibrium initialization completed.\n", - "2026-04-24 15:46:20 [INFO] idaes.init.fs.unit.vapor_phase: Property initialization routine finished.\n", - "2026-04-24 15:46:20 [INFO] idaes.init.fs.unit: Initialization Complete: optimal - \n" + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Starting initialization routine\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Bubble, dew, and critical point initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Equilibrium temperature initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: State variable initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Phase equilibrium initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Property initialization routine finished.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Starting initialization routine\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Bubble, dew, and critical point initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Equilibrium temperature initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: State variable initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Phase equilibrium initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Property initialization routine finished.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: Starting initialization routine\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: Bubble, dew, and critical point initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: Equilibrium temperature initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: State variable initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: Phase equilibrium initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: Property initialization routine finished.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit: Initialization Complete: optimal - \n" ] }, { @@ -1521,7 +2179,7 @@ "" ] }, - "execution_count": 32, + "execution_count": 35, "metadata": {}, "output_type": "execute_result" } @@ -1542,7 +2200,7 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 36, "id": "a2e3a35e-165e-4687-a0ef-5330557fdb16", "metadata": {}, "outputs": [ @@ -1568,7 +2226,7 @@ " Caution: 27 Variables with extreme value (<1.0E-04 or >1.0E+04)\n", " Caution: 2 Constraints with mismatched terms\n", " Caution: 1 Constraint with potential cancellation of terms\n", - " Caution: 15 extreme Jacobian Entries (<1.0E-04 or >1.0E+04)\n", + " Caution: 20 extreme Jacobian Entries (<1.0E-04 or >1.0E+04)\n", "\n", "------------------------------------------------------------------------------------\n", "Suggested next steps:\n", @@ -1587,6 +2245,20 @@ "dt.report_numerical_issues()" ] }, + { + "cell_type": "code", + "execution_count": 37, + "id": "f62989cb", + "metadata": { + "tags": [ + "testing" + ] + }, + "outputs": [], + "source": [ + "assert jacobian_cond(m.fs.unit) == pytest.approx(5.40e6, rel=1e-2)" + ] + }, { "cell_type": "markdown", "id": "a51f00e4-e26d-4569-9689-97c1851ccd24", @@ -1594,18 +2266,66 @@ "source": [ "We have reduced the Jacobian condition number by another four orders of magnitude, as well as eliminating all extreme Jacobian rows and columns. A condition number of $5\\cdot 10^6$ is still higher than we'd like for a single unit model, especially for a simple unit model like this one, because connecting units together as part of a flowsheet inevitably increases the condition number. \n", "\n", - "## Step 6: No More Low-hanging Fruit\n", + "## Step 6: Singular Value Decomposition\n", "\n", - "We have two avenues to proceed:\n", + "With no more extreme Jacobian rows or columns, we have two avenues to proceed:\n", "1. Check the extreme Jacobian *entries*\n", "2. Check the singular value decomposition (SVD) of the Jacobian\n", "\n", - "Let's try checking the SVD first." + "Extreme Jacobian entries only *suggest* that the variable and constraint might be contributing to ill-conditioning—they might also be false positives. However, extreme singular values are *guaranteed* to be contributing to the Jacobian's ill-conditioning. Therefore, we will look at the SVD next.\n", + "\n", + "The singular value decomposition factorizes a matrix into three parts:\n", + "$$\n", + "\\mathbf{J} = \\mathbf{U \\Sigma V}^T\n", + "$$\n", + "Both $\\mathbf{U}$ and $\\mathbf{V}$ are orthogonal matrices, i.e., $\\mathbf{U}^T \\mathbf{U} = \\mathbf{I}$ and $\\mathbf{V}^T\\mathbf{V} = \\mathbf{I}$. If $\\mathbf{J}$ is square, then $\\mathbf{\\Sigma}$ is a diagonal matrix of the form:\n", + "$$\n", + "\\mathbf{\\Sigma} = \\begin{bmatrix}\n", + " \\sigma_1 & 0 & \\dots & 0 \\\\\n", + " 0 & \\sigma_2 & \\dots & 0 \\\\\n", + " \\vdots & \\vdots & \\ddots & \\vdots\\\\\n", + " 0 & 0 & \\dots & \\sigma_n\n", + " \\end{bmatrix}\n", + "$$\n", + "in which $\\sigma_j$ are the singular values. The singular values are arranged in descending order, i.e., $\\sigma_{j+1} \\leq \\sigma_{j}$. If any $\\sigma_j=0$, then the matrix is singular.\n", + "\n", + "The condition number is given by:\n", + "$$\n", + "\\kappa(\\mathbf{J}) = \\sigma_1 / \\sigma_n\n", + "$$\n", + "Thus, extremely large and extremely small singular values cause matrix ill-conditioning. However, extremely large singular values typically show up as rows and columns with extreme norms. Therefore we will look at the smallest singular values.\n", + "\n", + "Because $\\mathbf{U}$ and $\\mathbf{V}$ are orthogonal and $\\mathbf{\\Sigma}$ is diagonal, computing a Newton step is easy once the SVD is calculated.\n", + "$$\n", + "\\mathbf{\\delta x}_k = -\\mathbf{V \\Sigma^{-1} U}^T \\cdot \\mathbf{f}(\\mathbf{x}_k)\n", + "$$\n", + "Since we have to refactorize $\\mathbf{J}$ at each iteration, the SVD is not an efficient method to calculate a Newton step. However, this process has a geometric interpretation that is useful for model diagnostics and scaling. First, the constraint residual is decomposed into orthogonal components by $\\mathbf{U}$:\n", + "$$\n", + "\\mathbf{s} = -\\mathbf{U}^T \\cdot \\mathbf{f}(\\mathbf{x}_k)\n", + "$$\n", + "Next, these orthogonal components are scaled by the inverse of the associated singular value:\n", + "$$\n", + "\\mathbf{\\tilde{s}} = \\Sigma^{-1} \\cdot \\mathbf{s}\n", + "$$\n", + "Finally, these independent components are translated into the variable space by $\\mathbf{V}$:\n", + "$$\n", + "\\mathbf{\\delta x}_k = \\mathbf{V} \\cdot \\mathbf{\\tilde{s}}\n", + "$$\n", + "So each orthogonal component of the constraint residual space is associated with an orthogonal component of the variable space. In particular, each singular value $\\sigma_j$ is associated with a left singular vector $\\mathbf{u}_j$ and right singular vector $\\mathbf{v}_j$, the $j\\text{th}$ columns of $\\mathbf{U}$ and $\\mathbf{V}$, respectively. Any constraint error in the direction of $\\mathbf{u}_j$ *must* be satisfied by a corresponding change in the direction of $\\mathbf{v}_j$. When $\\sigma_j$ is extremely small, tiny changes in the direction of $\\mathbf{u}_j$ translate into enormous changes in $\\mathbf{v}_j$. This dysfunctional relationship can be a sign of bad scaling, but also can be a sign of some other model issue like numerical singularity. Typically, singular values in the range $10^{-12}$ to $10^{-4}$ are signs of either bad scaling or a highly sensitive model (for example, a flowsheet with a large recycle stream). Values below $10^{-12}$ are indicative of numerical singularity.\n", + "\n", + "
\n", + "NOTE\n", + "\n", + "The singular vectors $\\mathbf{u}_j$ and $\\mathbf{v}_j$ are typically dense. In order to link them with specific variables and constraints, a thresholding scheme is applied. The `size_cutoff_in_singular_vector` config option for the `SVDToolbox` controls the magnitude of an entry in $\\mathbf{u}_j$ and $\\mathbf{v}_j$ that is sufficient to link a variable or constraint to the $\\sigma_j$. It is `0.1` by default, but can take on values between about `0.05` and `0.3`. Decrease it to show fewer variables and constraints, increase it to show more variables and constraints.\n", + "\n", + "
\n", + "\n", + "So let's create an instance of the `SVDToolbox` and display the variables and constraints associated with the 5 smallest singular values.\n" ] }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 38, "id": "8b62a78b-d7f3-455e-b2c2-4d3ff609f101", "metadata": { "scrolled": true @@ -1618,7 +2338,7 @@ "====================================================================================\n", "Constraints and Variables associated with smallest singular values\n", "\n", - " Smallest Singular Value 1:\n", + " 1st Smallest Singular Value: 6.356e-04\n", "\n", " Variables:\n", "\n", @@ -1636,7 +2356,7 @@ "\n", " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2]\n", "\n", - " Smallest Singular Value 2:\n", + " 2nd Smallest Singular Value: 2.781e-02\n", "\n", " Variables:\n", "\n", @@ -1669,7 +2389,7 @@ " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[MEA]\n", " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", "\n", - " Smallest Singular Value 3:\n", + " 3rd Smallest Singular Value: 3.679e-02\n", "\n", " Variables:\n", "\n", @@ -1707,7 +2427,7 @@ " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,HCO3_-]\n", " fs.unit.vapor_phase[0.0].sum_mole_frac_out\n", "\n", - " Smallest Singular Value 4:\n", + " 4th Smallest Singular Value: 6.842e-02\n", "\n", " Variables:\n", "\n", @@ -1731,7 +2451,7 @@ " fs.unit.liquid_phase.properties_in[0.0].total_flow_balance\n", " fs.unit.vapor_phase[0.0].sum_mole_frac_out\n", "\n", - " Smallest Singular Value 5:\n", + " 5th Smallest Singular Value: 7.703e-02\n", "\n", " Variables:\n", "\n", @@ -1752,25 +2472,28 @@ "\n", "====================================================================================\n" ] - }, - { - "data": { - "text/plain": [ - "array([0.00063559, 0.02780866, 0.03679008, 0.06841867, 0.07702857,\n", - " 0.09285582, 0.11369371, 0.11731412, 0.1479692 , 0.19043286])" - ] - }, - "execution_count": 34, - "metadata": {}, - "output_type": "execute_result" } ], "source": [ "st = dt.prepare_svd_toolbox()\n", "# The SVD toolbox displays 10 singular values by default, but we are going to\n", - "# look at just the first five to reduce the amount of output.\n", - "st.display_underdetermined_variables_and_constraints(singular_values=[1, 2, 3, 4, 5])\n", - "st.s" + "# view the only the first five to reduce the amount of output.\n", + "st.display_underdetermined_variables_and_constraints(singular_values=[1, 2, 3, 4, 5])" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "id": "4abb105d", + "metadata": { + "tags": [ + "testing" + ] + }, + "outputs": [], + "source": [ + "assert st.s[0] == pytest.approx(6.356e-04, rel=1e-2)\n", + "assert st.s[1] == pytest.approx(2.781e-02, rel=1e-2)" ] }, { @@ -1783,7 +2506,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 40, "id": "43b2dd6a-e71b-48ea-a3a8-36d6f73f9f80", "metadata": {}, "outputs": [ @@ -1791,12 +2514,16 @@ "name": "stdout", "output_type": "stream", "text": [ - "exp(fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]) == fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,CO2]/(mol/m**3)" + "exp(fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]) == fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,CO2]/(mol/m**3)\n" ] } ], "source": [ - "print_compact_form(m.fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[\"Liq\",\"CO2\"])" + "print_compact_form(\n", + " m.fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[\n", + " \"Liq\", \"CO2\"\n", + " ]\n", + ")" ] }, { @@ -1811,7 +2538,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 41, "id": "5900b815-9725-4334-a108-ae70088b3962", "metadata": {}, "outputs": [ @@ -1822,10 +2549,12 @@ "====================================================================================\n", "The following variables are involved in fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2]:\n", "\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,H2O]: 4.280e-05\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,MEA]: 1.492e-04\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,H2O]: 4.333e-05\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,MEA]: 1.441e-04\n", " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,CO2]: 6.126e-05\n", " fs.unit.liquid_phase.properties_out[0.0].temperature: 1.576e-04\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]: -5.255e-07\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA]: 5.123e-06\n", " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,CO2]: -1.648e+00\n", " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]: 5.621e-04\n", "\n", @@ -1834,7 +2563,11 @@ } ], "source": [ - "st.display_variables_in_constraint(m.fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[\"Liq\",\"CO2\"])" + "st.display_variables_in_constraint(\n", + " m.fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[\n", + " \"Liq\", \"CO2\"\n", + " ]\n", + ")" ] }, { @@ -1843,7 +2576,9 @@ "metadata": {}, "source": [ "
\n", - "NOTE At this point of the process, the original author found a shortcoming in the modular properties scaler. No scaling hint was set for the molar density expression, so the expression walker descended into it and came back with an inappropriate nominal value. Revising the scaler to estimate the phase density resulted in a condition number improvement of 1-2 orders of magnitude.\n", + "NOTE\n", + "\n", + "At this point of the process, the original author found a shortcoming in the `ModularPropertiesScaler`. No scaling hint was set for the molar density expression, so the expression walker descended into it and came back with an inappropriate nominal value. Revising the scaler to estimate the phase density resulted in a condition number improvement of 1-2 orders of magnitude.\n", "\n", "Remember:\n", "1. Scaling is an iterative process.\n", @@ -1858,7 +2593,7 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 42, "id": "7f9156a6-dbd0-4902-9fa2-ebb4e487f365", "metadata": {}, "outputs": [ @@ -1872,8 +2607,12 @@ } ], "source": [ - "print(f\"Left hand side value: {value(exp(m.fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[\"Liq\",\"CO2\"])):.4e}\")\n", - "print(f\"CO2 true concentration value: {value(m.fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[\"Liq\",\"CO2\"]):.4e}\")" + "print(\n", + " f\"Left hand side value: {value(exp(m.fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[\"Liq\",\"CO2\"])):.4e}\"\n", + ")\n", + "print(\n", + " f\"CO2 true concentration value: {value(m.fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[\"Liq\",\"CO2\"]):.4e}\"\n", + ")" ] }, { @@ -1886,7 +2625,27 @@ }, { "cell_type": "code", - "execution_count": 38, + "execution_count": 43, + "id": "33d7953e", + "metadata": { + "tags": [ + "testing" + ] + }, + "outputs": [], + "source": [ + "assert get_scaling_factor(\n", + " (\n", + " m.fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[\n", + " \"Liq\", \"CO2\"\n", + " ]\n", + " )\n", + ") == pytest.approx(4.104e-4, rel=1e-2)" + ] + }, + { + "cell_type": "code", + "execution_count": 44, "id": "5166b5b9-99cb-4a21-95d3-ead5992a40ed", "metadata": {}, "outputs": [ @@ -1899,7 +2658,15 @@ } ], "source": [ - "print(get_scaling_factor((m.fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[\"Liq\",\"CO2\"])))" + "print(\n", + " get_scaling_factor(\n", + " (\n", + " m.fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[\n", + " \"Liq\", \"CO2\"\n", + " ]\n", + " )\n", + " )\n", + ")" ] }, { @@ -1914,7 +2681,7 @@ }, { "cell_type": "code", - "execution_count": 39, + "execution_count": 45, "id": "ef7e9960-da1f-43a5-a1f6-6fd84be6896a", "metadata": {}, "outputs": [ @@ -1928,8 +2695,12 @@ } ], "source": [ - "print(f\"True CO2 mole fraction: {m.fs.unit.liquid_phase.properties_out[0].mole_frac_phase_comp_true[\"Liq\",\"CO2\"].value:4e}\")\n", - "print(f\"True MEACOO- mole fraction: {m.fs.unit.liquid_phase.properties_out[0].mole_frac_phase_comp_true[\"Liq\",\"MEACOO_-\"].value:4e}\")" + "print(\n", + " f\"True CO2 mole fraction: {m.fs.unit.liquid_phase.properties_out[0].mole_frac_phase_comp_true[\"Liq\",\"CO2\"].value:4e}\"\n", + ")\n", + "print(\n", + " f\"True MEACOO- mole fraction: {m.fs.unit.liquid_phase.properties_out[0].mole_frac_phase_comp_true[\"Liq\",\"MEACOO_-\"].value:4e}\"\n", + ")" ] }, { @@ -1942,12 +2713,14 @@ }, { "cell_type": "code", - "execution_count": 40, + "execution_count": 46, "id": "f519aee0-4a23-4d3c-a705-e7135ea6fd27", "metadata": {}, "outputs": [], "source": [ - "default_scaling_factors = m.fs.liquid_properties.default_state_scaler_object.default_scaling_factors\n", + "default_scaling_factors = (\n", + " m.fs.liquid_properties.default_state_scaler_object.default_scaling_factors\n", + ")\n", "# Dictionaries are mutable, so changing its value here also changes it on the scaler object\n", "# First scale the apparent mole fractions\n", "default_scaling_factors[\"mole_frac_phase_comp[Liq, H2O]\"] = 1\n", @@ -1967,42 +2740,44 @@ "id": "26d9d52d-3f27-4fa9-949b-764553252132", "metadata": {}, "source": [ - "With these new scaling factors, let's rescale and resolve the mode, then check the new condition number" + "With these new scaling factors, let's rescale and resolve the mode, then check the new condition number." ] }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 47, "id": "ae81a354-ba6e-452a-bb7d-37edbf850d05", - "metadata": {}, + "metadata": { + "scrolled": true + }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "2026-04-24 15:46:21 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Starting initialization routine\n", - "2026-04-24 15:46:21 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Bubble, dew, and critical point initialization completed.\n", - "2026-04-24 15:46:21 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Equilibrium temperature initialization completed.\n", - "2026-04-24 15:46:21 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: State variable initialization completed.\n", - "2026-04-24 15:46:21 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Phase equilibrium initialization completed.\n", - "2026-04-24 15:46:21 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Property initialization routine finished.\n", - "2026-04-24 15:46:21 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Starting initialization routine\n", - "2026-04-24 15:46:21 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Bubble, dew, and critical point initialization completed.\n", - "2026-04-24 15:46:21 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Equilibrium temperature initialization completed.\n", - "2026-04-24 15:46:21 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: State variable initialization completed.\n", - "2026-04-24 15:46:21 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Phase equilibrium initialization completed.\n", - "2026-04-24 15:46:21 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Property initialization routine finished.\n", - "2026-04-24 15:46:21 [INFO] idaes.init.fs.unit.vapor_phase: Starting initialization routine\n", - "2026-04-24 15:46:21 [INFO] idaes.init.fs.unit.vapor_phase: Bubble, dew, and critical point initialization completed.\n", - "2026-04-24 15:46:21 [INFO] idaes.init.fs.unit.vapor_phase: Equilibrium temperature initialization completed.\n", - "2026-04-24 15:46:21 [INFO] idaes.init.fs.unit.vapor_phase: State variable initialization completed.\n", - "2026-04-24 15:46:21 [INFO] idaes.init.fs.unit.vapor_phase: Phase equilibrium initialization completed.\n", - "2026-04-24 15:46:21 [INFO] idaes.init.fs.unit.vapor_phase: Property initialization routine finished.\n", - "2026-04-24 15:46:21 [INFO] idaes.init.fs.unit: Initialization Complete: optimal - \n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Starting initialization routine\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Bubble, dew, and critical point initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Equilibrium temperature initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: State variable initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Phase equilibrium initialization completed.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Property initialization routine finished.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Starting initialization routine\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Bubble, dew, and critical point initialization completed.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Equilibrium temperature initialization completed.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: State variable initialization completed.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Phase equilibrium initialization completed.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Property initialization routine finished.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: Starting initialization routine\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: Bubble, dew, and critical point initialization completed.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: Equilibrium temperature initialization completed.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: State variable initialization completed.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: Phase equilibrium initialization completed.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: Property initialization routine finished.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit: Initialization Complete: optimal - \n", "====================================================================================\n", "Model Statistics\n", "\n", - " Jacobian Condition Number: 2.914E+05\n", + " Jacobian Condition Number: 2.945E+05\n", "\n", "------------------------------------------------------------------------------------\n", "0 WARNINGS\n", @@ -2017,7 +2792,7 @@ " Caution: 27 Variables with extreme value (<1.0E-04 or >1.0E+04)\n", " Caution: 2 Constraints with mismatched terms\n", " Caution: 1 Constraint with potential cancellation of terms\n", - " Caution: 14 extreme Jacobian Entries (<1.0E-04 or >1.0E+04)\n", + " Caution: 16 extreme Jacobian Entries (<1.0E-04 or >1.0E+04)\n", "\n", "------------------------------------------------------------------------------------\n", "Suggested next steps:\n", @@ -2039,6 +2814,20 @@ "dt.report_numerical_issues()" ] }, + { + "cell_type": "code", + "execution_count": 48, + "id": "21820a85", + "metadata": { + "tags": [ + "testing" + ] + }, + "outputs": [], + "source": [ + "assert jacobian_cond(m.fs.unit) == pytest.approx(2.945e05, rel=1e-2)" + ] + }, { "cell_type": "markdown", "id": "a94bcc79-523e-4a54-9659-0da85ab98dac", @@ -2049,7 +2838,7 @@ }, { "cell_type": "code", - "execution_count": 42, + "execution_count": 49, "id": "baeb6028-71fb-46c9-ac73-ddaf75f1f7d4", "metadata": { "scrolled": true @@ -2062,7 +2851,7 @@ "====================================================================================\n", "Constraints and Variables associated with smallest singular values\n", "\n", - " Smallest Singular Value 1:\n", + " 1st Smallest Singular Value: 6.965e-04\n", "\n", " Variables:\n", "\n", @@ -2081,7 +2870,7 @@ " fs.unit.liquid_phase.properties_in[0.0].total_flow_balance\n", " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", "\n", - " Smallest Singular Value 2:\n", + " 2nd Smallest Singular Value: 1.047e-03\n", "\n", " Variables:\n", "\n", @@ -2095,16 +2884,15 @@ " fs.unit.liquid_phase.material_balances[0.0,H2O]\n", " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA]\n", " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEACOO_-]\n", " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEA_+]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-]\n", " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEACOO_-]\n", " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA_+]\n", "\n", - " Smallest Singular Value 3:\n", + " 3rd Smallest Singular Value: 4.024e-03\n", "\n", " Variables:\n", "\n", @@ -2122,18 +2910,14 @@ " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEA]\n", " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-]\n", " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,H2O]\n", " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA]\n", " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEACOO_-]\n", " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].total_flow_balance\n", " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[MEA]\n", " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_k_eq_constraint[bicarbonate]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_k_eq_constraint[carbamate]\n", - " fs.unit.liquid_phase.properties_in[0.0].inherent_equilibrium_constraint[bicarbonate]\n", - " fs.unit.liquid_phase.properties_in[0.0].inherent_equilibrium_constraint[carbamate]\n", "\n", - " Smallest Singular Value 4:\n", + " 4th Smallest Singular Value: 5.218e-03\n", "\n", " Variables:\n", "\n", @@ -2151,7 +2935,7 @@ " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEACOO_-]\n", " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,HCO3_-]\n", "\n", - " Smallest Singular Value 5:\n", + " 5th Smallest Singular Value: 5.115e-02\n", "\n", " Variables:\n", "\n", @@ -2161,6 +2945,7 @@ " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,CO2]\n", " fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,CO2]\n", " fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", " fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,CO2]\n", " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-]\n", @@ -2179,6 +2964,7 @@ " fs.unit.liquid_phase.material_balances[0.0,MEA]\n", " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA]\n", " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEACOO_-]\n", @@ -2188,6 +2974,7 @@ " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-]\n", " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA_+]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA]\n", " fs.unit.unit_material_balance[0.0,MEA]\n", " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,HCO3_-]\n", " fs.unit.liquid_phase.properties_in[0.0].total_flow_balance\n", @@ -2201,23 +2988,23 @@ "\n", "====================================================================================\n" ] - }, - { - "data": { - "text/plain": [ - "array([0.00069966, 0.00106482, 0.00451863, 0.00578932, 0.05431777,\n", - " 0.06674241, 0.06777552, 0.08956049, 0.14336208, 0.17607054])" - ] - }, - "execution_count": 42, - "metadata": {}, - "output_type": "execute_result" } ], "source": [ "st = dt.prepare_svd_toolbox()\n", - "st.display_underdetermined_variables_and_constraints([1,2,3,4,5])\n", - "st.s" + "st.display_underdetermined_variables_and_constraints([1, 2, 3, 4, 5])" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "id": "9f9c565b", + "metadata": {}, + "outputs": [], + "source": [ + "assert st.s[0] == pytest.approx(6.965e-04, rel=1e-2)\n", + "assert st.s[3] == pytest.approx(5.218e-03, rel=1e-2)\n", + "assert st.s[4] == pytest.approx(5.115e-02, rel=1e-2)" ] }, { @@ -2234,7 +3021,7 @@ }, { "cell_type": "code", - "execution_count": 43, + "execution_count": 51, "id": "28633b75-9a64-4fe6-b27c-c93498413f47", "metadata": { "scrolled": true @@ -2369,12 +3156,12 @@ "fs.unit.liquid_phase.properties_in[0.0].log_k_eq_constraint[carbamate] None\n", "fs.unit.liquid_phase.properties_in[0.0].inherent_equilibrium_constraint[bicarbonate] 1.000E+00\n", "fs.unit.liquid_phase.properties_in[0.0].inherent_equilibrium_constraint[carbamate] 1.000E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-] 4.104E-04\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-] 4.104E-03\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA_+] 4.104E-04\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,H2O] 4.104E-05\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA] 4.104E-04\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2] 4.104E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-] 2.377E-04\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-] 2.377E-03\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA_+] 2.377E-04\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,H2O] 2.377E-05\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA] 2.377E-04\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2] 2.377E-01\n", "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEACOO_-] 1.250E-01\n", "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,HCO3_-] 1.250E+00\n", "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA_+] 1.250E-01\n", @@ -2397,12 +3184,12 @@ "fs.unit.liquid_phase.properties_out[0.0].log_k_eq_constraint[carbamate] None\n", "fs.unit.liquid_phase.properties_out[0.0].inherent_equilibrium_constraint[bicarbonate] 1.000E+00\n", "fs.unit.liquid_phase.properties_out[0.0].inherent_equilibrium_constraint[carbamate] 1.000E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-] 4.104E-04\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-] 4.104E-03\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA_+] 4.104E-04\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,H2O] 4.104E-05\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA] 4.104E-04\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2] 4.104E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-] 2.377E-04\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-] 2.377E-03\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA_+] 2.377E-04\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,H2O] 2.377E-05\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA] 2.377E-04\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2] 2.377E-01\n", "fs.unit.vapor_phase[0.0].sum_mole_frac_out 1.000E+00\n", "fs.unit.vapor_phase[0.0].total_flow_balance 1.000E-01\n", "fs.unit.vapor_phase[0.0].component_flow_balances[CO2] 1.000E+01\n", @@ -2423,8 +3210,8 @@ "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,H2O] None\n", "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,MEA] None\n", "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,CO2] None\n", - "fs.unit.liquid_phase.properties_in[0.0].dens_mol_phase[Liq] 4.104E-05\n", - "fs.unit.liquid_phase.properties_in[0.0].vol_mol_phase[Liq] None\n", + "fs.unit.liquid_phase.properties_in[0.0].dens_mol_phase[Liq] 2.377E-05\n", + "fs.unit.liquid_phase.properties_in[0.0].vol_mol_phase[Liq] 4.206E+04\n", "fs.unit.liquid_phase.properties_in[0.0]._enthalpy_flow_term[Liq] None\n", "fs.unit.liquid_phase.properties_in[0.0].enth_mol_phase[Liq] 7.010E-05\n", "fs.unit.liquid_phase.properties_in[0.0].flow_mol_comp[H2O] 1.250E-02\n", @@ -2441,8 +3228,8 @@ "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,H2O] None\n", "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,MEA] None\n", "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,CO2] None\n", - "fs.unit.liquid_phase.properties_out[0.0].dens_mol_phase[Liq] 4.104E-05\n", - "fs.unit.liquid_phase.properties_out[0.0].vol_mol_phase[Liq] None\n", + "fs.unit.liquid_phase.properties_out[0.0].dens_mol_phase[Liq] 2.377E-05\n", + "fs.unit.liquid_phase.properties_out[0.0].vol_mol_phase[Liq] 4.206E+04\n", "fs.unit.liquid_phase.properties_out[0.0]._enthalpy_flow_term[Liq] None\n", "fs.unit.liquid_phase.properties_out[0.0].enth_mol_phase[Liq] 7.010E-05\n", "fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[Liq,H2O] None\n", @@ -2474,6 +3261,7 @@ ], "source": [ "from idaes.core.scaling.util import report_scaling_factors\n", + "\n", "report_scaling_factors(m.fs.unit, descend_into=True)" ] }, @@ -2487,6 +3275,18 @@ "We have reduced the condition number to $3 \\cdot 10^5$, which is not quite as low as we would have liked, but is a vast improvement over the value $3 \\cdot 10^{13}$, which we started out with. " ] }, + { + "cell_type": "markdown", + "id": "7255a079", + "metadata": {}, + "source": [ + "# References\n", + "\n", + "[[1](https://doi.org/10.1016/j.compchemeng.2025.109312)] Allan, D. A., Ostace, A. G., & Polley, T. (2025). Jacobian-based model diagnostics and application to equation oriented modeling of a carbon capture system. Computers & Chemical Engineering, 109312.\n", + "\n", + "[[2](https://link.springer.com/article/10.1007/S10107-004-0559-Y)] Wächter, A., & Biegler, L. T. (2006). On the implementation of an interior-point filter line-search algorithm for large-scale nonlinear programming. Mathematical programming, 106(1), 25-57." + ] + }, { "cell_type": "code", "execution_count": null, From 48b4c6fc43623276184f773c2d53cdad714ec6ec Mon Sep 17 00:00:00 2001 From: Doug A Date: Wed, 29 Apr 2026 17:22:51 -0400 Subject: [PATCH 4/7] register --- idaes_examples/notebooks/_toc.yml | 1 + .../advanced_scaling_techniques_doc.ipynb | 3110 ++++++++++++++++ .../advanced_scaling_techniques_test.ipynb | 3224 +++++++++++++++++ .../advanced_scaling_techniques_usr.ipynb | 3110 ++++++++++++++++ 4 files changed, 9445 insertions(+) create mode 100644 idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques_doc.ipynb create mode 100644 idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques_test.ipynb create mode 100644 idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques_usr.ipynb diff --git a/idaes_examples/notebooks/_toc.yml b/idaes_examples/notebooks/_toc.yml index fbed8572..966ce9f6 100644 --- a/idaes_examples/notebooks/_toc.yml +++ b/idaes_examples/notebooks/_toc.yml @@ -23,6 +23,7 @@ parts: - file: docs/scaling/index sections: - file: docs/scaling/scaler_workshop_doc + - file: docs/scaling/advanced_scaling_techniques_doc - file: docs/param_est/index sections: - file: docs/param_est/parameter_estimation_nrtl_using_state_block_doc diff --git a/idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques_doc.ipynb b/idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques_doc.ipynb new file mode 100644 index 00000000..693c14b1 --- /dev/null +++ b/idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques_doc.ipynb @@ -0,0 +1,3110 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "###############################################################################\n", + "# The Institute for the Design of Advanced Energy Systems Integrated Platform\n", + "# Framework (IDAES IP) was produced under the DOE Institute for the\n", + "# Design of Advanced Energy Systems (IDAES).\n", + "#\n", + "# Copyright (c) 2018-2026 by the software owners: The Regents of the\n", + "# University of California, through Lawrence Berkeley National Laboratory,\n", + "# National Technology & Engineering Solutions of Sandia, LLC, Carnegie Mellon\n", + "# University, West Virginia University Research Corporation, et al.\n", + "# All rights reserved. Please see the files COPYRIGHT.md and LICENSE.md\n", + "# for full copyright and license information.\n", + "###############################################################################" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Advanced Scaling Techniques\n", + "\n", + "Author: Doug Allan\\\n", + "Maintainer: Doug Allan\\\n", + "Updated: 2026-04-30\n", + "\n", + "## Introduction\n", + "\n", + "This notebook is intended to give the user further insight into how the scaling toolbox can be used to improve robustness. A large portion of the material is an adaptation of [Allan, Ostace, and Polly (2025)](#references). By the end of this study, the user should understand:\n", + "* How a default scaler object can be specified for a property package\n", + "* How to set default scaling factors for property package variables\n", + "* The strengths and weaknesses of the ``NominalValueExpressionWalker`` used in ``CustomScalerBase.get_sum_terms_nominal_values`` and ``CustomScalerBase.get_expression_nominal_value`` for use in constraint scaling\n", + "* How to use the ``SVDToolbox`` to troubleshoot scaling issues\n", + "\n", + "## Step 1: Set Up Test Case\n", + "We will use the `SolventReboiler` unit model as a case study. It is a component in a stripping column used for solvent regeneration. It is modeled as a single equilibrium stage with an external heat duty. The inlet stream is entirely liquid, while it has both boilup and bottoms outlet streams. The liquid and vapor phases use different configurations of the modular property framework.\n", + "\n", + "First, we set up and attempt to initialize the unit model." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2026-04-29 17:11:54 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Starting initialization routine\n", + "2026-04-29 17:11:54 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Bubble, dew, and critical point initialization completed.\n", + "2026-04-29 17:11:54 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Equilibrium temperature initialization completed.\n", + "2026-04-29 17:11:54 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: State variable initialization completed.\n", + "2026-04-29 17:11:54 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Phase equilibrium initialization completed.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Ipopt 3.13.2: linear_solver=\"ma57\"\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: max_iter=200\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: nlp_scaling_method=\"gradient-based\"\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: tol=1e-06\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: ******************************************************************************\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: For more information visit http://projects.coin-or.org/Ipopt\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: This version of Ipopt was compiled from source code available at\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: for large-scale scientific computation. All technical papers, sales and\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: publicity material resulting from use of the HSL codes within IPOPT must\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: contain the following acknowledgement:\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: HSL, a collection of Fortran codes for large-scale scientific\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: computation. See http://www.hsl.rl.ac.uk.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: ******************************************************************************\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of nonzeros in equality constraint Jacobian...: 74\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of nonzeros in inequality constraint Jacobian.: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of nonzeros in Lagrangian Hessian.............: 42\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Total number of variables............................: 18\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: variables with only lower bounds: 6\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: variables with lower and upper bounds: 12\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: variables with only upper bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Total number of equality constraints.................: 18\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Total number of inequality constraints...............: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: inequality constraints with only lower bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: inequality constraints with lower and upper bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: inequality constraints with only upper bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 0 0.0000000e+00 4.13e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Reallocating memory for MA57: lfact (1377)\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 1 0.0000000e+00 4.05e+02 1.89e+12 -1.0 6.07e+01 - 1.92e-01 1.98e-02H 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 2 0.0000000e+00 1.62e+04 1.56e+17 -1.0 8.76e+01 - 1.69e-01 5.07e-01H 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 3 0.0000000e+00 1.62e+04 1.55e+17 -1.0 4.59e+01 - 1.21e-07 3.23e-03H 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 4 0.0000000e+00 2.15e+04 1.93e+17 -1.0 4.88e+01 - 1.06e-02 9.12e-01h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Reallocating memory for MA57: lfact (1542)\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 5 0.0000000e+00 2.15e+04 1.93e+17 -1.0 3.05e+02 - 4.08e-04 6.58e-04h 2\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Reallocating memory for MA57: lfact (1662)\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 6 0.0000000e+00 2.09e+04 1.87e+17 -1.0 1.11e+01 - 4.04e-03 3.08e-02h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 7 0.0000000e+00 1.50e+04 1.37e+17 -1.0 1.37e+01 - 1.44e-04 3.14e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 8 0.0000000e+00 1.49e+04 1.36e+17 -1.0 4.21e+00 - 5.37e-01 9.11e-03h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 9 0.0000000e+00 1.49e+04 1.36e+17 -1.0 4.10e+00 - 9.86e-01 9.35e-05h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 10r 0.0000000e+00 1.49e+04 1.00e+03 1.6 0.00e+00 - 0.00e+00 4.68e-07R 2\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 11r 0.0000000e+00 5.25e+03 2.22e+03 1.6 3.13e+04 - 3.88e-03 1.14e-03f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 12r 0.0000000e+00 5.08e+03 4.24e+04 1.6 1.22e+03 - 1.88e-01 5.18e-03f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 13r 0.0000000e+00 4.77e+03 3.36e+04 1.6 6.27e+01 - 3.06e-02 6.76e-02f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 14r 0.0000000e+00 4.33e+03 1.32e+05 1.6 8.06e+00 - 5.05e-01 9.81e-02f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 15r 0.0000000e+00 4.19e+03 1.12e+05 1.6 9.20e+00 - 3.38e-01 3.25e-02f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 16r 0.0000000e+00 1.89e+03 5.50e+04 1.6 2.54e+00 - 8.42e-02 7.08e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 17r 0.0000000e+00 1.72e+03 4.73e+04 1.6 7.82e+00 - 2.36e-01 1.01e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 18r 0.0000000e+00 1.14e+03 2.84e+04 1.6 1.92e+00 - 7.10e-01 4.02e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 19r 0.0000000e+00 1.06e+03 2.92e+04 1.6 5.12e+00 - 7.85e-01 7.79e-02f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 20r 0.0000000e+00 2.69e+02 3.66e+03 1.6 5.52e-01 - 1.00e+00 9.33e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 21r 0.0000000e+00 1.64e+01 3.96e+02 0.9 1.63e-01 - 9.76e-01 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 22r 0.0000000e+00 6.87e-01 1.09e+02 0.2 3.52e-02 - 1.00e+00 9.59e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 23r 0.0000000e+00 2.05e-01 8.47e+03 -0.5 2.72e-03 - 1.00e+00 6.98e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 24r 0.0000000e+00 1.34e-03 2.18e-01 -0.5 1.87e-03 - 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 25r 0.0000000e+00 1.29e-02 1.88e+02 -2.9 3.36e-04 - 1.00e+00 9.47e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 26r 0.0000000e+00 2.90e-06 4.04e-05 -2.9 7.48e-05 - 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of Iterations....: 26\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: (scaled) (unscaled)\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Constraint violation....: 2.1131334015933589e-08 2.8957967970200116e-06\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Overall NLP error.......: 2.1131334015933589e-08 2.8957967970200116e-06\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of objective function evaluations = 34\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of objective gradient evaluations = 12\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of equality constraint evaluations = 36\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of inequality constraint evaluations = 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of equality constraint Jacobian evaluations = 28\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of inequality constraint Jacobian evaluations = 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of Lagrangian Hessian evaluations = 26\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Total CPU secs in IPOPT (w/o function evaluations) = 0.006\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Total CPU secs in NLP function evaluations = 0.000\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: EXIT: Optimal Solution Found.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Property initialization routine finished.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Starting initialization routine\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Bubble, dew, and critical point initialization completed.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Equilibrium temperature initialization completed.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: State variable initialization completed.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Phase equilibrium initialization completed.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Ipopt 3.13.2: linear_solver=\"ma57\"\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: max_iter=200\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: nlp_scaling_method=\"gradient-based\"\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: tol=1e-06\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: ******************************************************************************\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: For more information visit http://projects.coin-or.org/Ipopt\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: This version of Ipopt was compiled from source code available at\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: for large-scale scientific computation. All technical papers, sales and\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: publicity material resulting from use of the HSL codes within IPOPT must\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: contain the following acknowledgement:\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: HSL, a collection of Fortran codes for large-scale scientific\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: computation. See http://www.hsl.rl.ac.uk.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: ******************************************************************************\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of nonzeros in equality constraint Jacobian...: 74\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of nonzeros in inequality constraint Jacobian.: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of nonzeros in Lagrangian Hessian.............: 42\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Total number of variables............................: 18\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: variables with only lower bounds: 6\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: variables with lower and upper bounds: 12\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: variables with only upper bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Total number of equality constraints.................: 18\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Total number of inequality constraints...............: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: inequality constraints with only lower bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: inequality constraints with lower and upper bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: inequality constraints with only upper bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 0 0.0000000e+00 4.13e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Reallocating memory for MA57: lfact (1377)\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 1 0.0000000e+00 4.05e+02 1.89e+12 -1.0 6.07e+01 - 1.92e-01 1.98e-02H 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 2 0.0000000e+00 1.62e+04 1.56e+17 -1.0 8.76e+01 - 1.69e-01 5.07e-01H 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 3 0.0000000e+00 1.62e+04 1.55e+17 -1.0 4.59e+01 - 1.21e-07 3.23e-03H 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 4 0.0000000e+00 2.15e+04 1.93e+17 -1.0 4.88e+01 - 1.06e-02 9.12e-01h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Reallocating memory for MA57: lfact (1542)\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 5 0.0000000e+00 2.15e+04 1.93e+17 -1.0 3.05e+02 - 4.08e-04 6.58e-04h 2\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Reallocating memory for MA57: lfact (1662)\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 6 0.0000000e+00 2.09e+04 1.87e+17 -1.0 1.11e+01 - 4.04e-03 3.08e-02h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 7 0.0000000e+00 1.50e+04 1.37e+17 -1.0 1.37e+01 - 1.44e-04 3.14e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 8 0.0000000e+00 1.49e+04 1.36e+17 -1.0 4.21e+00 - 5.37e-01 9.11e-03h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 9 0.0000000e+00 1.49e+04 1.36e+17 -1.0 4.10e+00 - 9.86e-01 9.35e-05h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 10r 0.0000000e+00 1.49e+04 1.00e+03 1.6 0.00e+00 - 0.00e+00 4.68e-07R 2\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 11r 0.0000000e+00 5.25e+03 2.22e+03 1.6 3.13e+04 - 3.88e-03 1.14e-03f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 12r 0.0000000e+00 5.08e+03 4.24e+04 1.6 1.22e+03 - 1.88e-01 5.18e-03f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 13r 0.0000000e+00 4.77e+03 3.36e+04 1.6 6.27e+01 - 3.06e-02 6.76e-02f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 14r 0.0000000e+00 4.33e+03 1.32e+05 1.6 8.06e+00 - 5.05e-01 9.81e-02f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 15r 0.0000000e+00 4.19e+03 1.12e+05 1.6 9.20e+00 - 3.38e-01 3.25e-02f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 16r 0.0000000e+00 1.89e+03 5.50e+04 1.6 2.54e+00 - 8.42e-02 7.08e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 17r 0.0000000e+00 1.72e+03 4.73e+04 1.6 7.82e+00 - 2.36e-01 1.01e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 18r 0.0000000e+00 1.14e+03 2.84e+04 1.6 1.92e+00 - 7.10e-01 4.02e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 19r 0.0000000e+00 1.06e+03 2.92e+04 1.6 5.12e+00 - 7.85e-01 7.79e-02f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 20r 0.0000000e+00 2.69e+02 3.66e+03 1.6 5.52e-01 - 1.00e+00 9.33e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 21r 0.0000000e+00 1.64e+01 3.96e+02 0.9 1.63e-01 - 9.76e-01 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 22r 0.0000000e+00 6.87e-01 1.09e+02 0.2 3.52e-02 - 1.00e+00 9.59e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 23r 0.0000000e+00 2.05e-01 8.47e+03 -0.5 2.72e-03 - 1.00e+00 6.98e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 24r 0.0000000e+00 1.34e-03 2.18e-01 -0.5 1.87e-03 - 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 25r 0.0000000e+00 1.29e-02 1.88e+02 -2.9 3.36e-04 - 1.00e+00 9.47e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 26r 0.0000000e+00 2.90e-06 4.04e-05 -2.9 7.48e-05 - 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of Iterations....: 26\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: (scaled) (unscaled)\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Constraint violation....: 2.1131334015933589e-08 2.8957967970200116e-06\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Overall NLP error.......: 2.1131334015933589e-08 2.8957967970200116e-06\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of objective function evaluations = 34\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of objective gradient evaluations = 12\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of equality constraint evaluations = 36\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of inequality constraint evaluations = 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of equality constraint Jacobian evaluations = 28\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of inequality constraint Jacobian evaluations = 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of Lagrangian Hessian evaluations = 26\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Total CPU secs in IPOPT (w/o function evaluations) = 0.008\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Total CPU secs in NLP function evaluations = 0.000\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: EXIT: Optimal Solution Found.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Property initialization routine finished.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase: Control volume properties initialization complete\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase: Control volume reactions initialization complete\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit: Initialization Step 1 Complete.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: Starting initialization routine\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: Bubble, dew, and critical point initialization completed.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: Equilibrium temperature initialization completed.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: State variable initialization completed.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: Phase equilibrium initialization completed.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: Property initialization routine finished.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit: Initialization Step 2 Complete.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Ipopt 3.13.2: linear_solver=\"ma57\"\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: max_iter=200\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: nlp_scaling_method=\"gradient-based\"\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: tol=1e-06\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: ******************************************************************************\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: For more information visit http://projects.coin-or.org/Ipopt\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: This version of Ipopt was compiled from source code available at\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: for large-scale scientific computation. All technical papers, sales and\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: publicity material resulting from use of the HSL codes within IPOPT must\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: contain the following acknowledgement:\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: HSL, a collection of Fortran codes for large-scale scientific\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: computation. See http://www.hsl.rl.ac.uk.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: ******************************************************************************\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of nonzeros in equality constraint Jacobian...: 231\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of nonzeros in inequality constraint Jacobian.: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of nonzeros in Lagrangian Hessian.............: 149\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Total number of variables............................: 51\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: variables with only lower bounds: 12\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: variables with lower and upper bounds: 34\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: variables with only upper bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Total number of equality constraints.................: 51\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Total number of inequality constraints...............: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: inequality constraints with only lower bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: inequality constraints with lower and upper bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: inequality constraints with only upper bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 0 0.0000000e+00 3.62e+06 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Reallocating memory for MA57: lfact (3323)\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 1 0.0000000e+00 3.00e+06 1.18e+02 -1.0 3.71e+04 - 5.00e-01 1.73e-01h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 2 0.0000000e+00 2.99e+06 3.06e+03 -1.0 2.81e+04 - 8.76e-01 3.30e-03h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 3 0.0000000e+00 2.99e+06 8.95e+07 -1.0 2.80e+04 - 9.79e-01 3.34e-05h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 4r 0.0000000e+00 2.99e+06 1.00e+03 1.9 0.00e+00 - 0.00e+00 1.74e-07R 2\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 5r 0.0000000e+00 2.93e+06 9.98e+02 1.9 3.19e+04 - 2.43e-03 2.43e-03f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 6r 0.0000000e+00 2.86e+06 1.02e+03 1.2 3.69e+02 - 3.26e-01 2.09e-03f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 7r 0.0000000e+00 2.23e+06 1.04e+03 1.2 2.85e+02 - 1.93e-01 8.65e-02f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 8r 0.0000000e+00 1.90e+06 1.12e+05 1.2 2.94e+02 - 7.31e-02 2.42e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 9r 0.0000000e+00 1.44e+06 7.08e+04 1.2 1.51e+02 - 7.79e-01 2.13e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 10r 0.0000000e+00 1.21e+06 3.79e+04 1.2 1.60e+00 2.0 4.46e-01 1.46e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 11r 0.0000000e+00 7.63e+04 1.14e+04 1.2 9.97e+01 - 3.46e-01 9.00e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 12r 0.0000000e+00 4.57e+04 2.79e+04 1.2 8.49e+01 - 1.00e+00 2.61e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 13r 0.0000000e+00 5.79e+04 9.55e+03 1.2 3.35e+01 - 1.00e+00 7.44e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 14r 0.0000000e+00 1.21e+05 1.45e+04 1.2 2.11e+01 - 1.00e+00 1.00e+00h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 15r 0.0000000e+00 2.24e+05 6.34e+02 1.2 7.86e+00 - 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 16r 0.0000000e+00 2.19e+05 4.22e+03 0.5 1.77e+00 - 1.00e+00 9.43e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 17r 0.0000000e+00 3.93e+05 6.53e+02 0.5 1.02e+02 - 5.02e-01 4.46e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 18r 0.0000000e+00 4.24e+05 4.17e+03 0.5 1.55e+01 - 1.00e+00 2.17e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 19r 0.0000000e+00 4.87e+05 1.47e+01 0.5 7.37e+00 - 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 20r 0.0000000e+00 5.23e+05 2.31e+03 -0.9 1.53e+00 - 9.40e-01 7.50e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 21r 0.0000000e+00 5.39e+05 7.30e+03 -0.9 2.08e+02 - 8.07e-01 3.86e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 22r 0.0000000e+00 5.39e+05 5.05e+03 -0.9 1.37e+02 - 1.00e+00 4.43e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 23r 0.0000000e+00 5.38e+05 7.93e+00 -0.9 7.27e+01 - 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 24r 0.0000000e+00 5.39e+05 1.75e-03 -0.9 2.41e-01 - 1.00e+00 1.00e+00h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 25r 0.0000000e+00 5.44e+05 2.59e+01 -3.6 3.79e+00 - 9.90e-01 9.73e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 26r 0.0000000e+00 4.44e+05 3.73e+02 -3.6 6.08e+03 - 7.62e-02 6.44e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 27r 0.0000000e+00 3.34e+05 7.09e+02 -3.6 2.85e+03 - 5.42e-02 9.37e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 28r 0.0000000e+00 2.87e+03 9.51e+02 -3.6 1.42e+03 - 1.73e-01 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 29r 0.0000000e+00 8.65e+04 2.35e+02 -3.6 1.10e+03 - 1.00e+00 1.00e+00H 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 30r 0.0000000e+00 8.28e+04 4.88e-01 -3.6 1.19e+02 - 1.00e+00 1.00e+00h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 31r 0.0000000e+00 8.28e+04 9.25e-05 -3.6 2.69e-01 - 1.00e+00 1.00e+00h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 32r 0.0000000e+00 8.28e+04 2.10e+00 -5.4 5.64e-02 - 1.00e+00 9.70e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 33r 0.0000000e+00 8.28e+04 2.49e+02 -5.4 1.00e-03 1.5 8.85e-01 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 34r 0.0000000e+00 8.27e+04 3.33e-02 -5.4 3.00e-03 1.0 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 35r 0.0000000e+00 8.27e+04 3.31e-02 -5.4 8.93e-03 0.6 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 36r 0.0000000e+00 8.26e+04 3.24e-02 -5.4 2.63e-02 0.1 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 37r 0.0000000e+00 8.23e+04 3.06e-02 -5.4 7.43e-02 -0.4 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 38r 0.0000000e+00 8.16e+04 2.59e-02 -5.4 1.89e-01 -0.9 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 39r 0.0000000e+00 8.02e+04 4.92e-02 -5.4 3.67e-01 -1.3 1.00e+00 1.00e+00h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 40r 0.0000000e+00 7.85e+04 6.76e-02 -5.4 1.01e+00 -1.8 1.00e+00 1.00e+00h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 41r 0.0000000e+00 7.76e+04 2.21e-02 -5.4 3.03e+00 -2.3 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 42r 0.0000000e+00 7.73e+04 1.54e-02 -5.4 9.07e+00 -2.8 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 43r 0.0000000e+00 7.69e+04 1.54e-02 -5.4 2.72e+01 -3.2 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 44r 0.0000000e+00 7.57e+04 9.45e-02 -5.4 8.16e+01 -3.7 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 45r 0.0000000e+00 7.21e+04 7.98e-01 -5.4 2.45e+02 -4.2 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 46r 0.0000000e+00 6.17e+04 5.91e+00 -5.4 7.40e+02 -4.7 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 47r 0.0000000e+00 3.69e+04 5.13e+01 -5.4 2.31e+03 -5.2 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 48r 0.0000000e+00 7.15e+04 1.47e+02 -5.4 1.10e+04 -5.6 1.00e+00 2.17e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 49r 0.0000000e+00 7.15e+04 4.98e+02 -5.4 4.07e+03 -5.2 1.00e+00 5.56e-06h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 50r 0.0000000e+00 2.07e+05 4.58e+03 -5.4 2.01e+04 -5.7 4.61e-01 1.75e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 51r 0.0000000e+00 1.19e+06 4.31e+04 -5.4 9.31e+03 -5.3 2.11e-06 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 52r 0.0000000e+00 1.16e+06 3.63e+04 -5.4 1.14e+02 -0.3 4.01e-01 1.23e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 53r 0.0000000e+00 1.16e+06 3.63e+04 -5.4 2.83e+01 0.1 7.36e-01 7.74e-07h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 54r 0.0000000e+00 1.16e+06 3.63e+04 -5.4 3.94e+03 - 1.59e-01 7.41e-06h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 55r 0.0000000e+00 7.95e+05 2.50e+04 -5.4 4.00e+03 - 7.84e-01 3.17e-01h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 56r 0.0000000e+00 3.83e+05 1.19e+04 -5.4 1.69e+03 - 1.35e-05 5.23e-01h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 57r 0.0000000e+00 2.95e+05 9.19e+03 -5.4 9.94e+00 -0.4 5.56e-01 2.31e-01h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 58r 0.0000000e+00 1.29e+04 7.45e+02 -5.4 1.55e+03 - 2.88e-06 1.00e+00h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 59r 0.0000000e+00 1.05e+04 3.57e+00 -5.4 8.95e-02 -0.8 1.00e+00 1.00e+00h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 60r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 7.60e-02 -1.3 1.00e+00 1.00e+00h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 61r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 2.28e-01 -1.8 1.00e+00 2.50e-01h 3\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 62r 0.0000000e+00 1.05e+04 1.03e-02 -5.4 6.84e-01 -2.3 1.00e+00 1.56e-02h 7\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 63r 0.0000000e+00 1.05e+04 3.12e-02 -5.4 2.05e+00 -2.8 1.00e+00 9.77e-04h 11\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 64r 0.0000000e+00 1.05e+04 9.35e-02 -5.4 6.16e+00 -3.2 1.00e+00 1.22e-04h 14\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 65r 0.0000000e+00 1.05e+04 2.81e-01 -5.4 1.85e+01 -3.7 1.00e+00 7.45e-09h 28\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 66r 0.0000000e+00 1.05e+04 8.49e-01 -5.4 5.60e+01 -4.2 1.00e+00 1.86e-09h 30\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 67r 0.0000000e+00 1.05e+04 2.61e+00 -5.4 1.72e+02 -4.7 1.00e+00 1.16e-10h 34\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 68r 0.0000000e+00 1.05e+04 8.40e+00 -5.4 5.54e+02 -5.1 1.00e+00 3.64e-12h 39\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 69r 0.0000000e+00 1.05e+04 8.40e+00 -5.4 2.14e+03 -5.6 0.00e+00 3.59e-18R 58\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 70r 0.0000000e+00 1.05e+04 1.94e+01 -5.4 4.50e+04 -6.1 1.63e-02 1.43e-12f 35\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 71r 0.0000000e+00 1.05e+04 3.85e+01 -5.4 2.54e+03 -5.7 1.00e+00 1.27e-11f 36\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 72r 0.0000000e+00 1.05e+04 1.11e+01 -5.4 7.22e+02 -5.2 9.93e-01 2.91e-11f 36\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 73r 0.0000000e+00 1.05e+04 3.70e+01 -5.4 3.05e+03 -5.7 7.35e-01 1.32e-12f 39\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 74r 0.0000000e+00 1.05e+04 1.25e+01 -5.4 8.27e+02 -5.3 1.00e+00 3.64e-12f 39\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 75r 0.0000000e+00 1.05e+04 3.60e+01 -5.4 3.72e+03 -5.8 5.36e-01 1.35e-13f 42\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 76r 0.0000000e+00 1.05e+04 1.44e+01 -5.4 9.51e+02 -5.3 1.00e+00 1.14e-13f 44\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 77r 0.0000000e+00 1.05e+04 2.35e+01 -5.4 4.61e+03 -5.8 1.64e-01 1.36e-14f 45\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 78r 0.0000000e+00 1.05e+04 1.66e+01 -5.4 1.10e+03 -5.4 1.00e+00 3.55e-15f 49\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 79r 0.0000000e+00 1.05e+04 2.55e+01 -5.4 5.86e+03 -5.9 1.22e-01 3.35e-16f 50\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 80r 0.0000000e+00 2.67e+04 5.84e+01 -5.4 1.27e+03 -5.4 1.00e+00 8.72e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 81r 0.0000000e+00 2.67e+04 2.19e+03 -5.4 1.28e+03 - 4.11e-03 2.62e-05w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 82r 0.0000000e+00 4.42e+04 8.23e+02 -5.4 3.84e+03 -5.9 5.02e-01 4.78e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 83r 0.0000000e+00 1.05e+04 1.92e+01 -5.4 1.21e+04 - 1.00e+00 7.74e-16f 50\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 84r 0.0000000e+00 1.05e+04 2.07e+01 -5.4 1.47e+03 -5.5 4.87e-01 3.33e-16h 52\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 85r 0.0000000e+00 1.05e+04 5.09e+01 -5.4 1.08e+04 -6.0 2.11e-01 1.14e-17f 54\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 86r 0.0000000e+00 1.05e+04 6.78e+01 -5.4 1.72e+03 -5.5 1.00e+00 1.78e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 87r 0.0000000e+00 1.05e+04 1.11e+02 -5.4 1.65e+04 -6.0 4.54e-02 1.86e-18f 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 88r 0.0000000e+00 1.05e+04 2.03e+02 -5.4 2.02e+03 -5.6 1.00e+00 1.52e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 89r 0.0000000e+00 1.05e+04 3.30e+02 -5.4 3.06e+04 -6.1 2.34e-02 1.00e-18f 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 90r 0.0000000e+00 1.05e+04 7.12e+02 -5.4 2.38e+03 -5.7 1.00e+00 1.29e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 91r 0.0000000e+00 1.05e+04 7.29e+02 -5.4 9.01e+04 -6.1 3.00e-04 3.41e-19f 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 92r 0.0000000e+00 1.05e+04 3.99e+01 -5.4 2.95e+03 -5.7 3.70e-01 2.84e-18h 59\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 93r 0.0000000e+00 2.20e+04 3.07e+01 -5.4 7.91e+02 -5.3 1.00e+00 1.00e+00w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 94r 0.0000000e+00 3.01e+04 4.20e+01 -5.4 2.61e+03 -5.8 7.22e-01 2.55e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 95r 0.0000000e+00 3.01e+04 1.37e+03 -5.4 1.07e+03 - 1.99e-03 3.17e-05w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 96r 0.0000000e+00 1.05e+04 1.20e+01 -5.4 7.00e+03 -6.2 1.00e+00 1.78e-15h 49\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 97r 0.0000000e+00 1.05e+04 2.31e+01 -5.4 4.29e+03 -5.8 2.10e-01 6.00e-11f 33\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 98r 0.0000000e+00 1.05e+04 1.59e+01 -5.4 1.05e+03 -5.4 1.00e+00 7.28e-12f 38\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 99r 0.0000000e+00 1.05e+04 2.46e+01 -5.4 5.40e+03 -5.9 1.33e-01 4.76e-11f 33\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 100r 0.0000000e+00 1.05e+04 1.83e+01 -5.4 1.21e+03 -5.4 1.00e+00 1.07e-10f 34\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 101r 0.0000000e+00 1.05e+04 2.73e+01 -5.4 7.03e+03 -5.9 1.02e-01 3.66e-11f 33\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 102r 0.0000000e+00 1.05e+04 2.77e+01 -5.4 1.40e+03 -5.5 1.00e+00 1.43e-12f 40\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 103r 0.0000000e+00 1.05e+04 4.37e+01 -5.4 9.60e+03 -6.0 7.47e-02 5.24e-14f 42\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 104r 0.0000000e+00 1.05e+04 6.49e+01 -5.4 1.63e+03 -5.5 1.00e+00 7.69e-14f 44\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 105r 0.0000000e+00 1.05e+04 1.04e+02 -5.4 1.42e+04 -6.0 5.06e-02 1.11e-15f 47\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 106r 0.0000000e+00 2.67e+04 1.58e+01 -5.4 1.91e+03 -5.6 1.00e+00 5.77e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 107r 0.0000000e+00 2.67e+04 1.40e+03 -5.4 9.67e+02 - 2.90e-03 3.66e-04w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 108r 0.0000000e+00 4.39e+04 4.78e+02 -5.4 5.57e+03 -6.1 3.84e-01 3.25e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 109r 0.0000000e+00 1.05e+04 1.80e+02 -5.4 6.38e+03 - 1.00e+00 4.10e-15f 47\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 110r 0.0000000e+00 1.05e+04 2.40e+02 -5.4 2.26e+03 -5.6 3.17e-01 3.47e-15f 48\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 111r 0.0000000e+00 1.05e+04 5.44e+02 -5.4 6.90e+04 -6.1 2.06e-02 1.14e-16f 48\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 112r 0.0000000e+00 1.05e+04 4.95e+01 -5.4 2.79e+03 -5.7 2.55e-01 7.69e-16f 51\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 113r 0.0000000e+00 1.05e+04 1.15e+01 -5.4 7.57e+02 -5.3 1.00e+00 7.11e-15f 48\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 114r 0.0000000e+00 1.05e+04 2.06e+01 -5.4 3.26e+03 -5.7 2.41e-01 6.02e-16f 50\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 115r 0.0000000e+00 1.05e+04 1.32e+01 -5.4 8.68e+02 -5.3 1.00e+00 2.22e-16h 53\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 116r 0.0000000e+00 1.05e+04 2.17e+01 -5.4 3.99e+03 -5.8 1.79e-01 3.07e-17h 54\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 117r 0.0000000e+00 1.05e+04 1.51e+01 -5.4 9.98e+02 -5.4 1.00e+00 2.78e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 118r 0.0000000e+00 1.05e+04 2.38e+01 -5.4 4.99e+03 -5.8 1.44e-01 6.14e-18h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 119r 0.0000000e+00 2.67e+04 5.98e+01 -5.4 1.15e+03 -5.4 1.00e+00 9.60e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 120r 0.0000000e+00 2.67e+04 2.31e+03 -5.4 1.66e+03 - 4.25e-03 1.30e-05w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 121r 0.0000000e+00 4.43e+04 8.41e+02 -5.4 3.52e+03 -5.9 5.33e-01 5.24e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 122r 0.0000000e+00 1.05e+04 1.75e+01 -5.4 1.31e+04 - 1.00e+00 2.66e-17h 55\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 123r 0.0000000e+00 1.05e+04 1.89e+01 -5.4 1.33e+03 -5.5 5.38e-01 2.30e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 124r 0.0000000e+00 1.05e+04 4.92e+01 -5.4 8.61e+03 -5.9 2.71e-01 3.56e-18h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 125r 0.0000000e+00 1.05e+04 2.98e+01 -5.4 1.55e+03 -5.5 1.00e+00 1.98e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 126r 0.0000000e+00 1.05e+04 4.92e+01 -5.4 1.23e+04 -6.0 6.33e-02 2.48e-18h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 127r 0.0000000e+00 1.05e+04 8.12e+01 -5.4 1.82e+03 -5.6 1.00e+00 1.69e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 128r 0.0000000e+00 1.05e+04 1.31e+02 -5.4 2.00e+04 -6.0 3.59e-02 1.53e-18f 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 129r 0.0000000e+00 1.05e+04 2.54e+02 -5.4 2.14e+03 -5.6 1.00e+00 1.43e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 130r 0.0000000e+00 1.05e+04 4.15e+02 -5.4 4.32e+04 -6.1 1.66e-02 7.10e-19f 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 131r 0.0000000e+00 1.05e+04 9.52e+02 -5.4 2.53e+03 -5.7 1.00e+00 1.21e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 132r 0.0000000e+00 2.67e+04 2.24e+01 -5.4 4.51e+05 -6.1 1.18e-04 2.45e-03w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 133r 0.0000000e+00 4.32e+04 1.53e+02 -5.4 4.75e+04 -6.6 3.50e-02 3.68e-02w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 134r 0.0000000e+00 4.32e+04 3.80e+02 -5.4 3.44e+03 - 1.99e-02 3.86e-06w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 135r 0.0000000e+00 1.05e+04 9.98e+02 -5.4 8.04e+02 - 1.18e-04 6.81e-20f 55\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 136r 0.0000000e+00 1.05e+04 2.21e+01 -5.4 8.37e+02 -5.3 6.52e-01 5.55e-17h 55\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 137r 0.0000000e+00 1.05e+04 2.91e+01 -5.4 3.73e+03 -5.8 2.04e-01 8.22e-18h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 138r 0.0000000e+00 1.05e+04 1.45e+01 -5.4 9.53e+02 -5.3 1.00e+00 5.55e-17h 55\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 139r 0.0000000e+00 1.05e+04 2.31e+01 -5.4 4.63e+03 -5.8 1.55e-01 6.62e-18h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 140r 0.0000000e+00 1.05e+04 1.67e+01 -5.4 1.10e+03 -5.4 1.00e+00 2.78e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 141r 0.0000000e+00 1.05e+04 2.55e+01 -5.4 5.89e+03 -5.9 1.22e-01 5.20e-18h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 142r 0.0000000e+00 1.05e+04 1.93e+01 -5.4 1.27e+03 -5.4 1.00e+00 2.41e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 143r 0.0000000e+00 1.05e+04 2.84e+01 -5.4 7.78e+03 -5.9 9.22e-02 3.94e-18h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 144r 0.0000000e+00 1.05e+04 3.40e+01 -5.4 1.48e+03 -5.5 1.00e+00 2.08e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 145r 0.0000000e+00 2.67e+04 4.04e+01 -5.4 1.09e+04 -6.0 6.60e-02 1.02e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 146r 0.0000000e+00 2.67e+04 1.47e+03 -5.4 1.02e+03 - 2.88e-03 1.10e-04w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 147r 0.0000000e+00 4.33e+04 7.00e+02 -5.4 1.97e+04 -6.5 1.24e-01 8.93e-02w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 148r 0.0000000e+00 1.05e+04 5.40e+01 -5.4 6.24e+03 - 6.60e-02 2.82e-18h 55\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 149r 0.0000000e+00 1.05e+04 1.51e+02 -5.4 1.68e+04 -6.0 1.26e-01 1.83e-18h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 150r 0.0000000e+00 1.05e+04 5.58e+01 -5.4 2.10e+03 -5.6 1.51e-01 9.25e-19h 60\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 151r 0.0000000e+00 1.05e+04 6.31e+01 -5.4 3.28e+04 -6.1 1.66e-02 9.36e-19f 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 152r 0.0000000e+00 1.05e+04 6.32e+01 -5.4 3.63e+03 -5.7 8.61e-03 1.56e-18h 54\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 153r 0.0000000e+00 1.05e+04 6.33e+01 -5.4 2.10e+05 -6.1 1.98e-05 1.48e-19f 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 154r 0.0000000e+00 1.05e+04 8.87e-01 -5.4 1.46e-02 -0.3 1.00e+00 1.43e-06h 4\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 155r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 2.09e-02 -0.8 1.00e+00 5.00e-01f 2\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 156r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 6.26e-02 -1.2 1.00e+00 2.44e-04h 13\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 157r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 1.88e-01 -1.7 1.00e+00 1.53e-05h 17\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 158r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 5.64e-01 -2.2 1.00e+00 1.00e+00w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 159r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 1.69e+00 -2.7 1.00e+00 1.00e+00w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 160r 0.0000000e+00 1.06e+04 3.62e-03 -5.4 5.08e+00 -3.1 1.00e+00 1.00e+00w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 161r 0.0000000e+00 1.05e+04 8.60e-03 -5.4 1.53e+01 -3.6 1.00e+00 7.45e-09h 27\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 162r 0.0000000e+00 1.05e+04 6.99e-01 -5.4 4.61e+01 -4.1 1.00e+00 1.14e-13h 44\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 163r 0.0000000e+00 1.05e+04 2.14e+00 -5.4 1.41e+02 -4.6 1.00e+00 2.84e-14h 46\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 164r 0.0000000e+00 1.05e+04 6.79e+00 -5.4 4.48e+02 -5.1 1.00e+00 4.66e-10f 32\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 165r 0.0000000e+00 1.05e+04 2.13e+01 -5.4 1.64e+03 -5.5 8.03e-01 1.96e-11f 36\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 166r 0.0000000e+00 1.05e+04 5.45e+01 -5.4 1.44e+04 -6.0 1.69e-01 5.60e-13f 38\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 167r 0.0000000e+00 1.05e+04 2.91e+01 -5.4 1.92e+03 -5.6 1.00e+00 1.31e-13f 43\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 168r 0.0000000e+00 1.05e+04 3.94e+01 -5.4 2.52e+04 -6.1 2.91e-02 3.11e-16f 48\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 169r 0.0000000e+00 1.05e+04 3.44e+01 -5.4 2.27e+03 -5.6 1.00e+00 3.46e-15h 48\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 170r 0.0000000e+00 1.05e+04 4.50e+01 -5.4 7.69e+04 -6.1 9.32e-03 1.28e-17f 51\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 171r 0.0000000e+00 2.67e+04 3.33e+01 -5.4 2.71e+03 -5.7 1.00e+00 4.08e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 172r 0.0000000e+00 2.67e+04 9.73e+02 -5.4 1.12e+03 - 1.93e-03 9.14e-05w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 173r 0.0000000e+00 4.37e+04 5.94e+02 -5.4 7.46e+03 -6.2 2.29e-01 2.40e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 174r 0.0000000e+00 1.05e+04 4.51e+01 -5.4 3.87e+03 - 1.00e+00 2.97e-12f 37\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 175r 0.0000000e+00 1.05e+04 6.47e+01 -5.4 3.27e+03 -5.7 2.19e-01 7.69e-14f 43\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 176r 0.0000000e+00 1.05e+04 5.10e+01 -5.4 8.69e+02 -5.3 1.00e+00 1.14e-13h 44\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 177r 0.0000000e+00 1.05e+04 7.51e+01 -5.4 4.00e+03 -5.8 1.79e-01 6.43e-11f 33\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 178r 0.0000000e+00 1.05e+04 6.82e+01 -5.4 1.00e+03 -5.4 1.00e+00 4.66e-10f 32\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 179r 0.0000000e+00 1.05e+04 1.03e+02 -5.4 5.00e+03 -5.8 1.43e-01 1.29e-11f 35\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 180r 0.0000000e+00 1.05e+04 1.08e+02 -5.4 1.15e+03 -5.4 1.00e+00 1.39e-11f 37\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 181r 0.0000000e+00 1.05e+04 1.65e+02 -5.4 6.42e+03 -5.9 1.12e-01 5.01e-12f 36\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 182r 0.0000000e+00 1.05e+04 2.00e+02 -5.4 1.34e+03 -5.5 1.00e+00 1.20e-11f 37\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 183r 0.0000000e+00 1.05e+04 3.13e+02 -5.4 8.54e+03 -5.9 8.39e-02 9.41e-13f 38\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 184r 0.0000000e+00 2.67e+04 6.63e+01 -5.4 1.55e+03 -5.5 1.00e+00 7.13e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 185r 0.0000000e+00 2.67e+04 8.09e+02 -5.4 1.01e+03 - 2.25e-03 8.90e-04w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 186r 0.0000000e+00 4.40e+04 1.17e+02 -5.4 4.65e+03 -6.0 4.39e-01 3.92e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 187r 0.0000000e+00 1.05e+04 4.40e+02 -5.4 8.89e+03 - 1.00e+00 2.07e-11f 35\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 188r 0.0000000e+00 1.05e+04 5.51e+02 -5.4 1.81e+03 -5.6 3.96e-01 8.88e-12f 37\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 189r 0.0000000e+00 1.05e+04 8.25e+02 -5.4 1.87e+04 -6.0 3.12e-02 1.08e-13f 40\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 190r 0.0000000e+00 1.05e+04 3.35e+01 -5.4 2.20e+03 -5.6 4.67e-01 2.27e-13f 43\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 191r 0.0000000e+00 1.05e+04 4.40e+01 -5.4 4.69e+04 -6.1 1.56e-02 5.36e-15f 43\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 192r 0.0000000e+00 1.05e+04 3.87e+01 -5.4 2.56e+03 -5.7 1.00e+00 2.46e-14f 45\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 193r 0.0000000e+00 1.05e+04 1.92e+01 -5.4 7.26e+02 -5.2 9.88e-01 1.14e-13h 44\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 194r 0.0000000e+00 1.05e+04 4.68e+01 -5.4 3.07e+03 -5.7 7.96e-01 1.68e-10f 32\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 195r 0.0000000e+00 1.05e+04 3.54e+01 -5.4 8.31e+02 -5.3 1.00e+00 5.82e-11f 35\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 196r 0.0000000e+00 1.05e+04 8.07e+01 -5.4 3.74e+03 -5.8 5.32e-01 6.87e-11f 33\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 197r 0.0000000e+00 2.44e+04 4.51e+01 -5.4 9.55e+02 -5.3 1.00e+00 1.00e+00w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 198r 0.0000000e+00 2.90e+04 1.83e+02 -5.4 3.03e+03 -5.8 6.02e-01 1.26e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 199r 0.0000000e+00 2.90e+04 3.65e+02 -5.4 1.03e+03 - 1.58e-03 1.30e-03w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 200r 0.0000000e+00 1.05e+04 6.99e+01 -5.4 9.09e+03 -6.3 1.00e+00 2.91e-11f 35\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of Iterations....: 200\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: (scaled) (unscaled)\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Dual infeasibility......: 6.9908071367141474e+01 6.9908071367141474e+01\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Constraint violation....: 2.8645094423111342e-03 1.0458847092153306e+04\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Complementarity.........: 1.3579265591895737e-03 1.3579265591895737e-03\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Overall NLP error.......: 2.8645094423111342e-03 1.0458847092153306e+04\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of objective function evaluations = 5209\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of objective gradient evaluations = 6\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of equality constraint evaluations = 5210\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of inequality constraint evaluations = 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of equality constraint Jacobian evaluations = 203\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of inequality constraint Jacobian evaluations = 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of Lagrangian Hessian evaluations = 200\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Total CPU secs in IPOPT (w/o function evaluations) = 0.176\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Total CPU secs in NLP function evaluations = 0.014\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: EXIT: Maximum Number of Iterations Exceeded.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit: Initialization Step 3 maxIterations - .\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit: Initialization Complete: maxIterations - \n", + "Initialization failed.\n" + ] + } + ], + "source": [ + "import logging\n", + "from pyomo.environ import (\n", + " ComponentMap,\n", + " ConcreteModel,\n", + " Constraint,\n", + " exp,\n", + " Param,\n", + " Reference,\n", + " units as pyunits,\n", + " value,\n", + ")\n", + "\n", + "from idaes.core import (\n", + " ControlVolume0DBlock,\n", + " FlowsheetBlock,\n", + " MaterialFlowBasis,\n", + " MomentumBalanceType,\n", + ")\n", + "import idaes.logger as idaeslog\n", + "from idaes.core.scaling.util import get_scaling_factor\n", + "from idaes.core.util.exceptions import ConfigurationError, InitializationError\n", + "\n", + "from idaes.models.properties.modular_properties.base.generic_property import (\n", + " GenericParameterBlock,\n", + ")\n", + "\n", + "from idaes.models_extra.column_models.solvent_reboiler import SolventReboiler\n", + "from idaes.models_extra.column_models.properties.MEA_solvent import (\n", + " configuration as aqueous_mea,\n", + ")\n", + "from idaes.models_extra.column_models.properties.MEA_vapor import flue_gas\n", + "\n", + "logging.getLogger(\"pyomo.repn.plugins.nl_writer\").setLevel(logging.ERROR)\n", + "\n", + "\n", + "def create_model():\n", + " m = ConcreteModel()\n", + " m.fs = FlowsheetBlock(dynamic=False)\n", + "\n", + " m.fs.liquid_properties = GenericParameterBlock(**aqueous_mea)\n", + " m.fs.vapor_properties = GenericParameterBlock(**flue_gas)\n", + "\n", + " m.fs.unit = SolventReboiler(\n", + " liquid_property_package=m.fs.liquid_properties,\n", + " vapor_property_package=m.fs.vapor_properties,\n", + " )\n", + "\n", + " m.fs.unit.inlet.flow_mol[0].fix(83.89)\n", + " m.fs.unit.inlet.temperature[0].fix(392.5)\n", + " m.fs.unit.inlet.pressure[0].fix(183700)\n", + " m.fs.unit.inlet.mole_frac_comp[0, \"CO2\"].fix(0.0326)\n", + " m.fs.unit.inlet.mole_frac_comp[0, \"H2O\"].fix(0.8589)\n", + " m.fs.unit.inlet.mole_frac_comp[0, \"MEA\"].fix(0.1085)\n", + "\n", + " m.fs.unit.heat_duty.fix(430.61e3)\n", + " return m\n", + "\n", + "\n", + "if __name__ == \"__main__\":\n", + " m = create_model()\n", + "\n", + " reboiler_init = m.fs.unit.default_initializer(always_estimate_states=True)\n", + " try:\n", + " reboiler_init.initialize(m.fs.unit, output_level=idaeslog.DEBUG)\n", + " except InitializationError:\n", + " print(\"Initialization failed.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Step 2: Run Model Diagnostics\n", + "\n", + "We see that the unit model failed to initialize. When confronted with a bad solution state, we should first use the `DiagnosticsToolbox` to check to see if there are structural issues with the model." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "====================================================================================\n", + "Model Statistics\n", + "\n", + " Activated Blocks: 23 (Deactivated: 0)\n", + " Free Variables in Activated Constraints: 77 (External: 0)\n", + " Free Variables with only lower bounds: 15\n", + " Free Variables with only upper bounds: 0\n", + " Free Variables with upper and lower bounds: 50\n", + " Fixed Variables in Activated Constraints: 66 (External: 0)\n", + " Activated Equality Constraints: 77 (Deactivated: 0)\n", + " Activated Inequality Constraints: 0 (Deactivated: 0)\n", + " Activated Objectives: 0 (Deactivated: 0)\n", + "\n", + "------------------------------------------------------------------------------------\n", + "1 WARNINGS\n", + "\n", + " WARNING: Found 9 potential evaluation errors.\n", + "\n", + "------------------------------------------------------------------------------------\n", + "2 Cautions\n", + "\n", + " Caution: 11 variables fixed to 0\n", + " Caution: 82 unused variables (82 fixed)\n", + "\n", + "------------------------------------------------------------------------------------\n", + "Suggested next steps:\n", + "\n", + " display_potential_evaluation_errors()\n", + "\n", + "====================================================================================\n" + ] + } + ], + "source": [ + "from idaes.core.util import DiagnosticsToolbox\n", + "\n", + "dt = DiagnosticsToolbox(m)\n", + "dt.report_structural_issues()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The density relationship is being flagged for potential evaluation errors. The interval arithmetic used to identify potential evaluation errors can produce relatively loose bounds, especially for the sort of large polynomial expressions favored in the literature. Independent testing of the density relationship over a wide range of values has demonstrated that no evaluation errors occur, so we can ignore these warnings.\n", + "\n", + "The next step is determining which numerical issues exist." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "====================================================================================\n", + "Model Statistics\n", + "\n", + " Jacobian Condition Number: 2.718E+13\n", + "\n", + "------------------------------------------------------------------------------------\n", + "3 WARNINGS\n", + "\n", + " WARNING: 3 Constraints with large residuals (>1.0E-05)\n", + " WARNING: 1 Variable with extreme Jacobian column norms (<1.0E-08 or >1.0E+08)\n", + " WARNING: 1 Constraint with extreme Jacobian row norms (<1.0E-08 or >1.0E+08)\n", + "\n", + "------------------------------------------------------------------------------------\n", + "8 Cautions\n", + "\n", + " Caution: 9 Variables with value close to their bounds (abs=1.0E-04, rel=1.0E-04)\n", + " Caution: 18 Variables with value close to zero (tol=1.0E-08)\n", + " Caution: 30 Variables with extreme value (<1.0E-04 or >1.0E+04)\n", + " Caution: 2 Constraints with mismatched terms\n", + " Caution: 1 Constraint with potential cancellation of terms\n", + " Caution: 27 Variables with extreme Jacobian column norms (<1.0E-04 or >1.0E+04)\n", + " Caution: 16 Constraints with extreme Jacobian row norms (<1.0E-04 or >1.0E+04)\n", + " Caution: 50 extreme Jacobian Entries (<1.0E-04 or >1.0E+04)\n", + "\n", + "------------------------------------------------------------------------------------\n", + "Suggested next steps:\n", + "\n", + " display_constraints_with_large_residuals()\n", + " compute_infeasibility_explanation()\n", + " display_variables_with_extreme_jacobians()\n", + " display_constraints_with_extreme_jacobians()\n", + "\n", + "====================================================================================\n" + ] + } + ], + "source": [ + "dt.report_numerical_issues()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In order to help interpret this output, we need to review the solution of systems of nonlinear equations.\n", + "\n", + "When we try to solve a square problem (i.e., a problem with zero degrees of freedom) using IPOPT, we are asking it to solve an equation of the form\n", + "$$\n", + "\\mathbf{f}(\\mathbf{x}) = \\mathbf{0}\n", + "$$\n", + "in which $\\mathbf{f}(\\cdot)$ is a vector-valued function of length $n$, and $\\mathbf{x}$ is a vector also of length $n$. Due to the finite accuracy of floating point arithmetic, the most we can ask for is $||\\mathbf{f}(\\mathbf{x})|| < \\varepsilon$, for some small value of $\\varepsilon$. The IDAES default solver configuration sets $\\varepsilon = 10^{-6}$. For some constraint $j$, the value of $f_j(x_k)$ is the called its *residual*, i.e., the remaining error in constraint satisfaction. IPOPT displays the infinity norm of the constraint residual,\n", + "$$\n", + "\\lvert\\lvert \\mathbf{f}(\\mathbf{x}_k)\\rvert\\rvert_{\\infty} := \\max_j \\lvert f_j(\\mathbf{x}_k)\\rvert\n", + "$$\n", + "i.e., the constraint residual with largest magnitude, for each step $k$ in the primal infeasibility (`inf_pr`) column.\n", + "\n", + "Problems of this form are typically solved with some variation on Newton's method. We denote the Jacobian matrix for function $\\mathbf{f}(\\mathbf{x})$ as\n", + "$$\n", + "\\mathbf{J}(\\mathbf{x}) := \\begin{bmatrix}\n", + " \\frac{\\partial f_1}{\\partial x_1} & \\dots & \\frac{\\partial f_1}{\\partial x_n} \\\\\n", + " \\vdots & \\ddots & \\vdots \\\\\n", + " \\frac{\\partial f_n}{\\partial x_1} & \\dots & \\frac{\\partial f_n}{\\partial x_n}\n", + "\\end{bmatrix}\n", + "$$\n", + "Note that each row of $\\mathbf{J}(\\cdot)$ is associated with a constraint and every column is associated with a variable.\n", + "\n", + "In the classical form of Newton's method, we start with an initial guess $\\mathbf{x}_0$, then iterate using the relationship\n", + "\n", + "\\begin{align}\n", + "\\mathbf{J}(\\mathbf{x}_k)\\cdot\\mathbf{\\delta x}_k &= -\\mathbf{f}(\\mathbf{x}_k) \\\\\n", + "\\mathbf{x}_{k+1} &= \\mathbf{x}_k + \\mathbf{\\delta x}_k\n", + "\\end{align}\n", + "\n", + "IPOPT incorporates additional features, such as a line search, in order to enhance its robustness to bad initial guesses, but it is designed to take full Newton steps in the neighborhood of a solution (for the full details, refer to [W\u00e4chter and Biegler (2006)](#references)).\n", + "\n", + "The condition number $\\kappa_2(\\cdot)$ (for the Euclidean norm) is a worst-case error bound in the solution of a system of linear equations. In this case, we have\n", + "$$\n", + "\\lvert\\lvert\\mathbf{\\delta x}_k\\rvert\\rvert_2 \\leq \\kappa(\\mathbf{J}(\\mathbf{x}_k)) \\cdot \\lvert\\lvert \\mathbf{f}(\\mathbf{x}_k)\\rvert\\rvert_2\n", + "$$\n", + "If we terminate under the condition $||\\mathbf{f}(\\mathbf{x}_f)||_2 < \\varepsilon$, then\n", + "$$\n", + "\\lvert\\lvert\\mathbf{\\delta x}_f\\rvert\\rvert_2 \\leq \\kappa(\\mathbf{J}(\\mathbf{x}_f)) \\cdot \\varepsilon\n", + "$$\n", + "With a condition number on the order of $10^{13}$ and the default tolerance $\\varepsilon = 10^{-6}$, then the difference between the computed solution $x_f$ and the true solution $x$ could be on the order of $10^7$.\n", + "\n", + "In practice, however, we frequently end up with much better results than those predicted by this worst-case bound. Frequently, we find that most constraints have residuals on the order of $10^{-10}$ or less, with a few problematic constraints having larger residuals. That is the case here." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Number of constraints: 77\n", + "====================================================================================\n", + "The following constraint(s) have large residuals (>1.0E-10):\n", + "\n", + " fs.unit.unit_material_balance[0.0,CO2]: 1.84866E-10\n", + " fs.unit.unit_material_balance[0.0,N2]: 1.89950E-10\n", + " fs.unit.unit_material_balance[0.0,O2]: 1.87656E-10\n", + " fs.unit.unit_phase_equilibrium[0.0,CO2]: 1.04588E+04\n", + " fs.unit.unit_phase_equilibrium[0.0,H2O]: 8.88278E-07\n", + " fs.unit.unit_enthalpy_balance[0.0]: 5.05679E-10\n", + " fs.unit.liquid_phase.material_balances[0.0,CO2]: 1.70459E-10\n", + " fs.unit.liquid_phase.enthalpy_balances[0.0]: 1.17285E-05\n", + " fs.unit.liquid_phase.properties_out[0.0].sum_mole_frac_out: 2.08134E-10\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-]: 8.83857E-06\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]: 1.54414E-07\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA_+]: 7.69821E-06\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,H2O]: 2.50511E-08\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA]: 4.55346E-06\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2]: 4.42749E-05\n", + " fs.unit.vapor_phase[0.0].sum_mole_frac_out: 1.71144E-10\n", + "\n", + "====================================================================================\n" + ] + } + ], + "source": [ + "import idaes.core.util.model_statistics as mstat\n", + "\n", + "print(f\"Number of constraints: {mstat.number_activated_constraints(m)}\")\n", + "dt.config.constraint_residual_tolerance = 1e-10\n", + "dt.display_constraints_with_large_residuals()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Even with a non-optimal termination, we have only three constraints with residuals greater than $10^{-5}$ for a model with 77 active constraints. Two of those constraints are on the order of $10^{-5}$, but the third is on the order of $10^4$.\n", + "\n", + "Nevertheless, a condition number on the order of $10^{13}$ is significantly higher than we'd like, because large condition numbers can degrade the convergence of Newton's method or even prevent it from converging entirely. Ideally, we want flowsheets to have condition numbers less than $10^8$. Connecting unit models together with things like recycle streams can amplify the overall flowsheet condition number to be multiple orders of magnitude greater than that of its individual components. Consequently, we want unit models to have condition numbers less than $10^4$.\n", + "\n", + "Model scaling can both reduce the Jacobian's condition number and help ensure that constraints are satisfied to an appropriate precision. Both of those effects can help the model initialization to converge. Before beginning to write a scaler object, however, we should look at the structure of the unit model." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "def build(self):\n", + " \"\"\"Build the model.\n", + "\n", + " Args:\n", + " None\n", + " Returns:\n", + " None\n", + " \"\"\"\n", + " # Call UnitModel.build to setup dynamics\n", + " super().build()\n", + "\n", + " # Check phase lists match assumptions\n", + " if self.config.vapor_property_package.phase_list != [\"Vap\"]:\n", + " raise ConfigurationError(\n", + " f\"{self.name} SolventReboiler model requires that the vapor \"\n", + " f\"phase property package have a single phase named 'Vap'\"\n", + " )\n", + " if self.config.liquid_property_package.phase_list != [\"Liq\"]:\n", + " raise ConfigurationError(\n", + " f\"{self.name} SolventReboiler model requires that the liquid \"\n", + " f\"phase property package have a single phase named 'Liq'\"\n", + " )\n", + "\n", + " # Check for at least one common component in component lists\n", + " if not any(\n", + " j in self.config.vapor_property_package.component_list\n", + " for j in self.config.liquid_property_package.component_list\n", + " ):\n", + " raise ConfigurationError(\n", + " f\"{self.name} SolventReboiler model requires that the liquid \"\n", + " f\"and vapor phase property packages have at least one \"\n", + " f\"common component.\"\n", + " )\n", + "\n", + " # ---------------------------------------------------------------------\n", + " # Add Control Volume for the Liquid Phase\n", + " self.liquid_phase = ControlVolume0DBlock(\n", + " dynamic=self.config.dynamic,\n", + " has_holdup=self.config.has_holdup,\n", + " property_package=self.config.liquid_property_package,\n", + " property_package_args=self.config.liquid_property_package_args,\n", + " )\n", + "\n", + " self.liquid_phase.add_state_blocks(has_phase_equilibrium=True)\n", + "\n", + " # Separate liquid and vapor phases means that phase equilibrium will\n", + " # be handled at the unit model level, thus has_phase_equilibrium is\n", + " # False, but has_mass_transfer is True.\n", + " self.liquid_phase.add_material_balances(\n", + " balance_type=self.config.material_balance_type,\n", + " has_mass_transfer=True,\n", + " has_phase_equilibrium=False,\n", + " )\n", + "\n", + " # Need to include enthalpy transfer term for the mass transfer\n", + " self.liquid_phase.add_energy_balances(\n", + " balance_type=self.config.energy_balance_type,\n", + " has_heat_transfer=True,\n", + " has_enthalpy_transfer=True,\n", + " )\n", + "\n", + " self.liquid_phase.add_momentum_balances(\n", + " balance_type=self.config.momentum_balance_type,\n", + " has_pressure_change=self.config.has_pressure_change,\n", + " )\n", + "\n", + " # ---------------------------------------------------------------------\n", + " # Add single state block for vapor phase\n", + " tmp_dict = dict(**self.config.vapor_property_package_args)\n", + " tmp_dict[\"has_phase_equilibrium\"] = False\n", + " tmp_dict[\"defined_state\"] = False\n", + " self.vapor_phase = self.config.vapor_property_package.build_state_block(\n", + " self.flowsheet().time, doc=\"Vapor phase properties\", **tmp_dict\n", + " )\n", + "\n", + " # ---------------------------------------------------------------------\n", + " # Check flow basis is compatible\n", + " t_init = self.flowsheet().time.first()\n", + " if (\n", + " self.vapor_phase[t_init].get_material_flow_basis()\n", + " != self.liquid_phase.properties_out[t_init].get_material_flow_basis()\n", + " ):\n", + " raise ConfigurationError(\n", + " f\"{self.name} vapor and liquid property packages must use the \"\n", + " f\"same material flow basis.\"\n", + " )\n", + "\n", + " # ---------------------------------------------------------------------\n", + " # Add Ports for the reboiler\n", + " self.add_inlet_port(name=\"inlet\", block=self.liquid_phase, doc=\"Liquid feed\")\n", + " self.add_outlet_port(name=\"bottoms\", block=self.liquid_phase, doc=\"Bottoms stream\")\n", + " self.add_outlet_port(\n", + " name=\"vapor_reboil\",\n", + " block=self.vapor_phase,\n", + " doc=\"Vapor stream from reboiler\",\n", + " )\n", + "\n", + " # ---------------------------------------------------------------------\n", + " # Add unit level constraints\n", + " # First, need the union and intersection of component lists\n", + " all_comps = (\n", + " self.vapor_phase.component_list\n", + " | self.liquid_phase.properties_out.component_list\n", + " )\n", + " common_comps = (\n", + " self.vapor_phase.component_list\n", + " & self.liquid_phase.properties_out.component_list\n", + " )\n", + "\n", + " # Get units for unit conversion\n", + " vunits = self.config.vapor_property_package.get_metadata().get_derived_units\n", + " lunits = self.config.liquid_property_package.get_metadata().get_derived_units\n", + " flow_basis = self.vapor_phase[t_init].get_material_flow_basis()\n", + " if flow_basis == MaterialFlowBasis.molar:\n", + " fb = \"flow_mole\"\n", + " elif flow_basis == MaterialFlowBasis.mass:\n", + " fb = \"flow_mass\"\n", + " else:\n", + " raise ConfigurationError(\n", + " f\"{self.name} SolventReboiler only supports mass or molar \"\n", + " f\"basis for MaterialFlowBasis.\"\n", + " )\n", + "\n", + " if any(j not in common_comps for j in self.vapor_phase.component_list):\n", + " # We have non-condensable components present, need zero-flow param\n", + " self.zero_flow_param = Param(\n", + " mutable=True, default=1e-8, units=vunits(\"flow_mole\")\n", + " )\n", + "\n", + " # Material balances\n", + " def rule_material_balance(blk, t, j):\n", + " if j in common_comps:\n", + " # Component is in equilibrium\n", + " # Mass transfer equals vapor flowrate\n", + " return -blk.liquid_phase.mass_transfer_term[t, \"Liq\", j] == pyunits.convert(\n", + " blk.vapor_phase[t].get_material_flow_terms(\"Vap\", j),\n", + " to_units=lunits(fb),\n", + " )\n", + " elif j in self.vapor_phase.component_list:\n", + " # Non-condensable component\n", + " # No mass transfer term\n", + " # Set vapor flowrate to an arbitrary small value\n", + " return (\n", + " blk.vapor_phase[t].get_material_flow_terms(\"Vap\", j)\n", + " == blk.zero_flow_param\n", + " )\n", + " else:\n", + " # Non-vaporisable component\n", + " # Mass transfer term is zero, no vapor flowrate\n", + " return blk.liquid_phase.mass_transfer_term[t, \"Liq\", j] == 0 * lunits(fb)\n", + "\n", + " self.unit_material_balance = Constraint(\n", + " self.flowsheet().time,\n", + " all_comps,\n", + " rule=rule_material_balance,\n", + " doc=\"Unit level material balances\",\n", + " )\n", + "\n", + " # Phase equilibrium constraints\n", + " # For all common components, equate fugacity in vapor and liquid\n", + " def rule_phase_equilibrium(blk, t, j):\n", + " return blk.liquid_phase.properties_out[t].fug_phase_comp[\n", + " \"Liq\", j\n", + " ] == pyunits.convert(\n", + " blk.vapor_phase[t].fug_phase_comp[\"Vap\", j], to_units=lunits(\"pressure\")\n", + " )\n", + "\n", + " self.unit_phase_equilibrium = Constraint(\n", + " self.flowsheet().time,\n", + " common_comps,\n", + " rule=rule_phase_equilibrium,\n", + " doc=\"Unit level phase equilibrium constraints\",\n", + " )\n", + "\n", + " # Temperature equality constraint\n", + " def rule_temperature_balance(blk, t):\n", + " return blk.liquid_phase.properties_out[t].temperature == pyunits.convert(\n", + " blk.vapor_phase[t].temperature, to_units=lunits(\"temperature\")\n", + " )\n", + "\n", + " self.unit_temperature_equality = Constraint(\n", + " self.flowsheet().time,\n", + " rule=rule_temperature_balance,\n", + " doc=\"Unit level temperature equality\",\n", + " )\n", + "\n", + " # Unit level energy balance\n", + " # Energy leaving in vapor phase must be equal and opposite to enthalpy\n", + " # transfer from liquid phase\n", + " def rule_energy_balance(blk, t):\n", + " return -blk.liquid_phase.enthalpy_transfer[t] == pyunits.convert(\n", + " blk.vapor_phase[t].get_enthalpy_flow_terms(\"Vap\"),\n", + " to_units=lunits(\"energy\") / lunits(\"time\"),\n", + " )\n", + "\n", + " self.unit_enthalpy_balance = Constraint(\n", + " self.flowsheet().time,\n", + " rule=rule_energy_balance,\n", + " doc=\"Unit level enthalpy_balance\",\n", + " )\n", + "\n", + " # Pressure balance constraint\n", + " def rule_pressure_balance(blk, t):\n", + " return blk.liquid_phase.properties_out[t].pressure == pyunits.convert(\n", + " blk.vapor_phase[t].pressure, to_units=lunits(\"pressure\")\n", + " )\n", + "\n", + " self.unit_pressure_balance = Constraint(\n", + " self.flowsheet().time,\n", + " rule=rule_pressure_balance,\n", + " doc=\"Unit level pressure balance\",\n", + " )\n", + "\n", + " # Set references to balance terms at unit level\n", + " self.heat_duty = Reference(self.liquid_phase.heat[:])\n", + "\n", + " if (\n", + " self.config.has_pressure_change is True\n", + " and self.config.momentum_balance_type != MomentumBalanceType.none\n", + " ):\n", + " self.deltaP = Reference(self.liquid_phase.deltaP[:])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As is typical with IDAES models, two submodels are created: the `ControlVolume0D` named `liquid_phase` and the `StateBlock` named `vapor_phase`. Then several unit model level constraints are written. \n", + "\n", + "## Step 3: Creating a New Scaler Class\n", + "\n", + "To create a new scaling routine for the equilibrium reactor, we start by creating a new ``Scaler`` class which inherits from the ``CustomScalerBase`` class in ``idaes.core.scaling``. The ``CustomScalerBase`` class contains a number of useful methods to help us in developing our scaling routine, including some placeholder methods for implementing a standard scaling workflow and helper methods for doing common tasks.\n", + "\n", + "The cell below shows how to create our new class which we will name ``SolventReboilerScaler`` as well as two key methods we will fill out as part of this workshop." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "from idaes.core.scaling import CustomScalerBase\n", + "\n", + "\n", + "class SolventReboilerScaler(CustomScalerBase):\n", + " def variable_scaling_routine(\n", + " self, model, overwrite: bool = False, submodel_scalers: dict = None\n", + " ):\n", + " # Empty method for now\n", + " pass\n", + "\n", + " def constraint_scaling_routine(\n", + " self, model, overwrite: bool = False, submodel_scalers: dict = None\n", + " ):\n", + " # Empty method for now\n", + " pass" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As you know from the first scaling tutorial, the ``variable_scaling_routine`` and ``constraint_scaling_routine`` methods are used to implement subroutines for scaling the variables and constraints in the model respectively. Separately, there is a ``scale_model`` method that will call each of these in sequence in order to scale an entire model by applying the following steps:\n", + "\n", + "1. apply variable scaling routine,\n", + "2. apply first stage scaling fill-in,\n", + "3. apply constraint scaling routine,\n", + "4. apply second stage scaling fill-in.\n", + "\n", + "The second and fourth steps are intended to allow users to provide methods to fill in missing scaling information that was not provided by the first and second steps. However, these methods are prone to perform poorly on all but the simplest models (see Step 5 for more information).\n", + "\n", + "## Step 4: Apply Scaling to Sub-Models\n", + "\n", + "First, let's look at how to scale the control volume and state block sub-models. Because the property package for the ``vapor_phase`` state block is specified by the user, we do not know what variables and constraints it may contain, so we cannot (and should not) scale it directly. The property package creator (hopefully) created a scaler object that we can use. The zero-dimensional control volume ``liquid_phase`` contains two state blocks, material, energy, and pressure balance constraints, and variables corresponding to additional interaction terms. Because we are choosing which terms to create in the control volume, we could, in principle, scale it at the unit model level. However, because control volumes typically should be scaled in the same way, a submodel scaler has been provided for it as well. Thus, what we want to do here is to call the variable and constraint scaling routines from the ``Scaler`` associated with each sub-model, which we can do using the ``call_submodel_scaler_method`` method." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "class SolventReboilerScaler(CustomScalerBase):\n", + " def variable_scaling_routine(\n", + " self, model, overwrite: bool = False, submodel_scalers: ComponentMap = None\n", + " ):\n", + " # Call scaling methods for sub-models\n", + " self.call_submodel_scaler_method(\n", + " submodel=model.liquid_phase,\n", + " method=\"variable_scaling_routine\",\n", + " submodel_scalers=submodel_scalers,\n", + " overwrite=overwrite,\n", + " )\n", + "\n", + " self.call_submodel_scaler_method(\n", + " submodel=model.vapor_phase,\n", + " method=\"variable_scaling_routine\",\n", + " submodel_scalers=submodel_scalers,\n", + " overwrite=overwrite,\n", + " )\n", + "\n", + " def constraint_scaling_routine(\n", + " self, model, overwrite: bool = False, submodel_scalers: ComponentMap = None\n", + " ):\n", + " # Call scaling methods for sub-models\n", + " self.call_submodel_scaler_method(\n", + " submodel=model.liquid_phase,\n", + " method=\"constraint_scaling_routine\",\n", + " submodel_scalers=submodel_scalers,\n", + " overwrite=overwrite,\n", + " )\n", + "\n", + " self.call_submodel_scaler_method(\n", + " submodel=model.vapor_phase,\n", + " method=\"constraint_scaling_routine\",\n", + " submodel_scalers=submodel_scalers,\n", + " overwrite=overwrite,\n", + " )" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In order for the submodel scaling to function properly, default scaling factors need to be set for some variables. The property package scaler cannot know if the system is supposed to be bench scale, pilot scale, or production scale unless the user sets a default for flow rate. These defaults can be set on a unit model by unit model basis by using the `submodel_scalers` argument, or they can be set at the flowsheet level on the parameter block. We will do the latter.\n", + "\n", + "First, we need to create objects using the modular property submodel scaler class." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "liquid_properties_scaler = m.fs.liquid_properties.default_state_scaler_class()\n", + "vapor_properties_scaler = m.fs.vapor_properties.default_state_scaler_class()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, let's see what default scaling factors these scaler objects have." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'flow_mol_phase': ,\n", + " 'mole_frac_phase_comp': 10,\n", + " 'temperature': 0.0033333333333333335,\n", + " 'pressure': 1e-05,\n", + " 'enth_mol_phase': ,\n", + " 'visc_d_phase': ,\n", + " 'therm_cond_phase': ,\n", + " 'mole_frac_phase_comp_true': 10,\n", + " 'mole_frac_phase_comp_apparent': 10,\n", + " 'dens_mol_phase': ,\n", + " 'vol_mol_phase': }" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "liquid_properties_scaler.default_scaling_factors" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can see that we are required to set a default scaling factor for ``flow_mol_phase``. Furthermore, it is recommended to set a default scaling factor for ``enth_mol_phase``, ``visc_d_phase``, ``therm_cond_phase``, `dens_mol_phase`, and`vol_mol_phase`. For these latter quantities, there is a method to estimate reasonable scaling factors, but it might not be suitible for all cases.\n", + "\n", + "With an inlet flow of about 80 mol/s, a scaling factor of 1/80 is appropriate. We can ignore ``visc_d_phase`` and ``therm_cond_phase``, because this unit model does not require dynamic viscosity or thermal conductivity. Molar enthalpy is a tougher quantity to scale.\n", + "\n", + "By convention, the molar enthalpy of each element in its pure form at $25^\\circ\\text{C}$ and $1\\:\\text{atm}$ is set equal to zero. In some property packages, enthalpy of formation is taken into account for compounds, while in some property packages it is not. However, the scaling factor for enthalpy should not depend on this convention---only enthalpy *differences* are meaningful. So we need to determine how to determine what constitutes a \"significant\" enthalpy difference for this property package. The way the modular property scaler object estimates this is through the temperature scaling factor, which determines what a \"significant\" temperature difference is, and the observation that a wide range of substances have a specific heat capacity around $2\\:\\frac{\\text{J}}{\\text{g K}}$.\n", + "\n", + "This default method is good enough for our purposes now. We can revisit it later, if necessary." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "liquid_properties_scaler.default_scaling_factors[\"flow_mol_phase\"] = 1 / 80\n", + "vapor_properties_scaler.default_scaling_factors[\"flow_mol_phase\"] = 1 / 10\n", + "\n", + "m.fs.liquid_properties.default_state_scaler_object = liquid_properties_scaler\n", + "m.fs.vapor_properties.default_state_scaler_object = vapor_properties_scaler" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can see how much submodel scaling improves the conditioning of the unit model." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "====================================================================================\n", + "Model Statistics\n", + "\n", + " Jacobian Condition Number: 7.165E+10\n", + "\n", + "------------------------------------------------------------------------------------\n", + "1 WARNINGS\n", + "\n", + " WARNING: 1 Constraint with large residuals (>1.0E-05)\n", + "\n", + "------------------------------------------------------------------------------------\n", + "8 Cautions\n", + "\n", + " Caution: 9 Variables with value close to their bounds (abs=1.0E-04, rel=1.0E-04)\n", + " Caution: 14 Variables with value close to zero (tol=1.0E-08)\n", + " Caution: 27 Variables with extreme value (<1.0E-04 or >1.0E+04)\n", + " Caution: 2 Constraints with mismatched terms\n", + " Caution: 1 Constraint with potential cancellation of terms\n", + " Caution: 10 Variables with extreme Jacobian column norms (<1.0E-04 or >1.0E+04)\n", + " Caution: 4 Constraints with extreme Jacobian row norms (<1.0E-04 or >1.0E+04)\n", + " Caution: 33 extreme Jacobian Entries (<1.0E-04 or >1.0E+04)\n", + "\n", + "------------------------------------------------------------------------------------\n", + "Suggested next steps:\n", + "\n", + " display_constraints_with_large_residuals()\n", + " compute_infeasibility_explanation()\n", + "\n", + "====================================================================================\n" + ] + } + ], + "source": [ + "reboiler_scaler = SolventReboilerScaler()\n", + "reboiler_scaler.scale_model(m.fs.unit)\n", + "dt = DiagnosticsToolbox(m)\n", + "dt.report_numerical_issues()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We see in this case that partly scaling the model improved the condition number of the Jacobian by only two and a half orders of magnitude. This sort of marginal improvement is common for partial scaling, and sometimes partial scaling makes the model's condition number *worse*. When variables are scaled without the constraints they appear in also being scaled, it generates new extreme Jacobian entries. If we look at the number of extreme Jacobian rows and columns, however, we see the progress we've made. Before applying submodel scaling, we had 27 variables with extreme column norms and 16 constraints with extreme row norms. Now we have only 10 variables and 4 constraints.\n", + "\n", + "We are concerned with Jacobian rows and columns with extreme values because they allow us to estimate the Jacobian condition number. Determining the (Euclidean) condition number requires the computation of the *singular value decomposition* (SVD) of $\\mathbf{J}(\\mathbf{x})$. However, that process is computationally expensive for large models, and it does not identify individual variables and constraints as problematic (instead, it identifies *combinations* of variables and constraints as problematic). However, we have a lower bound to the condition number in terms of the norms of rows and columns of the Jacobian matrix:\n", + "$$\n", + "\\max\\left(\\frac{||\\mathbf{r}_\\text{max}||_2}{||\\mathbf{r}_\\text{min}||_2}, \\frac{||\\mathbf{c}_\\text{max}||_2}{||\\mathbf{c}_\\text{min}||_2}\\right) \\leq \\kappa(\\mathbf{J}(\\mathbf{x}))\n", + "$$\n", + "Consequently, Jacobian rows or columns with extremely large or extremely small norms indicate that the Jacobian is ill-conditioned. Each row is associated with a constraint and each column is associated with a variable. So the extreme Jacobian rows and columns give us a list of variables and constraints to investigate for scaling.\n", + "\n", + "
\n", + "Just because a variable or constraint has a Jacobian column or row with an extreme norm does not mean it is badly-scaled. Frequently, either a constraint containing the variable or a variable present in a constraint is the actual problem. \n", + "
\n", + "\n", + "
\n", + "NOTE\n", + "\n", + "Jacobian rows and columns with extreme norms reveal that the Jacobian matrix is ill-conditioned, but the converse is not true. A Jacobian matrix can have no rows and columns with extreme norms but still be singular or ill-conditioned.\n", + "\n", + "
\n", + "\n", + "\n", + "Let's see which variables and constraints are problematic." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "====================================================================================\n", + "The following variable(s) correspond to Jacobian columns with extreme norms(<1.0E-04 or>1.0E+04):\n", + "\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,CO2]: 3.450E+07\n", + " fs.unit.liquid_phase.enthalpy_transfer[0.0]: 1.970E+06\n", + " fs.unit.liquid_phase.properties_out[0.0].temperature: 1.586E+06\n", + " fs.unit.vapor_phase[0.0].pressure: 1.353E+05\n", + " fs.unit.vapor_phase[0.0].temperature: 1.014E+05\n", + " fs.unit.liquid_phase.properties_out[0.0].pressure: 1.000E+05\n", + " fs.unit.vapor_phase[0.0].flow_mol_phase[Vap]: 3.256E+04\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,H2O]: 1.954E+04\n", + " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]: 1.873E+04\n", + " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]: 1.863E+04\n", + "\n", + "====================================================================================\n", + "====================================================================================\n", + "The following constraint(s) correspond to Jacobian rows with extreme norms (<1.0E-04 or>1.0E+04):\n", + "\n", + " fs.unit.unit_phase_equilibrium[0.0,CO2]: 3.450E+07\n", + " fs.unit.unit_enthalpy_balance[0.0]: 1.973E+06\n", + " fs.unit.unit_phase_equilibrium[0.0,H2O]: 1.589E+06\n", + " fs.unit.unit_pressure_balance[0.0]: 1.414E+05\n", + "\n", + "====================================================================================\n" + ] + } + ], + "source": [ + "dt.display_variables_with_extreme_jacobians()\n", + "dt.display_constraints_with_extreme_jacobians()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "These four unit model level constraints are causing our remaining problems.\n", + "\n", + "## Step 5: Unit Model Level Scaling\n", + "\n", + "We should take a look at the constraints before determining their scaling factors. However, Pyomo's `pprint` method often prints out multiple terminal pages' worth of thermodynamic expressions, which are extremely difficult to parse. The output is so verbose because it descends into named `Expressions` and recursively subsititutes them into the constraint expression. Since IDAES makes heavy use of named `Expressions` to decrease the number of `Constraints` in a model, the output becomes unmanangable for all but the most simple constraints. The `print_compact_form` utility function usually results in much more readable output." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "- fs.unit.liquid_phase.enthalpy_transfer[0.0] == (kg*m**2/J/s**2)*fs.unit.vapor_phase[0.0]._enthalpy_flow_term[Vap]\n" + ] + } + ], + "source": [ + "from idaes.core.util.misc import print_compact_form\n", + "\n", + "print_compact_form(m.fs.unit.unit_enthalpy_balance[0.0])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This is a relatively straightforward constraint.\n", + "\n", + "So long as we have scaling factors set for the terms in the enthalpy balance, we can scale the constraint by the same factor. Because `liquid_phase.enthalpy_transfer[0.0]` is a `Var` created by the `ControlVolume0D`, it already has a scaling factor assigned by the `ControlVolume0DScaler`.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "5.076760620583219e-07" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "get_scaling_factor(m.fs.unit.liquid_phase.enthalpy_transfer[0.0])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "However, in the modular property framework, `get_enthalpy_flow_terms(p)` returns a named `Expression`. Expressions do not need to be scaled on their own. However, scaling hints can be assigned for them to assist in determining appropriate scaling factors for other variables and constraints. When the `get_scaling_factor` function is called on an `Expression`, it will return a scaling hint if one is assigned. (This behavior is useful, because what is a `Var` in one property package can be implemented as an `Expression` in another.)\n", + "\n", + "In this case, however, no scaling hint is assigned to `vapor_phase[0.0]._enthalpy_flow_term[\"Vap\"]`." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "None\n" + ] + } + ], + "source": [ + "print(get_scaling_factor(m.fs.unit.vapor_phase[0.0]._enthalpy_flow_term[\"Vap\"]))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To get an estimate of the size of that expression, then, we can look at its constituent terms:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "fs.unit.vapor_phase[0.0].flow_mol_phase[Vap]*fs.unit.vapor_phase[0.0].enth_mol_phase[Vap]\n" + ] + } + ], + "source": [ + "print_compact_form(m.fs.unit.vapor_phase[0.0]._enthalpy_flow_term[\"Vap\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The term `vapor_phase[0.0].flow_mol_phase[\"Vap\"]` *is* a `Var` and has a scaling factor applied." + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.1" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "get_scaling_factor(m.fs.unit.vapor_phase[0.0].flow_mol_phase[\"Vap\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "However, `vapor_phase[0.0].enth_mol_phase[\"Vap\"]` is a named `Expression`. Nevertheless, it has a scaling hint." + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "5.46268982847154e-05" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "get_scaling_factor(m.fs.unit.vapor_phase[0.0].enth_mol_phase[\"Vap\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Because the scaling factor of the molar flow rate is $0.1$, we can estimate that the molar flow rate will be about $10$. Similarly, we can estimate the size of a significant molar enthalpy difference is around the size of `1/5.46e-5`$ \\approx 18,000$. Therefore the general size of the enthalpy flow terms should be around $180,000$." + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.0125" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "get_scaling_factor(m.fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase[\"Liq\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The `get_sum_terms_nominal_values` method in `CustomScalerBase` which uses an expression walker to go through an expression to return a list of the expected magnitude (or \"nominal value\") of all additive terms in the expression based on the scaling factors for the variables involved. For example, suppose we have an expression\n", + "$$\n", + "a + b\\cdot c - d\\cdot (e - f)\n", + "$$\n", + "Let $\\sigma(v)$ denote the scaling factor of the variable $v$. Then `get_sum_terms_nominal_values` substitutes the inverse of the variable scaling factor into each term in the sum and returns it as a list:\n", + "$$\n", + "\\left[\\frac{1}{\\sigma(a)},\\; \\frac{1}{\\sigma(b) \\cdot \\sigma(c)}, \\frac{\\left(\\frac{1}{\\sigma(e)} - \\frac{1}{\\sigma(f)}\\right)}{\\sigma(d)} \\right]\n", + "$$\n", + "\n", + "This process can produce reliable estimates of expression magnitude for certain operations:\n", + " - Addition of positive numbers\n", + " - Multiplication and division\n", + " - Raising a variable to a fixed power\n", + "\n", + "For these operations, only an order-of-magnitude estimate for the variable is sufficient to get an order-of-magnitude estimate of the resulting expression. However, it is far less reliable for other operations:\n", + " - Subtraction (or addition of negative numbers to positive numbers)\n", + " - Functions with a variable exponent\n", + " - Trigometric functions\n", + " - Logarithms\n", + "\n", + "For these operations, an expression's final value is highly dependent on the exact values of its included variables. For example, suppose $\\sigma(e) = \\sigma(f)$. In that case, the term $d\\cdot (e - f)$ would have an estimated magnitude of $0$, which is useless for scaling purposes. It is in cases like this that scaling hints for named expressions. If we denote $G = e - f$ and assign $\\sigma(G) = \\sigma(e)$, we have a far better estimate of the term $d\\cdot (e - f)$ in the quantity $1/(\\sigma(d)\\cdot\\sigma(G))$.\n", + "\n", + "Logarithms are a special case. Since they convert multiplication to addition, application of a scaling factor simply shifts the zero point of the resulting expression.\n", + "$$\n", + " \\log(h \\cdot \\sigma(h)) = \\log(h) + \\log(\\sigma(h))\n", + "$$\n", + "\n", + "The output of a logarithmic expression should be considered well-scaled by default, unless its argument is an absolutely enormous number (in which case floating point arithmetic is probably inappropriate anyway).\n", + "\n", + "In the case of scaling `unit.unit_enthalpy_balance[0.0]`, we only have two additive terms, one consisting of a single variable, the other consisting of the product of a variable with an expression with a scaling hint. In this case, `get_sum_terms_nominal_values` should produce a good estimate of the order-of-magnitude of each term.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[1969759.9999999995, 183060.0]" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "reboiler_scaler.get_sum_terms_nominal_values(m.fs.unit.unit_enthalpy_balance[0.0])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The inverse of either of these numbers would be reasonable scaling factors. The `scale_constraint_by_nominal value` function automatically scales a constraint by using one of these numbers. Which number we use is selected using the `ConstraintScalingScheme` `Enum` If we take the inverse of the larger number, we are saying that the constraint needs to be satisfied with the same precision as the largest term in the sum. This corresponds to `ConstraintScalingScheme.inverseMaximum`. If we take the inverse of the smaller number, we are saying that the constraint needs to be satisfied with the same precision as the smallest term in the sum. This corresponds to `ConstraintScalingScheme.inverseMinimum`.\n", + "\n", + "In general, the `inverseMinimum` scheme is the safest to use, because it demands the most precision. Let's use the `inverseMinimum` method for this constraint in order to more precisely determine the vapor phase's temperature.\n", + "\n", + "The next two constraints can be dealt with together:" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[Liq,CO2] == fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,CO2]\n", + "\n", + "\n", + "fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[Liq,H2O] == fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,H2O]\n" + ] + } + ], + "source": [ + "print_compact_form(m.fs.unit.unit_phase_equilibrium[0.0, \"CO2\"])\n", + "print(\"\\n\")\n", + "print_compact_form(m.fs.unit.unit_phase_equilibrium[0.0, \"H2O\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "These are simple vapor-liquid equilibrium constraints for the volatile components. Let's see what `get_sum_terms_nominal_values` shows for them:" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[7623092.433711249, 10000.0]\n", + "[355.3596511053128, 10000.0]\n" + ] + } + ], + "source": [ + "print(\n", + " reboiler_scaler.get_sum_terms_nominal_values(\n", + " m.fs.unit.unit_phase_equilibrium[0.0, \"CO2\"]\n", + " )\n", + ")\n", + "print(\n", + " reboiler_scaler.get_sum_terms_nominal_values(\n", + " m.fs.unit.unit_phase_equilibrium[0.0, \"H2O\"]\n", + " )\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here, we see that, while the vapor phase fugacities are associated with a nominal value of 10000, the liquid phase fugacities have wildly different nominal values. We do expect the vapor phase to be enriched in $\\text{CO}_2$, but not by a factor of $2\\cdot 10^4$. Let's unpack these values. We are using the ideal gas law for the vapor phase, so the fugacity is simply the product of the mole fraction and vapor pressure:" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]*fs.unit.vapor_phase[0.0].pressure\n" + ] + } + ], + "source": [ + "print_compact_form(m.fs.unit.vapor_phase[0.0].fug_phase_comp[\"Vap\", \"CO2\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The liquid phase, by contrast, contains a complicated Henry's Law type relationship for $\\text{CO}_2$ and a slightly less complicated Antoine's Law relationship for $\\text{H}_2\\text{O}$:" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,CO2]*(exp(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O])*log(244800.0*exp(-1348*K/fs.unit.liquid_phase.properties_out[0.0].temperature)*(3520000.0*exp(-2113*K/fs.unit.liquid_phase.properties_out[0.0].temperature)/(8449000.0*exp(-2283*K/fs.unit.liquid_phase.properties_out[0.0].temperature)))) + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O])*log(3520000.0*exp(-2113*K/fs.unit.liquid_phase.properties_out[0.0].temperature)) + fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O])*(fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]))*(fs.liquid_properties.CO2.lwm_coeff_1 + K**(-1)*fs.liquid_properties.CO2.lwm_coeff_2*(fs.unit.liquid_phase.properties_out[0.0].temperature - 273.15*K) + K**(-2)*fs.liquid_properties.CO2.lwm_coeff_3*(fs.unit.liquid_phase.properties_out[0.0].temperature - 273.15*K)**2 + fs.liquid_properties.CO2.lwm_coeff_4*(fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]))))*Pa*m**3*mol**(-1))\n" + ] + } + ], + "source": [ + "print_compact_form(\n", + " m.fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[\"Liq\", \"CO2\"]\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Parsing the entire pile of thermodynamic gibberish is unnecessary to plan our next move. We can plainly see that the liquid phase fugacity expression is rife with subtraction and exponentiation, both of which are dangerous for the nominal value expression walker. Even worse, we are scaling based on a failed solution, so the values may be off anyway. It is far better to base the scaling factor on the vapor phase fugacity. The `get_expression_nominal_value` function allows the user to get the nominal value of a single expression." + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "10000.0" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "reboiler_scaler.get_expression_nominal_value(\n", + " m.fs.unit.vapor_phase[0.0].fug_phase_comp[\"Vap\", \"CO2\"]\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "While in this case this value is positive, the nominal value can be negative, so you should use the absolute value when getting a scaling factor.\n", + "\n", + "Finally, we have the last constraint: mechanical equilibrium between phases.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "fs.unit.liquid_phase.properties_out[0.0].pressure == fs.unit.vapor_phase[0.0].pressure\n" + ] + } + ], + "source": [ + "print_compact_form(m.fs.unit.unit_pressure_balance[0.0])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The `inverseMinimum` scheme will work here as well.\n", + "\n", + "In addition to these problematic unit model level constraints, there are some additional constraints that need scaling factors. Although they might not be problematic under these process conditions, they may be for a scaled-up flowsheet. If we suspect they are well-scaled already, we should use the `report_scaling_factors` function to show what they are:" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Scaling Factors for block fs.unit\n", + "\n", + "Variable Scaling Factor Value Scaled Value\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol 1.250E-02 8.389E+01 1.049E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[H2O] 1.000E+01 8.589E-01 8.589E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[MEA] 1.000E+01 1.085E-01 1.085E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[CO2] 1.000E+01 3.260E-02 3.260E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].temperature 3.333E-03 3.925E+02 1.308E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol 1.250E-02 7.424E+01 9.279E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O] 1.000E+01 8.527E-01 8.527E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] 1.000E+01 1.226E-01 1.226E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[CO2] 1.000E+01 2.471E-02 2.471E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].temperature 3.333E-03 3.926E+02 1.309E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", + "fs.unit.vapor_phase[0.0].flow_mol 1.000E-01 9.654E+00 9.654E-01\n", + "fs.unit.vapor_phase[0.0].mole_frac_comp[CO2] 1.000E+01 9.329E-02 9.329E-01\n", + "fs.unit.vapor_phase[0.0].mole_frac_comp[H2O] 1.000E+01 9.067E-01 9.067E+00\n", + "fs.unit.vapor_phase[0.0].mole_frac_comp[N2] 1.000E+01 1.055E-09 1.055E-08\n", + "fs.unit.vapor_phase[0.0].mole_frac_comp[O2] 1.000E+01 1.055E-09 1.055E-08\n", + "fs.unit.vapor_phase[0.0].temperature 3.333E-03 3.926E+02 1.309E+00\n", + "fs.unit.vapor_phase[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", + "fs.unit.liquid_phase.heat[0.0] 5.077E-07 4.306E+05 2.186E-01\n", + "\n", + "Constraint Scaling Factor\n", + "fs.unit.unit_material_balance[0.0,CO2] None\n", + "fs.unit.unit_material_balance[0.0,H2O] None\n", + "fs.unit.unit_material_balance[0.0,N2] None\n", + "fs.unit.unit_material_balance[0.0,O2] None\n", + "fs.unit.unit_material_balance[0.0,MEA] None\n", + "fs.unit.unit_phase_equilibrium[0.0,CO2] None\n", + "fs.unit.unit_phase_equilibrium[0.0,H2O] None\n", + "fs.unit.unit_temperature_equality[0.0] None\n", + "fs.unit.unit_enthalpy_balance[0.0] None\n", + "fs.unit.unit_pressure_balance[0.0] None\n" + ] + } + ], + "source": [ + "from idaes.core.scaling.util import report_scaling_factors\n", + "\n", + "report_scaling_factors(m.fs.unit, descend_into=False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We have yet to scale the `unit_temperature_equality` and `unit_material_balance`constraints. The temperature equality constraint is simple." + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "fs.unit.liquid_phase.properties_out[0.0].temperature == fs.unit.vapor_phase[0.0].temperature\n" + ] + } + ], + "source": [ + "print_compact_form(m.fs.unit.unit_temperature_equality[0.0])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "`inverseMinimum` works fine here.\n", + "\n", + "The material balance constraints have different forms depending on whether a component occurs in the liquid phase, the vapor phase, or both:" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "- fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,CO2] == fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,CO2]\n", + "\n", + "\n", + "fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,MEA] == 0*(mol*s**(-1))\n", + "\n", + "\n", + "fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,N2] == fs.unit.zero_flow_param\n" + ] + } + ], + "source": [ + "print_compact_form(m.fs.unit.unit_material_balance[0.0, \"CO2\"])\n", + "print(\"\\n\")\n", + "print_compact_form(m.fs.unit.unit_material_balance[0.0, \"MEA\"])\n", + "print(\"\\n\")\n", + "print_compact_form(m.fs.unit.unit_material_balance[0.0, \"N2\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The first constraint equates the vapor flow rate to the mass transfer from the liquid phase. Either inverse maximum or inverse minimum would work. The next two are a bit trickier. For $\\text{MEA}$, which is considered nonvolatile in this property package, there is no mass transfer to the vapor phase. A common misconception is that variables should always be scaled to be order one. That is incorrect. We only need to calculate `mass_transfer_term[0.0,\"Liq\",\"MEA\"]` to the same precision as the other (nonzero) terms of the mass balance (and the `ControlVolume0D` submodel scaler does just that). Similarly, `flow_mol_phase_comp[\"Vap\",\"N2\"]` is set to a tiny nonzero value (because flows that are exactly zero often cause problems for property calculations). We do not need more significant figures for either of those variables than the rest of the terms in their correspoding material balances. Therefore we want to use the `inverseMaximum` becuase `inverseMinimum` would demand unnecessary precision.\n", + "\n", + "
\n", + "NOTE\n", + "\n", + "If we had relied on autoscaling methods to fill in scaling factors for these variables and constraints, we would have ended up with enormous scaling factors for `flow_mol_phase_comp[\"Vap\",\"N2\"]` and `flow_mol_phase_comp[\"Vap\",\"O2\"]` because they are not-quite equal to zero at the model solution.\n", + "\n", + "Similarly, `m.fs.unit.unit_phase_equilibrium[0.0,\"CO2\"]` would have been overscaled due to the enormous nominal value given by the expression walker for the liquid phase fugacity\n", + "\n", + "
\n", + "\n", + "Finally, we can complete the scaler object." + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [], + "source": [ + "from idaes.core.scaling.custom_scaler_base import ConstraintScalingScheme\n", + "\n", + "\n", + "class SolventReboilerScaler(CustomScalerBase):\n", + " def variable_scaling_routine(\n", + " self, model, overwrite: bool = False, submodel_scalers: dict = None\n", + " ):\n", + " # Call scaling methods for sub-models\n", + " self.call_submodel_scaler_method(\n", + " submodel=model.liquid_phase,\n", + " method=\"variable_scaling_routine\",\n", + " submodel_scalers=submodel_scalers,\n", + " overwrite=overwrite,\n", + " )\n", + "\n", + " self.call_submodel_scaler_method(\n", + " submodel=model.vapor_phase,\n", + " method=\"variable_scaling_routine\",\n", + " submodel_scalers=submodel_scalers,\n", + " overwrite=overwrite,\n", + " )\n", + "\n", + " def constraint_scaling_routine(\n", + " self, model, overwrite: bool = False, submodel_scalers: dict = None\n", + " ):\n", + " # Call scaling methods for sub-models\n", + " self.call_submodel_scaler_method(\n", + " submodel=model.liquid_phase,\n", + " method=\"constraint_scaling_routine\",\n", + " submodel_scalers=submodel_scalers,\n", + " overwrite=overwrite,\n", + " )\n", + "\n", + " self.call_submodel_scaler_method(\n", + " submodel=model.vapor_phase,\n", + " method=\"constraint_scaling_routine\",\n", + " submodel_scalers=submodel_scalers,\n", + " overwrite=overwrite,\n", + " )\n", + " # Note: scaling factors cannot be applied directly to indexed objects.\n", + " # They should be applied to VarData/ConstraintData/ExpressionData children instead.\n", + " for condata in model.unit_material_balance.values():\n", + " self.scale_constraint_by_nominal_value(\n", + " condata,\n", + " scheme=ConstraintScalingScheme.inverseMaximum,\n", + " overwrite=overwrite,\n", + " )\n", + " for condata in model.unit_temperature_equality.values():\n", + " self.scale_constraint_by_nominal_value(\n", + " condata,\n", + " scheme=ConstraintScalingScheme.inverseMinimum,\n", + " overwrite=overwrite,\n", + " )\n", + " for condata in model.unit_enthalpy_balance.values():\n", + " self.scale_constraint_by_nominal_value(\n", + " condata,\n", + " scheme=ConstraintScalingScheme.inverseMinimum,\n", + " overwrite=overwrite,\n", + " )\n", + " for condata in model.unit_pressure_balance.values():\n", + " self.scale_constraint_by_nominal_value(\n", + " condata,\n", + " scheme=ConstraintScalingScheme.inverseMinimum,\n", + " overwrite=overwrite,\n", + " )\n", + " for (t, j), condata in m.fs.unit.unit_phase_equilibrium.items():\n", + " nom = abs(\n", + " self.get_expression_nominal_value(\n", + " m.fs.unit.vapor_phase[t].fug_phase_comp[\"Vap\", j]\n", + " )\n", + " )\n", + " self.set_constraint_scaling_factor(condata, 1 / nom, overwrite=overwrite)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can see how this works on the model. We'll pass `overwrite=True` config option when creating the scaler object to ensure we have up-to-date scaling factors." + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Starting initialization routine\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Bubble, dew, and critical point initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Equilibrium temperature initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: State variable initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Phase equilibrium initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Property initialization routine finished.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Starting initialization routine\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Bubble, dew, and critical point initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Equilibrium temperature initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: State variable initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Phase equilibrium initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Property initialization routine finished.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: Starting initialization routine\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: Bubble, dew, and critical point initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: Equilibrium temperature initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: State variable initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: Phase equilibrium initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: Property initialization routine finished.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit: Initialization Complete: optimal - \n" + ] + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "scaler_obj = SolventReboilerScaler(overwrite=True)\n", + "scaler_obj.scale_model(m.fs.unit)\n", + "reboiler_init.initialize(m.fs.unit)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We see that scaling improved the model enough so that initialization could succeed. Now let's look at the numerical issues." + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "====================================================================================\n", + "Model Statistics\n", + "\n", + " Jacobian Condition Number: 5.400E+06\n", + "\n", + "------------------------------------------------------------------------------------\n", + "0 WARNINGS\n", + "\n", + " No warnings found!\n", + "\n", + "------------------------------------------------------------------------------------\n", + "6 Cautions\n", + "\n", + " Caution: 9 Variables with value close to their bounds (abs=1.0E-04, rel=1.0E-04)\n", + " Caution: 14 Variables with value close to zero (tol=1.0E-08)\n", + " Caution: 27 Variables with extreme value (<1.0E-04 or >1.0E+04)\n", + " Caution: 2 Constraints with mismatched terms\n", + " Caution: 1 Constraint with potential cancellation of terms\n", + " Caution: 20 extreme Jacobian Entries (<1.0E-04 or >1.0E+04)\n", + "\n", + "------------------------------------------------------------------------------------\n", + "Suggested next steps:\n", + "\n", + " If you still have issues converging your model consider:\n", + "\n", + " prepare_degeneracy_hunter()\n", + " prepare_svd_toolbox()\n", + "\n", + "====================================================================================\n" + ] + } + ], + "source": [ + "dt = DiagnosticsToolbox(m)\n", + "dt.report_numerical_issues()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We have reduced the Jacobian condition number by another four orders of magnitude, as well as eliminating all extreme Jacobian rows and columns. A condition number of $5\\cdot 10^6$ is still higher than we'd like for a single unit model, especially for a simple unit model like this one, because connecting units together as part of a flowsheet inevitably increases the condition number. \n", + "\n", + "## Step 6: Singular Value Decomposition\n", + "\n", + "With no more extreme Jacobian rows or columns, we have two avenues to proceed:\n", + "1. Check the extreme Jacobian *entries*\n", + "2. Check the singular value decomposition (SVD) of the Jacobian\n", + "\n", + "Extreme Jacobian entries only *suggest* that the variable and constraint might be contributing to ill-conditioning\u2014they might also be false positives. However, extreme singular values are *guaranteed* to be contributing to the Jacobian's ill-conditioning. Therefore, we will look at the SVD next.\n", + "\n", + "The singular value decomposition factorizes a matrix into three parts:\n", + "$$\n", + "\\mathbf{J} = \\mathbf{U \\Sigma V}^T\n", + "$$\n", + "Both $\\mathbf{U}$ and $\\mathbf{V}$ are orthogonal matrices, i.e., $\\mathbf{U}^T \\mathbf{U} = \\mathbf{I}$ and $\\mathbf{V}^T\\mathbf{V} = \\mathbf{I}$. If $\\mathbf{J}$ is square, then $\\mathbf{\\Sigma}$ is a diagonal matrix of the form:\n", + "$$\n", + "\\mathbf{\\Sigma} = \\begin{bmatrix}\n", + " \\sigma_1 & 0 & \\dots & 0 \\\\\n", + " 0 & \\sigma_2 & \\dots & 0 \\\\\n", + " \\vdots & \\vdots & \\ddots & \\vdots\\\\\n", + " 0 & 0 & \\dots & \\sigma_n\n", + " \\end{bmatrix}\n", + "$$\n", + "in which $\\sigma_j$ are the singular values. The singular values are arranged in descending order, i.e., $\\sigma_{j+1} \\leq \\sigma_{j}$. If any $\\sigma_j=0$, then the matrix is singular.\n", + "\n", + "The condition number is given by:\n", + "$$\n", + "\\kappa(\\mathbf{J}) = \\sigma_1 / \\sigma_n\n", + "$$\n", + "Thus, extremely large and extremely small singular values cause matrix ill-conditioning. However, extremely large singular values typically show up as rows and columns with extreme norms. Therefore we will look at the smallest singular values.\n", + "\n", + "Because $\\mathbf{U}$ and $\\mathbf{V}$ are orthogonal and $\\mathbf{\\Sigma}$ is diagonal, computing a Newton step is easy once the SVD is calculated.\n", + "$$\n", + "\\mathbf{\\delta x}_k = -\\mathbf{V \\Sigma^{-1} U}^T \\cdot \\mathbf{f}(\\mathbf{x}_k)\n", + "$$\n", + "Since we have to refactorize $\\mathbf{J}$ at each iteration, the SVD is not an efficient method to calculate a Newton step. However, this process has a geometric interpretation that is useful for model diagnostics and scaling. First, the constraint residual is decomposed into orthogonal components by $\\mathbf{U}$:\n", + "$$\n", + "\\mathbf{s} = -\\mathbf{U}^T \\cdot \\mathbf{f}(\\mathbf{x}_k)\n", + "$$\n", + "Next, these orthogonal components are scaled by the inverse of the associated singular value:\n", + "$$\n", + "\\mathbf{\\tilde{s}} = \\Sigma^{-1} \\cdot \\mathbf{s}\n", + "$$\n", + "Finally, these independent components are translated into the variable space by $\\mathbf{V}$:\n", + "$$\n", + "\\mathbf{\\delta x}_k = \\mathbf{V} \\cdot \\mathbf{\\tilde{s}}\n", + "$$\n", + "So each orthogonal component of the constraint residual space is associated with an orthogonal component of the variable space. In particular, each singular value $\\sigma_j$ is associated with a left singular vector $\\mathbf{u}_j$ and right singular vector $\\mathbf{v}_j$, the $j\\text{th}$ columns of $\\mathbf{U}$ and $\\mathbf{V}$, respectively. Any constraint error in the direction of $\\mathbf{u}_j$ *must* be satisfied by a corresponding change in the direction of $\\mathbf{v}_j$. When $\\sigma_j$ is extremely small, tiny changes in the direction of $\\mathbf{u}_j$ translate into enormous changes in $\\mathbf{v}_j$. This dysfunctional relationship can be a sign of bad scaling, but also can be a sign of some other model issue like numerical singularity. Typically, singular values in the range $10^{-12}$ to $10^{-4}$ are signs of either bad scaling or a highly sensitive model (for example, a flowsheet with a large recycle stream). Values below $10^{-12}$ are indicative of numerical singularity.\n", + "\n", + "
\n", + "NOTE\n", + "\n", + "The singular vectors $\\mathbf{u}_j$ and $\\mathbf{v}_j$ are typically dense. In order to link them with specific variables and constraints, a thresholding scheme is applied. The `size_cutoff_in_singular_vector` config option for the `SVDToolbox` controls the magnitude of an entry in $\\mathbf{u}_j$ and $\\mathbf{v}_j$ that is sufficient to link a variable or constraint to the $\\sigma_j$. It is `0.1` by default, but can take on values between about `0.05` and `0.3`. Decrease it to show fewer variables and constraints, increase it to show more variables and constraints.\n", + "\n", + "
\n", + "\n", + "So let's create an instance of the `SVDToolbox` and display the variables and constraints associated with the 5 smallest singular values.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "====================================================================================\n", + "Constraints and Variables associated with smallest singular values\n", + "\n", + " 1st Smallest Singular Value: 6.356e-04\n", + "\n", + " Variables:\n", + "\n", + " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_comp[CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_comp[H2O]\n", + "\n", + " Constraints:\n", + "\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2]\n", + "\n", + " 2nd Smallest Singular Value: 2.781e-02\n", + "\n", + " Variables:\n", + "\n", + " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_comp[CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_comp[H2O]\n", + "\n", + " Constraints:\n", + "\n", + " fs.unit.unit_material_balance[0.0,CO2]\n", + " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", + "\n", + " 3rd Smallest Singular Value: 3.679e-02\n", + "\n", + " Variables:\n", + "\n", + " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_comp[CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_comp[H2O]\n", + "\n", + " Constraints:\n", + "\n", + " fs.unit.unit_material_balance[0.0,CO2]\n", + " fs.unit.liquid_phase.material_balances[0.0,MEA]\n", + " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", + " fs.unit.liquid_phase.enthalpy_balances[0.0]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", + " fs.unit.unit_material_balance[0.0,MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,HCO3_-]\n", + " fs.unit.vapor_phase[0.0].sum_mole_frac_out\n", + "\n", + " 4th Smallest Singular Value: 6.842e-02\n", + "\n", + " Variables:\n", + "\n", + " fs.unit.vapor_phase[0.0].flow_mol_phase[Vap]\n", + " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,H2O]\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]\n", + " fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,H2O]\n", + " fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,H2O]\n", + " fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,H2O]\n", + " fs.unit.vapor_phase[0.0].mole_frac_comp[H2O]\n", + " fs.unit.vapor_phase[0.0].flow_mol\n", + "\n", + " Constraints:\n", + "\n", + " fs.unit.unit_material_balance[0.0,CO2]\n", + " fs.unit.liquid_phase.material_balances[0.0,MEA]\n", + " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", + " fs.unit.liquid_phase.enthalpy_balances[0.0]\n", + " fs.unit.unit_material_balance[0.0,MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].total_flow_balance\n", + " fs.unit.vapor_phase[0.0].sum_mole_frac_out\n", + "\n", + " 5th Smallest Singular Value: 7.703e-02\n", + "\n", + " Variables:\n", + "\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,H2O]\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]\n", + " fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,H2O]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_k_eq[bicarbonate]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_k_eq[carbamate]\n", + "\n", + " Constraints:\n", + "\n", + " fs.unit.liquid_phase.material_balances[0.0,MEA]\n", + " fs.unit.unit_material_balance[0.0,MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].total_flow_balance\n", + " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[MEA]\n", + " fs.unit.liquid_phase.properties_out[0.0].sum_mole_frac_out\n", + "\n", + "====================================================================================\n" + ] + } + ], + "source": [ + "st = dt.prepare_svd_toolbox()\n", + "# The SVD toolbox displays 10 singular values by default, but we are going to\n", + "# view the only the first five to reduce the amount of output.\n", + "st.display_underdetermined_variables_and_constraints(singular_values=[1, 2, 3, 4, 5])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The smallest singular value is 40 times smaller than the second smallest singular value. This usually means that we can significantly improve the matrix conditioning by scaling only a small number of variables and constraints. There is only one constraint strongly associated with the smallest singular value, so let's start with that." + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "exp(fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]) == fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,CO2]/(mol/m**3)\n" + ] + } + ], + "source": [ + "print_compact_form(\n", + " m.fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[\n", + " \"Liq\", \"CO2\"\n", + " ]\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This constraint converts between the $\\text{CO}_2$ concentration and its logarithm. Using these sorts of log-form variables can increase the number of significant digits when dealing with reactions involving components in small quantities. (They can also introduce degeneracy when dealing with trace quantities that *do not* appear in reactions.)\n", + "\n", + "The SVD Toolbox also has two helper functions: `display_variables_in_constraint`, which displays the Jacobian row corresponding to a constraint, and `display_constraints_including_variable`, which displays the Jacobian column corresponding to a variable." + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "====================================================================================\n", + "The following variables are involved in fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2]:\n", + "\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,H2O]: 4.333e-05\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,MEA]: 1.441e-04\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,CO2]: 6.126e-05\n", + " fs.unit.liquid_phase.properties_out[0.0].temperature: 1.576e-04\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]: -5.255e-07\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA]: 5.123e-06\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,CO2]: -1.648e+00\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]: 5.621e-04\n", + "\n", + "====================================================================================\n" + ] + } + ], + "source": [ + "st.display_variables_in_constraint(\n", + " m.fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[\n", + " \"Liq\", \"CO2\"\n", + " ]\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "NOTE\n", + "\n", + "At this point of the process, the original author found a shortcoming in the `ModularPropertiesScaler`. No scaling hint was set for the molar density expression, so the expression walker descended into it and came back with an inappropriate nominal value. Revising the scaler to estimate the phase density resulted in a condition number improvement of 1-2 orders of magnitude.\n", + "\n", + "Remember:\n", + "1. Scaling is an iterative process.\n", + "2. Submodel scalers may need to be revised to fix scaling issues.\n", + "3. Using the expression walker in an expression tree that involves subtraction or exponential functions is dangerous.\n", + "
\n", + "\n", + "From our knowledge of the physical properties, `mole_frac_phase_comp_true[\"Liq\",\"CO2\"]` and `log_conc_mol_phase_comp_true[\"Liq\",\"CO2\"]` should have the largest effects on this equation. The other variables affect the concentration indirectly through the phase density. But while `mole_frac_phase_comp_true[\"Liq\",\"CO2\"]` does have an appropriately-sized impact, `log_conc_mol_phase_comp_true[\"Liq\",\"CO2\"]` is several orders-of-magnitude too small. A naive approach might be to decrease the scaling factor on `log_conc_mol_phase_comp_true[\"Liq\",\"CO2\"]` until it has an appropriately-sized effect in the equation. Remember, though, that log variables are well-scaled by default. Something else must be wrong.\n", + "\n", + "Let's take a look at the values on both sides of the equation." + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Left hand side value: 1.3698e+00\n", + "CO2 true concentration value: 1.3698e+00\n" + ] + } + ], + "source": [ + "print(\n", + " f\"Left hand side value: {value(exp(m.fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[\"Liq\",\"CO2\"])):.4e}\"\n", + ")\n", + "print(\n", + " f\"CO2 true concentration value: {value(m.fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[\"Liq\",\"CO2\"]):.4e}\"\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Since the left hand side and right hand side both have values of order one, we expect the equation to have a similar scaling factor." + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.0004103666666666667\n" + ] + } + ], + "source": [ + "print(\n", + " get_scaling_factor(\n", + " (\n", + " m.fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[\n", + " \"Liq\", \"CO2\"\n", + " ]\n", + " )\n", + " )\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "However, it actually has an extremely small scaling factor. To what can we attribute this?\n", + "\n", + "It is a result of not setting good default values for the true species mole fractions in the liquid phase. Although the apparent $\\text{CO}_2$ mole fraction is about 0.03, almost all of that is in the form of a carbamate salt formed through reaction with $\\text{MEA}$. The true mole fraction is significantly lower." + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True CO2 mole fraction: 3.410357e-05\n", + "True MEACOO- mole fraction: 2.796223e-02\n" + ] + } + ], + "source": [ + "print(\n", + " f\"True CO2 mole fraction: {m.fs.unit.liquid_phase.properties_out[0].mole_frac_phase_comp_true[\"Liq\",\"CO2\"].value:4e}\"\n", + ")\n", + "print(\n", + " f\"True MEACOO- mole fraction: {m.fs.unit.liquid_phase.properties_out[0].mole_frac_phase_comp_true[\"Liq\",\"MEACOO_-\"].value:4e}\"\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Nevertheless, the true value of the $\\text{CO}_2$ mole fraction is important because it is used in the calculation of fugacity. It should therefore be assigned a larger scaling factor. Therefore, let's revisit the default scaling factors for the liquid properties:" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": {}, + "outputs": [], + "source": [ + "default_scaling_factors = (\n", + " m.fs.liquid_properties.default_state_scaler_object.default_scaling_factors\n", + ")\n", + "# Dictionaries are mutable, so changing its value here also changes it on the scaler object\n", + "# First scale the apparent mole fractions\n", + "default_scaling_factors[\"mole_frac_phase_comp[Liq, H2O]\"] = 1\n", + "default_scaling_factors[\"mole_frac_phase_comp[Liq, CO2]\"] = 10\n", + "default_scaling_factors[\"mole_frac_phase_comp[Liq, MEA]\"] = 10\n", + "# Next scale the true mole fractions\n", + "default_scaling_factors[\"mole_frac_phase_comp_true[Liq, H2O]\"] = 1\n", + "default_scaling_factors[\"mole_frac_phase_comp_true[Liq, CO2]\"] = 1e4\n", + "default_scaling_factors[\"mole_frac_phase_comp_true[Liq, MEA]\"] = 10\n", + "default_scaling_factors[\"mole_frac_phase_comp_true[Liq, MEA_+]\"] = 10\n", + "default_scaling_factors[\"mole_frac_phase_comp_true[Liq, MEACOO_-]\"] = 10\n", + "default_scaling_factors[\"mole_frac_phase_comp_true[Liq, HCO3_-]\"] = 100" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "With these new scaling factors, let's rescale and resolve the mode, then check the new condition number." + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Starting initialization routine\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Bubble, dew, and critical point initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Equilibrium temperature initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: State variable initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Phase equilibrium initialization completed.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Property initialization routine finished.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Starting initialization routine\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Bubble, dew, and critical point initialization completed.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Equilibrium temperature initialization completed.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: State variable initialization completed.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Phase equilibrium initialization completed.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Property initialization routine finished.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: Starting initialization routine\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: Bubble, dew, and critical point initialization completed.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: Equilibrium temperature initialization completed.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: State variable initialization completed.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: Phase equilibrium initialization completed.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: Property initialization routine finished.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit: Initialization Complete: optimal - \n", + "====================================================================================\n", + "Model Statistics\n", + "\n", + " Jacobian Condition Number: 2.945E+05\n", + "\n", + "------------------------------------------------------------------------------------\n", + "0 WARNINGS\n", + "\n", + " No warnings found!\n", + "\n", + "------------------------------------------------------------------------------------\n", + "6 Cautions\n", + "\n", + " Caution: 9 Variables with value close to their bounds (abs=1.0E-04, rel=1.0E-04)\n", + " Caution: 14 Variables with value close to zero (tol=1.0E-08)\n", + " Caution: 27 Variables with extreme value (<1.0E-04 or >1.0E+04)\n", + " Caution: 2 Constraints with mismatched terms\n", + " Caution: 1 Constraint with potential cancellation of terms\n", + " Caution: 16 extreme Jacobian Entries (<1.0E-04 or >1.0E+04)\n", + "\n", + "------------------------------------------------------------------------------------\n", + "Suggested next steps:\n", + "\n", + " If you still have issues converging your model consider:\n", + "\n", + " prepare_degeneracy_hunter()\n", + " prepare_svd_toolbox()\n", + "\n", + "====================================================================================\n" + ] + } + ], + "source": [ + "scaler_obj = SolventReboilerScaler(overwrite=True)\n", + "scaler_obj.scale_model(m.fs.unit)\n", + "reboiler_init.initialize(m.fs.unit)\n", + "dt = DiagnosticsToolbox(m)\n", + "dt.report_numerical_issues()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The condition number decreased by a factor of 18, which is less than what we might have hoped for. Let's check out the SVD toolbox again." + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "====================================================================================\n", + "Constraints and Variables associated with smallest singular values\n", + "\n", + " 1st Smallest Singular Value: 6.965e-04\n", + "\n", + " Variables:\n", + "\n", + " fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[bicarbonate]\n", + " fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[carbamate]\n", + " fs.unit.liquid_phase.properties_out[0.0].apparent_inherent_reaction_extent[carbamate]\n", + "\n", + " Constraints:\n", + "\n", + " fs.unit.unit_material_balance[0.0,CO2]\n", + " fs.unit.unit_material_balance[0.0,H2O]\n", + " fs.unit.liquid_phase.material_balances[0.0,H2O]\n", + " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].total_flow_balance\n", + " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", + "\n", + " 2nd Smallest Singular Value: 1.047e-03\n", + "\n", + " Variables:\n", + "\n", + " fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[carbamate]\n", + " fs.unit.liquid_phase.properties_out[0.0].apparent_inherent_reaction_extent[carbamate]\n", + "\n", + " Constraints:\n", + "\n", + " fs.unit.unit_material_balance[0.0,CO2]\n", + " fs.unit.unit_material_balance[0.0,H2O]\n", + " fs.unit.liquid_phase.material_balances[0.0,H2O]\n", + " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEA_+]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA_+]\n", + "\n", + " 3rd Smallest Singular Value: 4.024e-03\n", + "\n", + " Variables:\n", + "\n", + " fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[bicarbonate]\n", + " fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[carbamate]\n", + "\n", + " Constraints:\n", + "\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,H2O]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,H2O]\n", + " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,H2O]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", + "\n", + " 4th Smallest Singular Value: 5.218e-03\n", + "\n", + " Variables:\n", + "\n", + " fs.unit.liquid_phase.properties_out[0.0].apparent_inherent_reaction_extent[bicarbonate]\n", + "\n", + " Constraints:\n", + "\n", + " fs.unit.unit_material_balance[0.0,CO2]\n", + " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,HCO3_-]\n", + "\n", + " 5th Smallest Singular Value: 5.115e-02\n", + "\n", + " Variables:\n", + "\n", + " fs.unit.vapor_phase[0.0].flow_mol_phase[Vap]\n", + " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_comp[CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_comp[H2O]\n", + " fs.unit.vapor_phase[0.0].flow_mol\n", + "\n", + " Constraints:\n", + "\n", + " fs.unit.unit_material_balance[0.0,CO2]\n", + " fs.unit.unit_material_balance[0.0,H2O]\n", + " fs.unit.liquid_phase.material_balances[0.0,H2O]\n", + " fs.unit.liquid_phase.material_balances[0.0,MEA]\n", + " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEA_+]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA_+]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA]\n", + " fs.unit.unit_material_balance[0.0,MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].total_flow_balance\n", + " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA_+]\n", + " fs.unit.liquid_phase.properties_out[0.0].sum_mole_frac_out\n", + " fs.unit.vapor_phase[0.0].sum_mole_frac_out\n", + "\n", + "====================================================================================\n" + ] + } + ], + "source": [ + "st = dt.prepare_svd_toolbox()\n", + "st.display_underdetermined_variables_and_constraints([1, 2, 3, 4, 5])" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": {}, + "outputs": [], + "source": [ + "assert st.s[0] == pytest.approx(6.965e-04, rel=1e-2)\n", + "assert st.s[3] == pytest.approx(5.218e-03, rel=1e-2)\n", + "assert st.s[4] == pytest.approx(5.115e-02, rel=1e-2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can see an order-of-magnitude difference between the first four smallest singular values and the fifth-smallest singular value. Inspecting the variables and constraints involved, they all involve the inherent reaction calculations for ionic speciation. Improving the scaling of those variables and constraints might improve the condition number by another one to two orders of magnitude. However, we are reaching the point of diminishing returns for scaling. We can leave the scaler here unless a solver failure forces us to revisit it again.\n", + "\n", + "## Step 7: Reviewing Model Scaling\n", + "\n", + "Before we conclude entirely, let's take a look at all the variable and constraint scaling factors used." + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Scaling Factors for block fs.unit\n", + "\n", + "Variable Scaling Factor Value Scaled Value\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol 1.250E-02 8.389E+01 1.049E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[H2O] 1.000E+00 8.589E-01 8.589E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[MEA] 1.000E+01 1.085E-01 1.085E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[CO2] 1.000E+01 3.260E-02 3.260E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].temperature 3.333E-03 3.925E+02 1.308E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol 1.250E-02 7.410E+01 9.263E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O] 1.000E+00 8.487E-01 8.487E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] 1.000E+01 1.228E-01 1.228E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[CO2] 1.000E+01 2.851E-02 2.851E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].temperature 3.333E-03 3.938E+02 1.313E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", + "fs.unit.vapor_phase[0.0].flow_mol 1.000E-01 9.785E+00 9.785E-01\n", + "fs.unit.vapor_phase[0.0].mole_frac_comp[CO2] 1.000E+01 6.361E-02 6.361E-01\n", + "fs.unit.vapor_phase[0.0].mole_frac_comp[H2O] 1.000E+01 9.364E-01 9.364E+00\n", + "fs.unit.vapor_phase[0.0].mole_frac_comp[N2] 1.000E+01 1.022E-09 1.022E-08\n", + "fs.unit.vapor_phase[0.0].mole_frac_comp[O2] 1.000E+01 1.022E-09 1.022E-08\n", + "fs.unit.vapor_phase[0.0].temperature 3.333E-03 3.938E+02 1.313E+00\n", + "fs.unit.vapor_phase[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", + "fs.unit.liquid_phase.heat[0.0] 8.763E-07 4.306E+05 3.773E-01\n", + "fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,H2O] 1.250E-02 -9.163E+00 -1.145E-01\n", + "fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,MEA] 1.250E-01 0.000E+00 0.000E+00\n", + "fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,CO2] 1.250E-01 -6.224E-01 -7.780E-02\n", + "fs.unit.liquid_phase.enthalpy_transfer[0.0] 8.763E-07 -3.209E+04 -2.812E-02\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase[Liq] 1.250E-02 8.389E+01 1.049E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp[Liq,H2O] 1.000E+00 8.589E-01 8.589E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp[Liq,MEA] 1.000E+01 1.085E-01 1.085E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp[Liq,CO2] 1.000E+01 3.260E-02 3.260E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].phase_frac[Liq] 1.000E+00 1.000E+00 1.000E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,MEACOO_-] 1.250E-01 2.550E+00 3.187E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,HCO3_-] 1.250E+00 1.785E-01 2.231E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,MEA_+] 1.250E-01 2.728E+00 3.410E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,H2O] 1.250E-02 7.187E+01 8.984E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,MEA] 1.250E-01 3.825E+00 4.781E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,CO2] 1.250E+02 6.803E-03 8.504E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,MEACOO_-] 1.000E+01 3.141E-02 3.141E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,HCO3_-] 1.000E+02 2.199E-03 2.199E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,MEA_+] 1.000E+01 3.361E-02 3.361E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,H2O] 1.000E+00 8.856E-01 8.856E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,MEA] 1.000E+01 4.712E-02 4.712E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,CO2] 1.000E+04 8.383E-05 8.383E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[bicarbonate] 1.250E+02 1.785E-01 2.231E+01\n", + "fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[carbamate] 1.250E+02 2.550E+00 3.187E+02\n", + "fs.unit.liquid_phase.properties_in[0.0].log_k_eq[bicarbonate] None -7.578E+00 -7.578E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].log_k_eq[carbamate] None -1.985E+00 -1.985E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-] 1.000E+00 7.168E+00 7.168E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-] 1.000E+00 4.509E+00 4.509E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+] 1.000E+00 7.236E+00 7.236E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,H2O] 1.000E+00 1.051E+01 1.051E+01\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEA] 1.000E+00 7.573E+00 7.573E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,CO2] 1.000E+00 1.242E+00 1.242E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase[Liq] 1.250E-02 7.410E+01 9.263E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,H2O] 1.000E+00 8.487E-01 8.487E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,MEA] 1.000E+01 1.228E-01 1.228E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,CO2] 1.000E+01 2.851E-02 2.851E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].phase_frac[Liq] 1.000E+00 1.000E+00 1.000E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,MEACOO_-] 1.250E-01 2.013E+00 2.516E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,HCO3_-] 1.250E+00 9.684E-02 1.210E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,MEA_+] 1.250E-01 2.110E+00 2.637E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,H2O] 1.250E-02 6.279E+01 7.849E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,MEA] 1.250E-01 4.979E+00 6.224E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,CO2] 1.250E+02 2.455E-03 3.069E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,MEACOO_-] 1.000E+01 2.796E-02 2.796E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,HCO3_-] 1.000E+02 1.345E-03 1.345E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,MEA_+] 1.000E+01 2.931E-02 2.931E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,H2O] 1.000E+00 8.722E-01 8.722E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,MEA] 1.000E+01 6.916E-02 6.916E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,CO2] 1.000E+04 3.410E-05 3.410E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].apparent_inherent_reaction_extent[bicarbonate] 1.250E+02 9.684E-02 1.210E+01\n", + "fs.unit.liquid_phase.properties_out[0.0].apparent_inherent_reaction_extent[carbamate] 1.250E+02 2.013E+00 2.516E+02\n", + "fs.unit.liquid_phase.properties_out[0.0].log_k_eq[bicarbonate] None -7.648E+00 -7.648E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].log_k_eq[carbamate] None -2.079E+00 -2.079E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-] 1.000E+00 7.024E+00 7.024E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-] 1.000E+00 3.989E+00 3.989E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+] 1.000E+00 7.071E+00 7.071E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,H2O] 1.000E+00 1.046E+01 1.046E+01\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA] 1.000E+00 7.929E+00 7.929E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2] 1.000E+00 3.147E-01 3.147E-01\n", + "fs.unit.vapor_phase[0.0].flow_mol_phase[Vap] 1.000E-01 9.785E+00 9.785E-01\n", + "fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2] 1.000E+01 6.361E-02 6.361E-01\n", + "fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O] 1.000E+01 9.364E-01 9.364E+00\n", + "fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,N2] 1.000E+01 1.022E-09 1.022E-08\n", + "fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,O2] 1.000E+01 1.022E-09 1.022E-08\n", + "fs.unit.vapor_phase[0.0].phase_frac[Vap] 1.000E+00 1.000E+00 1.000E+00\n", + "\n", + "Constraint Scaling Factor\n", + "fs.unit.unit_material_balance[0.0,CO2] 1.250E-01\n", + "fs.unit.unit_material_balance[0.0,H2O] 1.250E-02\n", + "fs.unit.unit_material_balance[0.0,N2] 1.000E+00\n", + "fs.unit.unit_material_balance[0.0,O2] 1.000E+00\n", + "fs.unit.unit_material_balance[0.0,MEA] 1.250E-01\n", + "fs.unit.unit_phase_equilibrium[0.0,CO2] 1.000E-04\n", + "fs.unit.unit_phase_equilibrium[0.0,H2O] 1.000E-04\n", + "fs.unit.unit_temperature_equality[0.0] 3.333E-03\n", + "fs.unit.unit_enthalpy_balance[0.0] 5.463E-06\n", + "fs.unit.unit_pressure_balance[0.0] 1.000E-05\n", + "fs.unit.liquid_phase.material_balances[0.0,H2O] 1.250E-02\n", + "fs.unit.liquid_phase.material_balances[0.0,MEA] 1.250E-01\n", + "fs.unit.liquid_phase.material_balances[0.0,CO2] 1.250E-01\n", + "fs.unit.liquid_phase.enthalpy_balances[0.0] 8.763E-07\n", + "fs.unit.liquid_phase.pressure_balance[0.0] 1.000E-05\n", + "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEACOO_-] 1.250E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,HCO3_-] 1.250E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEA_+] 1.250E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,H2O] 1.250E-02\n", + "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEA] 1.250E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2] 1.250E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEACOO_-] 1.250E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,HCO3_-] 1.250E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEA_+] 1.250E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,H2O] 1.250E-02\n", + "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEA] 1.250E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,CO2] 1.250E+02\n", + "fs.unit.liquid_phase.properties_in[0.0].total_flow_balance 1.250E-02\n", + "fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[H2O] 1.000E+01\n", + "fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[MEA] 1.000E+01\n", + "fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2] 1.000E+01\n", + "fs.unit.liquid_phase.properties_in[0.0].phase_fraction_constraint[Liq] 1.000E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].log_k_eq_constraint[bicarbonate] None\n", + "fs.unit.liquid_phase.properties_in[0.0].log_k_eq_constraint[carbamate] None\n", + "fs.unit.liquid_phase.properties_in[0.0].inherent_equilibrium_constraint[bicarbonate] 1.000E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].inherent_equilibrium_constraint[carbamate] 1.000E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-] 2.377E-04\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-] 2.377E-03\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA_+] 2.377E-04\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,H2O] 2.377E-05\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA] 2.377E-04\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2] 2.377E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEACOO_-] 1.250E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,HCO3_-] 1.250E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA_+] 1.250E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,H2O] 1.250E-02\n", + "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA] 1.250E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2] 1.250E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEACOO_-] 1.250E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,HCO3_-] 1.250E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEA_+] 1.250E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,H2O] 1.250E-02\n", + "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEA] 1.250E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,CO2] 1.250E+02\n", + "fs.unit.liquid_phase.properties_out[0.0].sum_mole_frac_out 1.000E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].total_flow_balance 1.250E-02\n", + "fs.unit.liquid_phase.properties_out[0.0].component_flow_balances[H2O] 1.000E+01\n", + "fs.unit.liquid_phase.properties_out[0.0].component_flow_balances[MEA] 1.000E+01\n", + "fs.unit.liquid_phase.properties_out[0.0].component_flow_balances[CO2] 1.000E+01\n", + "fs.unit.liquid_phase.properties_out[0.0].phase_fraction_constraint[Liq] 1.000E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].log_k_eq_constraint[bicarbonate] None\n", + "fs.unit.liquid_phase.properties_out[0.0].log_k_eq_constraint[carbamate] None\n", + "fs.unit.liquid_phase.properties_out[0.0].inherent_equilibrium_constraint[bicarbonate] 1.000E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].inherent_equilibrium_constraint[carbamate] 1.000E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-] 2.377E-04\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-] 2.377E-03\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA_+] 2.377E-04\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,H2O] 2.377E-05\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA] 2.377E-04\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2] 2.377E-01\n", + "fs.unit.vapor_phase[0.0].sum_mole_frac_out 1.000E+00\n", + "fs.unit.vapor_phase[0.0].total_flow_balance 1.000E-01\n", + "fs.unit.vapor_phase[0.0].component_flow_balances[CO2] 1.000E+01\n", + "fs.unit.vapor_phase[0.0].component_flow_balances[H2O] 1.000E+01\n", + "fs.unit.vapor_phase[0.0].component_flow_balances[N2] 1.000E+01\n", + "fs.unit.vapor_phase[0.0].component_flow_balances[O2] 1.000E+01\n", + "fs.unit.vapor_phase[0.0].phase_fraction_constraint[Vap] 1.000E+00\n", + "\n", + "Expression Scaling Hint\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp[Liq,H2O] 1.250E-02\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp[Liq,MEA] 1.250E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp[Liq,CO2] 1.250E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].k_eq[bicarbonate] None\n", + "fs.unit.liquid_phase.properties_in[0.0].k_eq[carbamate] None\n", + "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,MEACOO_-] None\n", + "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,HCO3_-] None\n", + "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,MEA_+] None\n", + "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,H2O] None\n", + "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,MEA] None\n", + "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,CO2] None\n", + "fs.unit.liquid_phase.properties_in[0.0].dens_mol_phase[Liq] 2.377E-05\n", + "fs.unit.liquid_phase.properties_in[0.0].vol_mol_phase[Liq] 4.206E+04\n", + "fs.unit.liquid_phase.properties_in[0.0]._enthalpy_flow_term[Liq] None\n", + "fs.unit.liquid_phase.properties_in[0.0].enth_mol_phase[Liq] 7.010E-05\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_comp[H2O] 1.250E-02\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_comp[MEA] 1.250E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_comp[CO2] 1.250E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp[Liq,H2O] 1.250E-02\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp[Liq,MEA] 1.250E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp[Liq,CO2] 1.250E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].k_eq[bicarbonate] None\n", + "fs.unit.liquid_phase.properties_out[0.0].k_eq[carbamate] None\n", + "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,MEACOO_-] None\n", + "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,HCO3_-] None\n", + "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,MEA_+] None\n", + "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,H2O] None\n", + "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,MEA] None\n", + "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,CO2] None\n", + "fs.unit.liquid_phase.properties_out[0.0].dens_mol_phase[Liq] 2.377E-05\n", + "fs.unit.liquid_phase.properties_out[0.0].vol_mol_phase[Liq] 4.206E+04\n", + "fs.unit.liquid_phase.properties_out[0.0]._enthalpy_flow_term[Liq] None\n", + "fs.unit.liquid_phase.properties_out[0.0].enth_mol_phase[Liq] 7.010E-05\n", + "fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[Liq,H2O] None\n", + "fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[Liq,MEA] None\n", + "fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[Liq,CO2] None\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_comp[H2O] 1.250E-02\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_comp[MEA] 1.250E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_comp[CO2] 1.250E-01\n", + "fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,CO2] 1.000E+00\n", + "fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,H2O] 1.000E+00\n", + "fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,N2] 1.000E+00\n", + "fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,O2] 1.000E+00\n", + "fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,CO2] None\n", + "fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,H2O] None\n", + "fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,N2] None\n", + "fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,O2] None\n", + "fs.unit.vapor_phase[0.0]._enthalpy_flow_term[Vap] None\n", + "fs.unit.vapor_phase[0.0].enth_mol_phase[Vap] 5.463E-05\n", + "fs.unit.vapor_phase[0.0].enth_mol_phase_comp[Vap,CO2] 3.787E-05\n", + "fs.unit.vapor_phase[0.0].enth_mol_phase_comp[Vap,H2O] 9.249E-05\n", + "fs.unit.vapor_phase[0.0].enth_mol_phase_comp[Vap,N2] 5.950E-05\n", + "fs.unit.vapor_phase[0.0].enth_mol_phase_comp[Vap,O2] 5.208E-05\n", + "fs.unit.vapor_phase[0.0].flow_mol_comp[CO2] 1.000E+00\n", + "fs.unit.vapor_phase[0.0].flow_mol_comp[H2O] 1.000E+00\n", + "fs.unit.vapor_phase[0.0].flow_mol_comp[N2] 1.000E+00\n", + "fs.unit.vapor_phase[0.0].flow_mol_comp[O2] 1.000E+00\n" + ] + } + ], + "source": [ + "from idaes.core.scaling.util import report_scaling_factors\n", + "\n", + "report_scaling_factors(m.fs.unit, descend_into=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Most variable values have scaled values within a couple orders of magnitude of one, which is what we like. The outliers are inherent reaction extents, which we already know are a bit problematic, and variables corresponding to the components $\\text{N}_2$ and $\\text{O}_2$, which are present in the vapor property package but not the vapor stream.\n", + "\n", + "We have reduced the condition number to $3 \\cdot 10^5$, which is not quite as low as we would have liked, but is a vast improvement over the value $3 \\cdot 10^{13}$, which we started out with. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# References\n", + "\n", + "[[1](https://doi.org/10.1016/j.compchemeng.2025.109312)] Allan, D. A., Ostace, A. G., & Polley, T. (2025). Jacobian-based model diagnostics and application to equation oriented modeling of a carbon capture system. Computers & Chemical Engineering, 109312.\n", + "\n", + "[[2](https://link.springer.com/article/10.1007/S10107-004-0559-Y)] W\u00e4chter, A., & Biegler, L. T. (2006). On the implementation of an interior-point filter line-search algorithm for large-scale nonlinear programming. Mathematical programming, 106(1), 25-57." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.12" + } + }, + "nbformat": 4, + "nbformat_minor": 3 +} \ No newline at end of file diff --git a/idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques_test.ipynb b/idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques_test.ipynb new file mode 100644 index 00000000..bc14bdac --- /dev/null +++ b/idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques_test.ipynb @@ -0,0 +1,3224 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "###############################################################################\n", + "# The Institute for the Design of Advanced Energy Systems Integrated Platform\n", + "# Framework (IDAES IP) was produced under the DOE Institute for the\n", + "# Design of Advanced Energy Systems (IDAES).\n", + "#\n", + "# Copyright (c) 2018-2026 by the software owners: The Regents of the\n", + "# University of California, through Lawrence Berkeley National Laboratory,\n", + "# National Technology & Engineering Solutions of Sandia, LLC, Carnegie Mellon\n", + "# University, West Virginia University Research Corporation, et al.\n", + "# All rights reserved. Please see the files COPYRIGHT.md and LICENSE.md\n", + "# for full copyright and license information.\n", + "###############################################################################" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Advanced Scaling Techniques\n", + "\n", + "Author: Doug Allan\\\n", + "Maintainer: Doug Allan\\\n", + "Updated: 2026-04-30\n", + "\n", + "## Introduction\n", + "\n", + "This notebook is intended to give the user further insight into how the scaling toolbox can be used to improve robustness. A large portion of the material is an adaptation of [Allan, Ostace, and Polly (2025)](#references). By the end of this study, the user should understand:\n", + "* How a default scaler object can be specified for a property package\n", + "* How to set default scaling factors for property package variables\n", + "* The strengths and weaknesses of the ``NominalValueExpressionWalker`` used in ``CustomScalerBase.get_sum_terms_nominal_values`` and ``CustomScalerBase.get_expression_nominal_value`` for use in constraint scaling\n", + "* How to use the ``SVDToolbox`` to troubleshoot scaling issues\n", + "\n", + "## Step 1: Set Up Test Case\n", + "We will use the `SolventReboiler` unit model as a case study. It is a component in a stripping column used for solvent regeneration. It is modeled as a single equilibrium stage with an external heat duty. The inlet stream is entirely liquid, while it has both boilup and bottoms outlet streams. The liquid and vapor phases use different configurations of the modular property framework.\n", + "\n", + "First, we set up and attempt to initialize the unit model." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2026-04-29 17:11:54 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Starting initialization routine\n", + "2026-04-29 17:11:54 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Bubble, dew, and critical point initialization completed.\n", + "2026-04-29 17:11:54 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Equilibrium temperature initialization completed.\n", + "2026-04-29 17:11:54 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: State variable initialization completed.\n", + "2026-04-29 17:11:54 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Phase equilibrium initialization completed.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Ipopt 3.13.2: linear_solver=\"ma57\"\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: max_iter=200\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: nlp_scaling_method=\"gradient-based\"\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: tol=1e-06\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: ******************************************************************************\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: For more information visit http://projects.coin-or.org/Ipopt\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: This version of Ipopt was compiled from source code available at\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: for large-scale scientific computation. All technical papers, sales and\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: publicity material resulting from use of the HSL codes within IPOPT must\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: contain the following acknowledgement:\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: HSL, a collection of Fortran codes for large-scale scientific\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: computation. See http://www.hsl.rl.ac.uk.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: ******************************************************************************\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of nonzeros in equality constraint Jacobian...: 74\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of nonzeros in inequality constraint Jacobian.: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of nonzeros in Lagrangian Hessian.............: 42\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Total number of variables............................: 18\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: variables with only lower bounds: 6\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: variables with lower and upper bounds: 12\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: variables with only upper bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Total number of equality constraints.................: 18\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Total number of inequality constraints...............: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: inequality constraints with only lower bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: inequality constraints with lower and upper bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: inequality constraints with only upper bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 0 0.0000000e+00 4.13e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Reallocating memory for MA57: lfact (1377)\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 1 0.0000000e+00 4.05e+02 1.89e+12 -1.0 6.07e+01 - 1.92e-01 1.98e-02H 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 2 0.0000000e+00 1.62e+04 1.56e+17 -1.0 8.76e+01 - 1.69e-01 5.07e-01H 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 3 0.0000000e+00 1.62e+04 1.55e+17 -1.0 4.59e+01 - 1.21e-07 3.23e-03H 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 4 0.0000000e+00 2.15e+04 1.93e+17 -1.0 4.88e+01 - 1.06e-02 9.12e-01h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Reallocating memory for MA57: lfact (1542)\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 5 0.0000000e+00 2.15e+04 1.93e+17 -1.0 3.05e+02 - 4.08e-04 6.58e-04h 2\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Reallocating memory for MA57: lfact (1662)\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 6 0.0000000e+00 2.09e+04 1.87e+17 -1.0 1.11e+01 - 4.04e-03 3.08e-02h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 7 0.0000000e+00 1.50e+04 1.37e+17 -1.0 1.37e+01 - 1.44e-04 3.14e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 8 0.0000000e+00 1.49e+04 1.36e+17 -1.0 4.21e+00 - 5.37e-01 9.11e-03h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 9 0.0000000e+00 1.49e+04 1.36e+17 -1.0 4.10e+00 - 9.86e-01 9.35e-05h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 10r 0.0000000e+00 1.49e+04 1.00e+03 1.6 0.00e+00 - 0.00e+00 4.68e-07R 2\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 11r 0.0000000e+00 5.25e+03 2.22e+03 1.6 3.13e+04 - 3.88e-03 1.14e-03f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 12r 0.0000000e+00 5.08e+03 4.24e+04 1.6 1.22e+03 - 1.88e-01 5.18e-03f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 13r 0.0000000e+00 4.77e+03 3.36e+04 1.6 6.27e+01 - 3.06e-02 6.76e-02f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 14r 0.0000000e+00 4.33e+03 1.32e+05 1.6 8.06e+00 - 5.05e-01 9.81e-02f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 15r 0.0000000e+00 4.19e+03 1.12e+05 1.6 9.20e+00 - 3.38e-01 3.25e-02f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 16r 0.0000000e+00 1.89e+03 5.50e+04 1.6 2.54e+00 - 8.42e-02 7.08e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 17r 0.0000000e+00 1.72e+03 4.73e+04 1.6 7.82e+00 - 2.36e-01 1.01e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 18r 0.0000000e+00 1.14e+03 2.84e+04 1.6 1.92e+00 - 7.10e-01 4.02e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 19r 0.0000000e+00 1.06e+03 2.92e+04 1.6 5.12e+00 - 7.85e-01 7.79e-02f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 20r 0.0000000e+00 2.69e+02 3.66e+03 1.6 5.52e-01 - 1.00e+00 9.33e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 21r 0.0000000e+00 1.64e+01 3.96e+02 0.9 1.63e-01 - 9.76e-01 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 22r 0.0000000e+00 6.87e-01 1.09e+02 0.2 3.52e-02 - 1.00e+00 9.59e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 23r 0.0000000e+00 2.05e-01 8.47e+03 -0.5 2.72e-03 - 1.00e+00 6.98e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 24r 0.0000000e+00 1.34e-03 2.18e-01 -0.5 1.87e-03 - 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 25r 0.0000000e+00 1.29e-02 1.88e+02 -2.9 3.36e-04 - 1.00e+00 9.47e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 26r 0.0000000e+00 2.90e-06 4.04e-05 -2.9 7.48e-05 - 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of Iterations....: 26\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: (scaled) (unscaled)\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Constraint violation....: 2.1131334015933589e-08 2.8957967970200116e-06\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Overall NLP error.......: 2.1131334015933589e-08 2.8957967970200116e-06\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of objective function evaluations = 34\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of objective gradient evaluations = 12\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of equality constraint evaluations = 36\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of inequality constraint evaluations = 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of equality constraint Jacobian evaluations = 28\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of inequality constraint Jacobian evaluations = 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of Lagrangian Hessian evaluations = 26\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Total CPU secs in IPOPT (w/o function evaluations) = 0.006\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Total CPU secs in NLP function evaluations = 0.000\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: EXIT: Optimal Solution Found.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Property initialization routine finished.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Starting initialization routine\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Bubble, dew, and critical point initialization completed.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Equilibrium temperature initialization completed.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: State variable initialization completed.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Phase equilibrium initialization completed.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Ipopt 3.13.2: linear_solver=\"ma57\"\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: max_iter=200\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: nlp_scaling_method=\"gradient-based\"\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: tol=1e-06\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: ******************************************************************************\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: For more information visit http://projects.coin-or.org/Ipopt\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: This version of Ipopt was compiled from source code available at\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: for large-scale scientific computation. All technical papers, sales and\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: publicity material resulting from use of the HSL codes within IPOPT must\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: contain the following acknowledgement:\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: HSL, a collection of Fortran codes for large-scale scientific\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: computation. See http://www.hsl.rl.ac.uk.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: ******************************************************************************\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of nonzeros in equality constraint Jacobian...: 74\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of nonzeros in inequality constraint Jacobian.: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of nonzeros in Lagrangian Hessian.............: 42\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Total number of variables............................: 18\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: variables with only lower bounds: 6\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: variables with lower and upper bounds: 12\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: variables with only upper bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Total number of equality constraints.................: 18\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Total number of inequality constraints...............: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: inequality constraints with only lower bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: inequality constraints with lower and upper bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: inequality constraints with only upper bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 0 0.0000000e+00 4.13e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Reallocating memory for MA57: lfact (1377)\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 1 0.0000000e+00 4.05e+02 1.89e+12 -1.0 6.07e+01 - 1.92e-01 1.98e-02H 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 2 0.0000000e+00 1.62e+04 1.56e+17 -1.0 8.76e+01 - 1.69e-01 5.07e-01H 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 3 0.0000000e+00 1.62e+04 1.55e+17 -1.0 4.59e+01 - 1.21e-07 3.23e-03H 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 4 0.0000000e+00 2.15e+04 1.93e+17 -1.0 4.88e+01 - 1.06e-02 9.12e-01h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Reallocating memory for MA57: lfact (1542)\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 5 0.0000000e+00 2.15e+04 1.93e+17 -1.0 3.05e+02 - 4.08e-04 6.58e-04h 2\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Reallocating memory for MA57: lfact (1662)\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 6 0.0000000e+00 2.09e+04 1.87e+17 -1.0 1.11e+01 - 4.04e-03 3.08e-02h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 7 0.0000000e+00 1.50e+04 1.37e+17 -1.0 1.37e+01 - 1.44e-04 3.14e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 8 0.0000000e+00 1.49e+04 1.36e+17 -1.0 4.21e+00 - 5.37e-01 9.11e-03h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 9 0.0000000e+00 1.49e+04 1.36e+17 -1.0 4.10e+00 - 9.86e-01 9.35e-05h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 10r 0.0000000e+00 1.49e+04 1.00e+03 1.6 0.00e+00 - 0.00e+00 4.68e-07R 2\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 11r 0.0000000e+00 5.25e+03 2.22e+03 1.6 3.13e+04 - 3.88e-03 1.14e-03f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 12r 0.0000000e+00 5.08e+03 4.24e+04 1.6 1.22e+03 - 1.88e-01 5.18e-03f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 13r 0.0000000e+00 4.77e+03 3.36e+04 1.6 6.27e+01 - 3.06e-02 6.76e-02f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 14r 0.0000000e+00 4.33e+03 1.32e+05 1.6 8.06e+00 - 5.05e-01 9.81e-02f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 15r 0.0000000e+00 4.19e+03 1.12e+05 1.6 9.20e+00 - 3.38e-01 3.25e-02f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 16r 0.0000000e+00 1.89e+03 5.50e+04 1.6 2.54e+00 - 8.42e-02 7.08e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 17r 0.0000000e+00 1.72e+03 4.73e+04 1.6 7.82e+00 - 2.36e-01 1.01e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 18r 0.0000000e+00 1.14e+03 2.84e+04 1.6 1.92e+00 - 7.10e-01 4.02e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 19r 0.0000000e+00 1.06e+03 2.92e+04 1.6 5.12e+00 - 7.85e-01 7.79e-02f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 20r 0.0000000e+00 2.69e+02 3.66e+03 1.6 5.52e-01 - 1.00e+00 9.33e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 21r 0.0000000e+00 1.64e+01 3.96e+02 0.9 1.63e-01 - 9.76e-01 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 22r 0.0000000e+00 6.87e-01 1.09e+02 0.2 3.52e-02 - 1.00e+00 9.59e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 23r 0.0000000e+00 2.05e-01 8.47e+03 -0.5 2.72e-03 - 1.00e+00 6.98e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 24r 0.0000000e+00 1.34e-03 2.18e-01 -0.5 1.87e-03 - 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 25r 0.0000000e+00 1.29e-02 1.88e+02 -2.9 3.36e-04 - 1.00e+00 9.47e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 26r 0.0000000e+00 2.90e-06 4.04e-05 -2.9 7.48e-05 - 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of Iterations....: 26\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: (scaled) (unscaled)\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Constraint violation....: 2.1131334015933589e-08 2.8957967970200116e-06\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Overall NLP error.......: 2.1131334015933589e-08 2.8957967970200116e-06\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of objective function evaluations = 34\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of objective gradient evaluations = 12\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of equality constraint evaluations = 36\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of inequality constraint evaluations = 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of equality constraint Jacobian evaluations = 28\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of inequality constraint Jacobian evaluations = 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of Lagrangian Hessian evaluations = 26\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Total CPU secs in IPOPT (w/o function evaluations) = 0.008\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Total CPU secs in NLP function evaluations = 0.000\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: EXIT: Optimal Solution Found.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Property initialization routine finished.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase: Control volume properties initialization complete\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase: Control volume reactions initialization complete\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit: Initialization Step 1 Complete.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: Starting initialization routine\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: Bubble, dew, and critical point initialization completed.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: Equilibrium temperature initialization completed.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: State variable initialization completed.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: Phase equilibrium initialization completed.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: Property initialization routine finished.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit: Initialization Step 2 Complete.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Ipopt 3.13.2: linear_solver=\"ma57\"\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: max_iter=200\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: nlp_scaling_method=\"gradient-based\"\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: tol=1e-06\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: ******************************************************************************\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: For more information visit http://projects.coin-or.org/Ipopt\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: This version of Ipopt was compiled from source code available at\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: for large-scale scientific computation. All technical papers, sales and\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: publicity material resulting from use of the HSL codes within IPOPT must\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: contain the following acknowledgement:\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: HSL, a collection of Fortran codes for large-scale scientific\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: computation. See http://www.hsl.rl.ac.uk.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: ******************************************************************************\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of nonzeros in equality constraint Jacobian...: 231\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of nonzeros in inequality constraint Jacobian.: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of nonzeros in Lagrangian Hessian.............: 149\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Total number of variables............................: 51\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: variables with only lower bounds: 12\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: variables with lower and upper bounds: 34\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: variables with only upper bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Total number of equality constraints.................: 51\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Total number of inequality constraints...............: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: inequality constraints with only lower bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: inequality constraints with lower and upper bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: inequality constraints with only upper bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 0 0.0000000e+00 3.62e+06 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Reallocating memory for MA57: lfact (3323)\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 1 0.0000000e+00 3.00e+06 1.18e+02 -1.0 3.71e+04 - 5.00e-01 1.73e-01h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 2 0.0000000e+00 2.99e+06 3.06e+03 -1.0 2.81e+04 - 8.76e-01 3.30e-03h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 3 0.0000000e+00 2.99e+06 8.95e+07 -1.0 2.80e+04 - 9.79e-01 3.34e-05h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 4r 0.0000000e+00 2.99e+06 1.00e+03 1.9 0.00e+00 - 0.00e+00 1.74e-07R 2\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 5r 0.0000000e+00 2.93e+06 9.98e+02 1.9 3.19e+04 - 2.43e-03 2.43e-03f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 6r 0.0000000e+00 2.86e+06 1.02e+03 1.2 3.69e+02 - 3.26e-01 2.09e-03f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 7r 0.0000000e+00 2.23e+06 1.04e+03 1.2 2.85e+02 - 1.93e-01 8.65e-02f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 8r 0.0000000e+00 1.90e+06 1.12e+05 1.2 2.94e+02 - 7.31e-02 2.42e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 9r 0.0000000e+00 1.44e+06 7.08e+04 1.2 1.51e+02 - 7.79e-01 2.13e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 10r 0.0000000e+00 1.21e+06 3.79e+04 1.2 1.60e+00 2.0 4.46e-01 1.46e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 11r 0.0000000e+00 7.63e+04 1.14e+04 1.2 9.97e+01 - 3.46e-01 9.00e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 12r 0.0000000e+00 4.57e+04 2.79e+04 1.2 8.49e+01 - 1.00e+00 2.61e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 13r 0.0000000e+00 5.79e+04 9.55e+03 1.2 3.35e+01 - 1.00e+00 7.44e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 14r 0.0000000e+00 1.21e+05 1.45e+04 1.2 2.11e+01 - 1.00e+00 1.00e+00h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 15r 0.0000000e+00 2.24e+05 6.34e+02 1.2 7.86e+00 - 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 16r 0.0000000e+00 2.19e+05 4.22e+03 0.5 1.77e+00 - 1.00e+00 9.43e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 17r 0.0000000e+00 3.93e+05 6.53e+02 0.5 1.02e+02 - 5.02e-01 4.46e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 18r 0.0000000e+00 4.24e+05 4.17e+03 0.5 1.55e+01 - 1.00e+00 2.17e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 19r 0.0000000e+00 4.87e+05 1.47e+01 0.5 7.37e+00 - 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 20r 0.0000000e+00 5.23e+05 2.31e+03 -0.9 1.53e+00 - 9.40e-01 7.50e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 21r 0.0000000e+00 5.39e+05 7.30e+03 -0.9 2.08e+02 - 8.07e-01 3.86e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 22r 0.0000000e+00 5.39e+05 5.05e+03 -0.9 1.37e+02 - 1.00e+00 4.43e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 23r 0.0000000e+00 5.38e+05 7.93e+00 -0.9 7.27e+01 - 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 24r 0.0000000e+00 5.39e+05 1.75e-03 -0.9 2.41e-01 - 1.00e+00 1.00e+00h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 25r 0.0000000e+00 5.44e+05 2.59e+01 -3.6 3.79e+00 - 9.90e-01 9.73e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 26r 0.0000000e+00 4.44e+05 3.73e+02 -3.6 6.08e+03 - 7.62e-02 6.44e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 27r 0.0000000e+00 3.34e+05 7.09e+02 -3.6 2.85e+03 - 5.42e-02 9.37e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 28r 0.0000000e+00 2.87e+03 9.51e+02 -3.6 1.42e+03 - 1.73e-01 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 29r 0.0000000e+00 8.65e+04 2.35e+02 -3.6 1.10e+03 - 1.00e+00 1.00e+00H 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 30r 0.0000000e+00 8.28e+04 4.88e-01 -3.6 1.19e+02 - 1.00e+00 1.00e+00h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 31r 0.0000000e+00 8.28e+04 9.25e-05 -3.6 2.69e-01 - 1.00e+00 1.00e+00h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 32r 0.0000000e+00 8.28e+04 2.10e+00 -5.4 5.64e-02 - 1.00e+00 9.70e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 33r 0.0000000e+00 8.28e+04 2.49e+02 -5.4 1.00e-03 1.5 8.85e-01 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 34r 0.0000000e+00 8.27e+04 3.33e-02 -5.4 3.00e-03 1.0 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 35r 0.0000000e+00 8.27e+04 3.31e-02 -5.4 8.93e-03 0.6 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 36r 0.0000000e+00 8.26e+04 3.24e-02 -5.4 2.63e-02 0.1 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 37r 0.0000000e+00 8.23e+04 3.06e-02 -5.4 7.43e-02 -0.4 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 38r 0.0000000e+00 8.16e+04 2.59e-02 -5.4 1.89e-01 -0.9 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 39r 0.0000000e+00 8.02e+04 4.92e-02 -5.4 3.67e-01 -1.3 1.00e+00 1.00e+00h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 40r 0.0000000e+00 7.85e+04 6.76e-02 -5.4 1.01e+00 -1.8 1.00e+00 1.00e+00h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 41r 0.0000000e+00 7.76e+04 2.21e-02 -5.4 3.03e+00 -2.3 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 42r 0.0000000e+00 7.73e+04 1.54e-02 -5.4 9.07e+00 -2.8 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 43r 0.0000000e+00 7.69e+04 1.54e-02 -5.4 2.72e+01 -3.2 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 44r 0.0000000e+00 7.57e+04 9.45e-02 -5.4 8.16e+01 -3.7 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 45r 0.0000000e+00 7.21e+04 7.98e-01 -5.4 2.45e+02 -4.2 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 46r 0.0000000e+00 6.17e+04 5.91e+00 -5.4 7.40e+02 -4.7 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 47r 0.0000000e+00 3.69e+04 5.13e+01 -5.4 2.31e+03 -5.2 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 48r 0.0000000e+00 7.15e+04 1.47e+02 -5.4 1.10e+04 -5.6 1.00e+00 2.17e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 49r 0.0000000e+00 7.15e+04 4.98e+02 -5.4 4.07e+03 -5.2 1.00e+00 5.56e-06h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 50r 0.0000000e+00 2.07e+05 4.58e+03 -5.4 2.01e+04 -5.7 4.61e-01 1.75e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 51r 0.0000000e+00 1.19e+06 4.31e+04 -5.4 9.31e+03 -5.3 2.11e-06 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 52r 0.0000000e+00 1.16e+06 3.63e+04 -5.4 1.14e+02 -0.3 4.01e-01 1.23e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 53r 0.0000000e+00 1.16e+06 3.63e+04 -5.4 2.83e+01 0.1 7.36e-01 7.74e-07h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 54r 0.0000000e+00 1.16e+06 3.63e+04 -5.4 3.94e+03 - 1.59e-01 7.41e-06h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 55r 0.0000000e+00 7.95e+05 2.50e+04 -5.4 4.00e+03 - 7.84e-01 3.17e-01h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 56r 0.0000000e+00 3.83e+05 1.19e+04 -5.4 1.69e+03 - 1.35e-05 5.23e-01h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 57r 0.0000000e+00 2.95e+05 9.19e+03 -5.4 9.94e+00 -0.4 5.56e-01 2.31e-01h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 58r 0.0000000e+00 1.29e+04 7.45e+02 -5.4 1.55e+03 - 2.88e-06 1.00e+00h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 59r 0.0000000e+00 1.05e+04 3.57e+00 -5.4 8.95e-02 -0.8 1.00e+00 1.00e+00h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 60r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 7.60e-02 -1.3 1.00e+00 1.00e+00h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 61r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 2.28e-01 -1.8 1.00e+00 2.50e-01h 3\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 62r 0.0000000e+00 1.05e+04 1.03e-02 -5.4 6.84e-01 -2.3 1.00e+00 1.56e-02h 7\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 63r 0.0000000e+00 1.05e+04 3.12e-02 -5.4 2.05e+00 -2.8 1.00e+00 9.77e-04h 11\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 64r 0.0000000e+00 1.05e+04 9.35e-02 -5.4 6.16e+00 -3.2 1.00e+00 1.22e-04h 14\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 65r 0.0000000e+00 1.05e+04 2.81e-01 -5.4 1.85e+01 -3.7 1.00e+00 7.45e-09h 28\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 66r 0.0000000e+00 1.05e+04 8.49e-01 -5.4 5.60e+01 -4.2 1.00e+00 1.86e-09h 30\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 67r 0.0000000e+00 1.05e+04 2.61e+00 -5.4 1.72e+02 -4.7 1.00e+00 1.16e-10h 34\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 68r 0.0000000e+00 1.05e+04 8.40e+00 -5.4 5.54e+02 -5.1 1.00e+00 3.64e-12h 39\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 69r 0.0000000e+00 1.05e+04 8.40e+00 -5.4 2.14e+03 -5.6 0.00e+00 3.59e-18R 58\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 70r 0.0000000e+00 1.05e+04 1.94e+01 -5.4 4.50e+04 -6.1 1.63e-02 1.43e-12f 35\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 71r 0.0000000e+00 1.05e+04 3.85e+01 -5.4 2.54e+03 -5.7 1.00e+00 1.27e-11f 36\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 72r 0.0000000e+00 1.05e+04 1.11e+01 -5.4 7.22e+02 -5.2 9.93e-01 2.91e-11f 36\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 73r 0.0000000e+00 1.05e+04 3.70e+01 -5.4 3.05e+03 -5.7 7.35e-01 1.32e-12f 39\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 74r 0.0000000e+00 1.05e+04 1.25e+01 -5.4 8.27e+02 -5.3 1.00e+00 3.64e-12f 39\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 75r 0.0000000e+00 1.05e+04 3.60e+01 -5.4 3.72e+03 -5.8 5.36e-01 1.35e-13f 42\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 76r 0.0000000e+00 1.05e+04 1.44e+01 -5.4 9.51e+02 -5.3 1.00e+00 1.14e-13f 44\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 77r 0.0000000e+00 1.05e+04 2.35e+01 -5.4 4.61e+03 -5.8 1.64e-01 1.36e-14f 45\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 78r 0.0000000e+00 1.05e+04 1.66e+01 -5.4 1.10e+03 -5.4 1.00e+00 3.55e-15f 49\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 79r 0.0000000e+00 1.05e+04 2.55e+01 -5.4 5.86e+03 -5.9 1.22e-01 3.35e-16f 50\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 80r 0.0000000e+00 2.67e+04 5.84e+01 -5.4 1.27e+03 -5.4 1.00e+00 8.72e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 81r 0.0000000e+00 2.67e+04 2.19e+03 -5.4 1.28e+03 - 4.11e-03 2.62e-05w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 82r 0.0000000e+00 4.42e+04 8.23e+02 -5.4 3.84e+03 -5.9 5.02e-01 4.78e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 83r 0.0000000e+00 1.05e+04 1.92e+01 -5.4 1.21e+04 - 1.00e+00 7.74e-16f 50\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 84r 0.0000000e+00 1.05e+04 2.07e+01 -5.4 1.47e+03 -5.5 4.87e-01 3.33e-16h 52\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 85r 0.0000000e+00 1.05e+04 5.09e+01 -5.4 1.08e+04 -6.0 2.11e-01 1.14e-17f 54\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 86r 0.0000000e+00 1.05e+04 6.78e+01 -5.4 1.72e+03 -5.5 1.00e+00 1.78e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 87r 0.0000000e+00 1.05e+04 1.11e+02 -5.4 1.65e+04 -6.0 4.54e-02 1.86e-18f 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 88r 0.0000000e+00 1.05e+04 2.03e+02 -5.4 2.02e+03 -5.6 1.00e+00 1.52e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 89r 0.0000000e+00 1.05e+04 3.30e+02 -5.4 3.06e+04 -6.1 2.34e-02 1.00e-18f 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 90r 0.0000000e+00 1.05e+04 7.12e+02 -5.4 2.38e+03 -5.7 1.00e+00 1.29e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 91r 0.0000000e+00 1.05e+04 7.29e+02 -5.4 9.01e+04 -6.1 3.00e-04 3.41e-19f 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 92r 0.0000000e+00 1.05e+04 3.99e+01 -5.4 2.95e+03 -5.7 3.70e-01 2.84e-18h 59\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 93r 0.0000000e+00 2.20e+04 3.07e+01 -5.4 7.91e+02 -5.3 1.00e+00 1.00e+00w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 94r 0.0000000e+00 3.01e+04 4.20e+01 -5.4 2.61e+03 -5.8 7.22e-01 2.55e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 95r 0.0000000e+00 3.01e+04 1.37e+03 -5.4 1.07e+03 - 1.99e-03 3.17e-05w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 96r 0.0000000e+00 1.05e+04 1.20e+01 -5.4 7.00e+03 -6.2 1.00e+00 1.78e-15h 49\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 97r 0.0000000e+00 1.05e+04 2.31e+01 -5.4 4.29e+03 -5.8 2.10e-01 6.00e-11f 33\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 98r 0.0000000e+00 1.05e+04 1.59e+01 -5.4 1.05e+03 -5.4 1.00e+00 7.28e-12f 38\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 99r 0.0000000e+00 1.05e+04 2.46e+01 -5.4 5.40e+03 -5.9 1.33e-01 4.76e-11f 33\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 100r 0.0000000e+00 1.05e+04 1.83e+01 -5.4 1.21e+03 -5.4 1.00e+00 1.07e-10f 34\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 101r 0.0000000e+00 1.05e+04 2.73e+01 -5.4 7.03e+03 -5.9 1.02e-01 3.66e-11f 33\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 102r 0.0000000e+00 1.05e+04 2.77e+01 -5.4 1.40e+03 -5.5 1.00e+00 1.43e-12f 40\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 103r 0.0000000e+00 1.05e+04 4.37e+01 -5.4 9.60e+03 -6.0 7.47e-02 5.24e-14f 42\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 104r 0.0000000e+00 1.05e+04 6.49e+01 -5.4 1.63e+03 -5.5 1.00e+00 7.69e-14f 44\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 105r 0.0000000e+00 1.05e+04 1.04e+02 -5.4 1.42e+04 -6.0 5.06e-02 1.11e-15f 47\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 106r 0.0000000e+00 2.67e+04 1.58e+01 -5.4 1.91e+03 -5.6 1.00e+00 5.77e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 107r 0.0000000e+00 2.67e+04 1.40e+03 -5.4 9.67e+02 - 2.90e-03 3.66e-04w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 108r 0.0000000e+00 4.39e+04 4.78e+02 -5.4 5.57e+03 -6.1 3.84e-01 3.25e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 109r 0.0000000e+00 1.05e+04 1.80e+02 -5.4 6.38e+03 - 1.00e+00 4.10e-15f 47\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 110r 0.0000000e+00 1.05e+04 2.40e+02 -5.4 2.26e+03 -5.6 3.17e-01 3.47e-15f 48\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 111r 0.0000000e+00 1.05e+04 5.44e+02 -5.4 6.90e+04 -6.1 2.06e-02 1.14e-16f 48\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 112r 0.0000000e+00 1.05e+04 4.95e+01 -5.4 2.79e+03 -5.7 2.55e-01 7.69e-16f 51\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 113r 0.0000000e+00 1.05e+04 1.15e+01 -5.4 7.57e+02 -5.3 1.00e+00 7.11e-15f 48\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 114r 0.0000000e+00 1.05e+04 2.06e+01 -5.4 3.26e+03 -5.7 2.41e-01 6.02e-16f 50\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 115r 0.0000000e+00 1.05e+04 1.32e+01 -5.4 8.68e+02 -5.3 1.00e+00 2.22e-16h 53\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 116r 0.0000000e+00 1.05e+04 2.17e+01 -5.4 3.99e+03 -5.8 1.79e-01 3.07e-17h 54\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 117r 0.0000000e+00 1.05e+04 1.51e+01 -5.4 9.98e+02 -5.4 1.00e+00 2.78e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 118r 0.0000000e+00 1.05e+04 2.38e+01 -5.4 4.99e+03 -5.8 1.44e-01 6.14e-18h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 119r 0.0000000e+00 2.67e+04 5.98e+01 -5.4 1.15e+03 -5.4 1.00e+00 9.60e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 120r 0.0000000e+00 2.67e+04 2.31e+03 -5.4 1.66e+03 - 4.25e-03 1.30e-05w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 121r 0.0000000e+00 4.43e+04 8.41e+02 -5.4 3.52e+03 -5.9 5.33e-01 5.24e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 122r 0.0000000e+00 1.05e+04 1.75e+01 -5.4 1.31e+04 - 1.00e+00 2.66e-17h 55\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 123r 0.0000000e+00 1.05e+04 1.89e+01 -5.4 1.33e+03 -5.5 5.38e-01 2.30e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 124r 0.0000000e+00 1.05e+04 4.92e+01 -5.4 8.61e+03 -5.9 2.71e-01 3.56e-18h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 125r 0.0000000e+00 1.05e+04 2.98e+01 -5.4 1.55e+03 -5.5 1.00e+00 1.98e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 126r 0.0000000e+00 1.05e+04 4.92e+01 -5.4 1.23e+04 -6.0 6.33e-02 2.48e-18h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 127r 0.0000000e+00 1.05e+04 8.12e+01 -5.4 1.82e+03 -5.6 1.00e+00 1.69e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 128r 0.0000000e+00 1.05e+04 1.31e+02 -5.4 2.00e+04 -6.0 3.59e-02 1.53e-18f 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 129r 0.0000000e+00 1.05e+04 2.54e+02 -5.4 2.14e+03 -5.6 1.00e+00 1.43e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 130r 0.0000000e+00 1.05e+04 4.15e+02 -5.4 4.32e+04 -6.1 1.66e-02 7.10e-19f 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 131r 0.0000000e+00 1.05e+04 9.52e+02 -5.4 2.53e+03 -5.7 1.00e+00 1.21e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 132r 0.0000000e+00 2.67e+04 2.24e+01 -5.4 4.51e+05 -6.1 1.18e-04 2.45e-03w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 133r 0.0000000e+00 4.32e+04 1.53e+02 -5.4 4.75e+04 -6.6 3.50e-02 3.68e-02w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 134r 0.0000000e+00 4.32e+04 3.80e+02 -5.4 3.44e+03 - 1.99e-02 3.86e-06w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 135r 0.0000000e+00 1.05e+04 9.98e+02 -5.4 8.04e+02 - 1.18e-04 6.81e-20f 55\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 136r 0.0000000e+00 1.05e+04 2.21e+01 -5.4 8.37e+02 -5.3 6.52e-01 5.55e-17h 55\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 137r 0.0000000e+00 1.05e+04 2.91e+01 -5.4 3.73e+03 -5.8 2.04e-01 8.22e-18h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 138r 0.0000000e+00 1.05e+04 1.45e+01 -5.4 9.53e+02 -5.3 1.00e+00 5.55e-17h 55\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 139r 0.0000000e+00 1.05e+04 2.31e+01 -5.4 4.63e+03 -5.8 1.55e-01 6.62e-18h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 140r 0.0000000e+00 1.05e+04 1.67e+01 -5.4 1.10e+03 -5.4 1.00e+00 2.78e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 141r 0.0000000e+00 1.05e+04 2.55e+01 -5.4 5.89e+03 -5.9 1.22e-01 5.20e-18h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 142r 0.0000000e+00 1.05e+04 1.93e+01 -5.4 1.27e+03 -5.4 1.00e+00 2.41e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 143r 0.0000000e+00 1.05e+04 2.84e+01 -5.4 7.78e+03 -5.9 9.22e-02 3.94e-18h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 144r 0.0000000e+00 1.05e+04 3.40e+01 -5.4 1.48e+03 -5.5 1.00e+00 2.08e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 145r 0.0000000e+00 2.67e+04 4.04e+01 -5.4 1.09e+04 -6.0 6.60e-02 1.02e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 146r 0.0000000e+00 2.67e+04 1.47e+03 -5.4 1.02e+03 - 2.88e-03 1.10e-04w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 147r 0.0000000e+00 4.33e+04 7.00e+02 -5.4 1.97e+04 -6.5 1.24e-01 8.93e-02w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 148r 0.0000000e+00 1.05e+04 5.40e+01 -5.4 6.24e+03 - 6.60e-02 2.82e-18h 55\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 149r 0.0000000e+00 1.05e+04 1.51e+02 -5.4 1.68e+04 -6.0 1.26e-01 1.83e-18h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 150r 0.0000000e+00 1.05e+04 5.58e+01 -5.4 2.10e+03 -5.6 1.51e-01 9.25e-19h 60\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 151r 0.0000000e+00 1.05e+04 6.31e+01 -5.4 3.28e+04 -6.1 1.66e-02 9.36e-19f 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 152r 0.0000000e+00 1.05e+04 6.32e+01 -5.4 3.63e+03 -5.7 8.61e-03 1.56e-18h 54\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 153r 0.0000000e+00 1.05e+04 6.33e+01 -5.4 2.10e+05 -6.1 1.98e-05 1.48e-19f 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 154r 0.0000000e+00 1.05e+04 8.87e-01 -5.4 1.46e-02 -0.3 1.00e+00 1.43e-06h 4\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 155r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 2.09e-02 -0.8 1.00e+00 5.00e-01f 2\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 156r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 6.26e-02 -1.2 1.00e+00 2.44e-04h 13\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 157r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 1.88e-01 -1.7 1.00e+00 1.53e-05h 17\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 158r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 5.64e-01 -2.2 1.00e+00 1.00e+00w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 159r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 1.69e+00 -2.7 1.00e+00 1.00e+00w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 160r 0.0000000e+00 1.06e+04 3.62e-03 -5.4 5.08e+00 -3.1 1.00e+00 1.00e+00w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 161r 0.0000000e+00 1.05e+04 8.60e-03 -5.4 1.53e+01 -3.6 1.00e+00 7.45e-09h 27\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 162r 0.0000000e+00 1.05e+04 6.99e-01 -5.4 4.61e+01 -4.1 1.00e+00 1.14e-13h 44\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 163r 0.0000000e+00 1.05e+04 2.14e+00 -5.4 1.41e+02 -4.6 1.00e+00 2.84e-14h 46\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 164r 0.0000000e+00 1.05e+04 6.79e+00 -5.4 4.48e+02 -5.1 1.00e+00 4.66e-10f 32\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 165r 0.0000000e+00 1.05e+04 2.13e+01 -5.4 1.64e+03 -5.5 8.03e-01 1.96e-11f 36\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 166r 0.0000000e+00 1.05e+04 5.45e+01 -5.4 1.44e+04 -6.0 1.69e-01 5.60e-13f 38\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 167r 0.0000000e+00 1.05e+04 2.91e+01 -5.4 1.92e+03 -5.6 1.00e+00 1.31e-13f 43\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 168r 0.0000000e+00 1.05e+04 3.94e+01 -5.4 2.52e+04 -6.1 2.91e-02 3.11e-16f 48\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 169r 0.0000000e+00 1.05e+04 3.44e+01 -5.4 2.27e+03 -5.6 1.00e+00 3.46e-15h 48\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 170r 0.0000000e+00 1.05e+04 4.50e+01 -5.4 7.69e+04 -6.1 9.32e-03 1.28e-17f 51\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 171r 0.0000000e+00 2.67e+04 3.33e+01 -5.4 2.71e+03 -5.7 1.00e+00 4.08e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 172r 0.0000000e+00 2.67e+04 9.73e+02 -5.4 1.12e+03 - 1.93e-03 9.14e-05w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 173r 0.0000000e+00 4.37e+04 5.94e+02 -5.4 7.46e+03 -6.2 2.29e-01 2.40e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 174r 0.0000000e+00 1.05e+04 4.51e+01 -5.4 3.87e+03 - 1.00e+00 2.97e-12f 37\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 175r 0.0000000e+00 1.05e+04 6.47e+01 -5.4 3.27e+03 -5.7 2.19e-01 7.69e-14f 43\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 176r 0.0000000e+00 1.05e+04 5.10e+01 -5.4 8.69e+02 -5.3 1.00e+00 1.14e-13h 44\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 177r 0.0000000e+00 1.05e+04 7.51e+01 -5.4 4.00e+03 -5.8 1.79e-01 6.43e-11f 33\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 178r 0.0000000e+00 1.05e+04 6.82e+01 -5.4 1.00e+03 -5.4 1.00e+00 4.66e-10f 32\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 179r 0.0000000e+00 1.05e+04 1.03e+02 -5.4 5.00e+03 -5.8 1.43e-01 1.29e-11f 35\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 180r 0.0000000e+00 1.05e+04 1.08e+02 -5.4 1.15e+03 -5.4 1.00e+00 1.39e-11f 37\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 181r 0.0000000e+00 1.05e+04 1.65e+02 -5.4 6.42e+03 -5.9 1.12e-01 5.01e-12f 36\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 182r 0.0000000e+00 1.05e+04 2.00e+02 -5.4 1.34e+03 -5.5 1.00e+00 1.20e-11f 37\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 183r 0.0000000e+00 1.05e+04 3.13e+02 -5.4 8.54e+03 -5.9 8.39e-02 9.41e-13f 38\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 184r 0.0000000e+00 2.67e+04 6.63e+01 -5.4 1.55e+03 -5.5 1.00e+00 7.13e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 185r 0.0000000e+00 2.67e+04 8.09e+02 -5.4 1.01e+03 - 2.25e-03 8.90e-04w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 186r 0.0000000e+00 4.40e+04 1.17e+02 -5.4 4.65e+03 -6.0 4.39e-01 3.92e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 187r 0.0000000e+00 1.05e+04 4.40e+02 -5.4 8.89e+03 - 1.00e+00 2.07e-11f 35\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 188r 0.0000000e+00 1.05e+04 5.51e+02 -5.4 1.81e+03 -5.6 3.96e-01 8.88e-12f 37\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 189r 0.0000000e+00 1.05e+04 8.25e+02 -5.4 1.87e+04 -6.0 3.12e-02 1.08e-13f 40\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 190r 0.0000000e+00 1.05e+04 3.35e+01 -5.4 2.20e+03 -5.6 4.67e-01 2.27e-13f 43\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 191r 0.0000000e+00 1.05e+04 4.40e+01 -5.4 4.69e+04 -6.1 1.56e-02 5.36e-15f 43\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 192r 0.0000000e+00 1.05e+04 3.87e+01 -5.4 2.56e+03 -5.7 1.00e+00 2.46e-14f 45\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 193r 0.0000000e+00 1.05e+04 1.92e+01 -5.4 7.26e+02 -5.2 9.88e-01 1.14e-13h 44\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 194r 0.0000000e+00 1.05e+04 4.68e+01 -5.4 3.07e+03 -5.7 7.96e-01 1.68e-10f 32\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 195r 0.0000000e+00 1.05e+04 3.54e+01 -5.4 8.31e+02 -5.3 1.00e+00 5.82e-11f 35\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 196r 0.0000000e+00 1.05e+04 8.07e+01 -5.4 3.74e+03 -5.8 5.32e-01 6.87e-11f 33\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 197r 0.0000000e+00 2.44e+04 4.51e+01 -5.4 9.55e+02 -5.3 1.00e+00 1.00e+00w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 198r 0.0000000e+00 2.90e+04 1.83e+02 -5.4 3.03e+03 -5.8 6.02e-01 1.26e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 199r 0.0000000e+00 2.90e+04 3.65e+02 -5.4 1.03e+03 - 1.58e-03 1.30e-03w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 200r 0.0000000e+00 1.05e+04 6.99e+01 -5.4 9.09e+03 -6.3 1.00e+00 2.91e-11f 35\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of Iterations....: 200\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: (scaled) (unscaled)\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Dual infeasibility......: 6.9908071367141474e+01 6.9908071367141474e+01\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Constraint violation....: 2.8645094423111342e-03 1.0458847092153306e+04\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Complementarity.........: 1.3579265591895737e-03 1.3579265591895737e-03\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Overall NLP error.......: 2.8645094423111342e-03 1.0458847092153306e+04\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of objective function evaluations = 5209\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of objective gradient evaluations = 6\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of equality constraint evaluations = 5210\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of inequality constraint evaluations = 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of equality constraint Jacobian evaluations = 203\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of inequality constraint Jacobian evaluations = 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of Lagrangian Hessian evaluations = 200\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Total CPU secs in IPOPT (w/o function evaluations) = 0.176\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Total CPU secs in NLP function evaluations = 0.014\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: EXIT: Maximum Number of Iterations Exceeded.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit: Initialization Step 3 maxIterations - .\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit: Initialization Complete: maxIterations - \n", + "Initialization failed.\n" + ] + } + ], + "source": [ + "import logging\n", + "from pyomo.environ import (\n", + " ComponentMap,\n", + " ConcreteModel,\n", + " Constraint,\n", + " exp,\n", + " Param,\n", + " Reference,\n", + " units as pyunits,\n", + " value,\n", + ")\n", + "\n", + "from idaes.core import (\n", + " ControlVolume0DBlock,\n", + " FlowsheetBlock,\n", + " MaterialFlowBasis,\n", + " MomentumBalanceType,\n", + ")\n", + "import idaes.logger as idaeslog\n", + "from idaes.core.scaling.util import get_scaling_factor\n", + "from idaes.core.util.exceptions import ConfigurationError, InitializationError\n", + "\n", + "from idaes.models.properties.modular_properties.base.generic_property import (\n", + " GenericParameterBlock,\n", + ")\n", + "\n", + "from idaes.models_extra.column_models.solvent_reboiler import SolventReboiler\n", + "from idaes.models_extra.column_models.properties.MEA_solvent import (\n", + " configuration as aqueous_mea,\n", + ")\n", + "from idaes.models_extra.column_models.properties.MEA_vapor import flue_gas\n", + "\n", + "logging.getLogger(\"pyomo.repn.plugins.nl_writer\").setLevel(logging.ERROR)\n", + "\n", + "\n", + "def create_model():\n", + " m = ConcreteModel()\n", + " m.fs = FlowsheetBlock(dynamic=False)\n", + "\n", + " m.fs.liquid_properties = GenericParameterBlock(**aqueous_mea)\n", + " m.fs.vapor_properties = GenericParameterBlock(**flue_gas)\n", + "\n", + " m.fs.unit = SolventReboiler(\n", + " liquid_property_package=m.fs.liquid_properties,\n", + " vapor_property_package=m.fs.vapor_properties,\n", + " )\n", + "\n", + " m.fs.unit.inlet.flow_mol[0].fix(83.89)\n", + " m.fs.unit.inlet.temperature[0].fix(392.5)\n", + " m.fs.unit.inlet.pressure[0].fix(183700)\n", + " m.fs.unit.inlet.mole_frac_comp[0, \"CO2\"].fix(0.0326)\n", + " m.fs.unit.inlet.mole_frac_comp[0, \"H2O\"].fix(0.8589)\n", + " m.fs.unit.inlet.mole_frac_comp[0, \"MEA\"].fix(0.1085)\n", + "\n", + " m.fs.unit.heat_duty.fix(430.61e3)\n", + " return m\n", + "\n", + "\n", + "if __name__ == \"__main__\":\n", + " m = create_model()\n", + "\n", + " reboiler_init = m.fs.unit.default_initializer(always_estimate_states=True)\n", + " try:\n", + " reboiler_init.initialize(m.fs.unit, output_level=idaeslog.DEBUG)\n", + " except InitializationError:\n", + " print(\"Initialization failed.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Step 2: Run Model Diagnostics\n", + "\n", + "We see that the unit model failed to initialize. When confronted with a bad solution state, we should first use the `DiagnosticsToolbox` to check to see if there are structural issues with the model." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "====================================================================================\n", + "Model Statistics\n", + "\n", + " Activated Blocks: 23 (Deactivated: 0)\n", + " Free Variables in Activated Constraints: 77 (External: 0)\n", + " Free Variables with only lower bounds: 15\n", + " Free Variables with only upper bounds: 0\n", + " Free Variables with upper and lower bounds: 50\n", + " Fixed Variables in Activated Constraints: 66 (External: 0)\n", + " Activated Equality Constraints: 77 (Deactivated: 0)\n", + " Activated Inequality Constraints: 0 (Deactivated: 0)\n", + " Activated Objectives: 0 (Deactivated: 0)\n", + "\n", + "------------------------------------------------------------------------------------\n", + "1 WARNINGS\n", + "\n", + " WARNING: Found 9 potential evaluation errors.\n", + "\n", + "------------------------------------------------------------------------------------\n", + "2 Cautions\n", + "\n", + " Caution: 11 variables fixed to 0\n", + " Caution: 82 unused variables (82 fixed)\n", + "\n", + "------------------------------------------------------------------------------------\n", + "Suggested next steps:\n", + "\n", + " display_potential_evaluation_errors()\n", + "\n", + "====================================================================================\n" + ] + } + ], + "source": [ + "from idaes.core.util import DiagnosticsToolbox\n", + "\n", + "dt = DiagnosticsToolbox(m)\n", + "dt.report_structural_issues()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The density relationship is being flagged for potential evaluation errors. The interval arithmetic used to identify potential evaluation errors can produce relatively loose bounds, especially for the sort of large polynomial expressions favored in the literature. Independent testing of the density relationship over a wide range of values has demonstrated that no evaluation errors occur, so we can ignore these warnings.\n", + "\n", + "The next step is determining which numerical issues exist." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "====================================================================================\n", + "Model Statistics\n", + "\n", + " Jacobian Condition Number: 2.718E+13\n", + "\n", + "------------------------------------------------------------------------------------\n", + "3 WARNINGS\n", + "\n", + " WARNING: 3 Constraints with large residuals (>1.0E-05)\n", + " WARNING: 1 Variable with extreme Jacobian column norms (<1.0E-08 or >1.0E+08)\n", + " WARNING: 1 Constraint with extreme Jacobian row norms (<1.0E-08 or >1.0E+08)\n", + "\n", + "------------------------------------------------------------------------------------\n", + "8 Cautions\n", + "\n", + " Caution: 9 Variables with value close to their bounds (abs=1.0E-04, rel=1.0E-04)\n", + " Caution: 18 Variables with value close to zero (tol=1.0E-08)\n", + " Caution: 30 Variables with extreme value (<1.0E-04 or >1.0E+04)\n", + " Caution: 2 Constraints with mismatched terms\n", + " Caution: 1 Constraint with potential cancellation of terms\n", + " Caution: 27 Variables with extreme Jacobian column norms (<1.0E-04 or >1.0E+04)\n", + " Caution: 16 Constraints with extreme Jacobian row norms (<1.0E-04 or >1.0E+04)\n", + " Caution: 50 extreme Jacobian Entries (<1.0E-04 or >1.0E+04)\n", + "\n", + "------------------------------------------------------------------------------------\n", + "Suggested next steps:\n", + "\n", + " display_constraints_with_large_residuals()\n", + " compute_infeasibility_explanation()\n", + " display_variables_with_extreme_jacobians()\n", + " display_constraints_with_extreme_jacobians()\n", + "\n", + "====================================================================================\n" + ] + } + ], + "source": [ + "dt.report_numerical_issues()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "tags": [ + "testing" + ] + }, + "outputs": [], + "source": [ + "import pytest\n", + "from idaes.core.scaling.util import jacobian_cond\n", + "\n", + "dt.assert_no_structural_warnings(ignore_evaluation_errors=True)\n", + "assert jacobian_cond(m.fs.unit) == pytest.approx(2.718e13, rel=1e-2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In order to help interpret this output, we need to review the solution of systems of nonlinear equations.\n", + "\n", + "When we try to solve a square problem (i.e., a problem with zero degrees of freedom) using IPOPT, we are asking it to solve an equation of the form\n", + "$$\n", + "\\mathbf{f}(\\mathbf{x}) = \\mathbf{0}\n", + "$$\n", + "in which $\\mathbf{f}(\\cdot)$ is a vector-valued function of length $n$, and $\\mathbf{x}$ is a vector also of length $n$. Due to the finite accuracy of floating point arithmetic, the most we can ask for is $||\\mathbf{f}(\\mathbf{x})|| < \\varepsilon$, for some small value of $\\varepsilon$. The IDAES default solver configuration sets $\\varepsilon = 10^{-6}$. For some constraint $j$, the value of $f_j(x_k)$ is the called its *residual*, i.e., the remaining error in constraint satisfaction. IPOPT displays the infinity norm of the constraint residual,\n", + "$$\n", + "\\lvert\\lvert \\mathbf{f}(\\mathbf{x}_k)\\rvert\\rvert_{\\infty} := \\max_j \\lvert f_j(\\mathbf{x}_k)\\rvert\n", + "$$\n", + "i.e., the constraint residual with largest magnitude, for each step $k$ in the primal infeasibility (`inf_pr`) column.\n", + "\n", + "Problems of this form are typically solved with some variation on Newton's method. We denote the Jacobian matrix for function $\\mathbf{f}(\\mathbf{x})$ as\n", + "$$\n", + "\\mathbf{J}(\\mathbf{x}) := \\begin{bmatrix}\n", + " \\frac{\\partial f_1}{\\partial x_1} & \\dots & \\frac{\\partial f_1}{\\partial x_n} \\\\\n", + " \\vdots & \\ddots & \\vdots \\\\\n", + " \\frac{\\partial f_n}{\\partial x_1} & \\dots & \\frac{\\partial f_n}{\\partial x_n}\n", + "\\end{bmatrix}\n", + "$$\n", + "Note that each row of $\\mathbf{J}(\\cdot)$ is associated with a constraint and every column is associated with a variable.\n", + "\n", + "In the classical form of Newton's method, we start with an initial guess $\\mathbf{x}_0$, then iterate using the relationship\n", + "\n", + "\\begin{align}\n", + "\\mathbf{J}(\\mathbf{x}_k)\\cdot\\mathbf{\\delta x}_k &= -\\mathbf{f}(\\mathbf{x}_k) \\\\\n", + "\\mathbf{x}_{k+1} &= \\mathbf{x}_k + \\mathbf{\\delta x}_k\n", + "\\end{align}\n", + "\n", + "IPOPT incorporates additional features, such as a line search, in order to enhance its robustness to bad initial guesses, but it is designed to take full Newton steps in the neighborhood of a solution (for the full details, refer to [W\u00e4chter and Biegler (2006)](#references)).\n", + "\n", + "The condition number $\\kappa_2(\\cdot)$ (for the Euclidean norm) is a worst-case error bound in the solution of a system of linear equations. In this case, we have\n", + "$$\n", + "\\lvert\\lvert\\mathbf{\\delta x}_k\\rvert\\rvert_2 \\leq \\kappa(\\mathbf{J}(\\mathbf{x}_k)) \\cdot \\lvert\\lvert \\mathbf{f}(\\mathbf{x}_k)\\rvert\\rvert_2\n", + "$$\n", + "If we terminate under the condition $||\\mathbf{f}(\\mathbf{x}_f)||_2 < \\varepsilon$, then\n", + "$$\n", + "\\lvert\\lvert\\mathbf{\\delta x}_f\\rvert\\rvert_2 \\leq \\kappa(\\mathbf{J}(\\mathbf{x}_f)) \\cdot \\varepsilon\n", + "$$\n", + "With a condition number on the order of $10^{13}$ and the default tolerance $\\varepsilon = 10^{-6}$, then the difference between the computed solution $x_f$ and the true solution $x$ could be on the order of $10^7$.\n", + "\n", + "In practice, however, we frequently end up with much better results than those predicted by this worst-case bound. Frequently, we find that most constraints have residuals on the order of $10^{-10}$ or less, with a few problematic constraints having larger residuals. That is the case here." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Number of constraints: 77\n", + "====================================================================================\n", + "The following constraint(s) have large residuals (>1.0E-10):\n", + "\n", + " fs.unit.unit_material_balance[0.0,CO2]: 1.84866E-10\n", + " fs.unit.unit_material_balance[0.0,N2]: 1.89950E-10\n", + " fs.unit.unit_material_balance[0.0,O2]: 1.87656E-10\n", + " fs.unit.unit_phase_equilibrium[0.0,CO2]: 1.04588E+04\n", + " fs.unit.unit_phase_equilibrium[0.0,H2O]: 8.88278E-07\n", + " fs.unit.unit_enthalpy_balance[0.0]: 5.05679E-10\n", + " fs.unit.liquid_phase.material_balances[0.0,CO2]: 1.70459E-10\n", + " fs.unit.liquid_phase.enthalpy_balances[0.0]: 1.17285E-05\n", + " fs.unit.liquid_phase.properties_out[0.0].sum_mole_frac_out: 2.08134E-10\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-]: 8.83857E-06\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]: 1.54414E-07\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA_+]: 7.69821E-06\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,H2O]: 2.50511E-08\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA]: 4.55346E-06\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2]: 4.42749E-05\n", + " fs.unit.vapor_phase[0.0].sum_mole_frac_out: 1.71144E-10\n", + "\n", + "====================================================================================\n" + ] + } + ], + "source": [ + "import idaes.core.util.model_statistics as mstat\n", + "\n", + "print(f\"Number of constraints: {mstat.number_activated_constraints(m)}\")\n", + "dt.config.constraint_residual_tolerance = 1e-10\n", + "dt.display_constraints_with_large_residuals()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Even with a non-optimal termination, we have only three constraints with residuals greater than $10^{-5}$ for a model with 77 active constraints. Two of those constraints are on the order of $10^{-5}$, but the third is on the order of $10^4$.\n", + "\n", + "Nevertheless, a condition number on the order of $10^{13}$ is significantly higher than we'd like, because large condition numbers can degrade the convergence of Newton's method or even prevent it from converging entirely. Ideally, we want flowsheets to have condition numbers less than $10^8$. Connecting unit models together with things like recycle streams can amplify the overall flowsheet condition number to be multiple orders of magnitude greater than that of its individual components. Consequently, we want unit models to have condition numbers less than $10^4$.\n", + "\n", + "Model scaling can both reduce the Jacobian's condition number and help ensure that constraints are satisfied to an appropriate precision. Both of those effects can help the model initialization to converge. Before beginning to write a scaler object, however, we should look at the structure of the unit model." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "def build(self):\n", + " \"\"\"Build the model.\n", + "\n", + " Args:\n", + " None\n", + " Returns:\n", + " None\n", + " \"\"\"\n", + " # Call UnitModel.build to setup dynamics\n", + " super().build()\n", + "\n", + " # Check phase lists match assumptions\n", + " if self.config.vapor_property_package.phase_list != [\"Vap\"]:\n", + " raise ConfigurationError(\n", + " f\"{self.name} SolventReboiler model requires that the vapor \"\n", + " f\"phase property package have a single phase named 'Vap'\"\n", + " )\n", + " if self.config.liquid_property_package.phase_list != [\"Liq\"]:\n", + " raise ConfigurationError(\n", + " f\"{self.name} SolventReboiler model requires that the liquid \"\n", + " f\"phase property package have a single phase named 'Liq'\"\n", + " )\n", + "\n", + " # Check for at least one common component in component lists\n", + " if not any(\n", + " j in self.config.vapor_property_package.component_list\n", + " for j in self.config.liquid_property_package.component_list\n", + " ):\n", + " raise ConfigurationError(\n", + " f\"{self.name} SolventReboiler model requires that the liquid \"\n", + " f\"and vapor phase property packages have at least one \"\n", + " f\"common component.\"\n", + " )\n", + "\n", + " # ---------------------------------------------------------------------\n", + " # Add Control Volume for the Liquid Phase\n", + " self.liquid_phase = ControlVolume0DBlock(\n", + " dynamic=self.config.dynamic,\n", + " has_holdup=self.config.has_holdup,\n", + " property_package=self.config.liquid_property_package,\n", + " property_package_args=self.config.liquid_property_package_args,\n", + " )\n", + "\n", + " self.liquid_phase.add_state_blocks(has_phase_equilibrium=True)\n", + "\n", + " # Separate liquid and vapor phases means that phase equilibrium will\n", + " # be handled at the unit model level, thus has_phase_equilibrium is\n", + " # False, but has_mass_transfer is True.\n", + " self.liquid_phase.add_material_balances(\n", + " balance_type=self.config.material_balance_type,\n", + " has_mass_transfer=True,\n", + " has_phase_equilibrium=False,\n", + " )\n", + "\n", + " # Need to include enthalpy transfer term for the mass transfer\n", + " self.liquid_phase.add_energy_balances(\n", + " balance_type=self.config.energy_balance_type,\n", + " has_heat_transfer=True,\n", + " has_enthalpy_transfer=True,\n", + " )\n", + "\n", + " self.liquid_phase.add_momentum_balances(\n", + " balance_type=self.config.momentum_balance_type,\n", + " has_pressure_change=self.config.has_pressure_change,\n", + " )\n", + "\n", + " # ---------------------------------------------------------------------\n", + " # Add single state block for vapor phase\n", + " tmp_dict = dict(**self.config.vapor_property_package_args)\n", + " tmp_dict[\"has_phase_equilibrium\"] = False\n", + " tmp_dict[\"defined_state\"] = False\n", + " self.vapor_phase = self.config.vapor_property_package.build_state_block(\n", + " self.flowsheet().time, doc=\"Vapor phase properties\", **tmp_dict\n", + " )\n", + "\n", + " # ---------------------------------------------------------------------\n", + " # Check flow basis is compatible\n", + " t_init = self.flowsheet().time.first()\n", + " if (\n", + " self.vapor_phase[t_init].get_material_flow_basis()\n", + " != self.liquid_phase.properties_out[t_init].get_material_flow_basis()\n", + " ):\n", + " raise ConfigurationError(\n", + " f\"{self.name} vapor and liquid property packages must use the \"\n", + " f\"same material flow basis.\"\n", + " )\n", + "\n", + " # ---------------------------------------------------------------------\n", + " # Add Ports for the reboiler\n", + " self.add_inlet_port(name=\"inlet\", block=self.liquid_phase, doc=\"Liquid feed\")\n", + " self.add_outlet_port(name=\"bottoms\", block=self.liquid_phase, doc=\"Bottoms stream\")\n", + " self.add_outlet_port(\n", + " name=\"vapor_reboil\",\n", + " block=self.vapor_phase,\n", + " doc=\"Vapor stream from reboiler\",\n", + " )\n", + "\n", + " # ---------------------------------------------------------------------\n", + " # Add unit level constraints\n", + " # First, need the union and intersection of component lists\n", + " all_comps = (\n", + " self.vapor_phase.component_list\n", + " | self.liquid_phase.properties_out.component_list\n", + " )\n", + " common_comps = (\n", + " self.vapor_phase.component_list\n", + " & self.liquid_phase.properties_out.component_list\n", + " )\n", + "\n", + " # Get units for unit conversion\n", + " vunits = self.config.vapor_property_package.get_metadata().get_derived_units\n", + " lunits = self.config.liquid_property_package.get_metadata().get_derived_units\n", + " flow_basis = self.vapor_phase[t_init].get_material_flow_basis()\n", + " if flow_basis == MaterialFlowBasis.molar:\n", + " fb = \"flow_mole\"\n", + " elif flow_basis == MaterialFlowBasis.mass:\n", + " fb = \"flow_mass\"\n", + " else:\n", + " raise ConfigurationError(\n", + " f\"{self.name} SolventReboiler only supports mass or molar \"\n", + " f\"basis for MaterialFlowBasis.\"\n", + " )\n", + "\n", + " if any(j not in common_comps for j in self.vapor_phase.component_list):\n", + " # We have non-condensable components present, need zero-flow param\n", + " self.zero_flow_param = Param(\n", + " mutable=True, default=1e-8, units=vunits(\"flow_mole\")\n", + " )\n", + "\n", + " # Material balances\n", + " def rule_material_balance(blk, t, j):\n", + " if j in common_comps:\n", + " # Component is in equilibrium\n", + " # Mass transfer equals vapor flowrate\n", + " return -blk.liquid_phase.mass_transfer_term[t, \"Liq\", j] == pyunits.convert(\n", + " blk.vapor_phase[t].get_material_flow_terms(\"Vap\", j),\n", + " to_units=lunits(fb),\n", + " )\n", + " elif j in self.vapor_phase.component_list:\n", + " # Non-condensable component\n", + " # No mass transfer term\n", + " # Set vapor flowrate to an arbitrary small value\n", + " return (\n", + " blk.vapor_phase[t].get_material_flow_terms(\"Vap\", j)\n", + " == blk.zero_flow_param\n", + " )\n", + " else:\n", + " # Non-vaporisable component\n", + " # Mass transfer term is zero, no vapor flowrate\n", + " return blk.liquid_phase.mass_transfer_term[t, \"Liq\", j] == 0 * lunits(fb)\n", + "\n", + " self.unit_material_balance = Constraint(\n", + " self.flowsheet().time,\n", + " all_comps,\n", + " rule=rule_material_balance,\n", + " doc=\"Unit level material balances\",\n", + " )\n", + "\n", + " # Phase equilibrium constraints\n", + " # For all common components, equate fugacity in vapor and liquid\n", + " def rule_phase_equilibrium(blk, t, j):\n", + " return blk.liquid_phase.properties_out[t].fug_phase_comp[\n", + " \"Liq\", j\n", + " ] == pyunits.convert(\n", + " blk.vapor_phase[t].fug_phase_comp[\"Vap\", j], to_units=lunits(\"pressure\")\n", + " )\n", + "\n", + " self.unit_phase_equilibrium = Constraint(\n", + " self.flowsheet().time,\n", + " common_comps,\n", + " rule=rule_phase_equilibrium,\n", + " doc=\"Unit level phase equilibrium constraints\",\n", + " )\n", + "\n", + " # Temperature equality constraint\n", + " def rule_temperature_balance(blk, t):\n", + " return blk.liquid_phase.properties_out[t].temperature == pyunits.convert(\n", + " blk.vapor_phase[t].temperature, to_units=lunits(\"temperature\")\n", + " )\n", + "\n", + " self.unit_temperature_equality = Constraint(\n", + " self.flowsheet().time,\n", + " rule=rule_temperature_balance,\n", + " doc=\"Unit level temperature equality\",\n", + " )\n", + "\n", + " # Unit level energy balance\n", + " # Energy leaving in vapor phase must be equal and opposite to enthalpy\n", + " # transfer from liquid phase\n", + " def rule_energy_balance(blk, t):\n", + " return -blk.liquid_phase.enthalpy_transfer[t] == pyunits.convert(\n", + " blk.vapor_phase[t].get_enthalpy_flow_terms(\"Vap\"),\n", + " to_units=lunits(\"energy\") / lunits(\"time\"),\n", + " )\n", + "\n", + " self.unit_enthalpy_balance = Constraint(\n", + " self.flowsheet().time,\n", + " rule=rule_energy_balance,\n", + " doc=\"Unit level enthalpy_balance\",\n", + " )\n", + "\n", + " # Pressure balance constraint\n", + " def rule_pressure_balance(blk, t):\n", + " return blk.liquid_phase.properties_out[t].pressure == pyunits.convert(\n", + " blk.vapor_phase[t].pressure, to_units=lunits(\"pressure\")\n", + " )\n", + "\n", + " self.unit_pressure_balance = Constraint(\n", + " self.flowsheet().time,\n", + " rule=rule_pressure_balance,\n", + " doc=\"Unit level pressure balance\",\n", + " )\n", + "\n", + " # Set references to balance terms at unit level\n", + " self.heat_duty = Reference(self.liquid_phase.heat[:])\n", + "\n", + " if (\n", + " self.config.has_pressure_change is True\n", + " and self.config.momentum_balance_type != MomentumBalanceType.none\n", + " ):\n", + " self.deltaP = Reference(self.liquid_phase.deltaP[:])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As is typical with IDAES models, two submodels are created: the `ControlVolume0D` named `liquid_phase` and the `StateBlock` named `vapor_phase`. Then several unit model level constraints are written. \n", + "\n", + "## Step 3: Creating a New Scaler Class\n", + "\n", + "To create a new scaling routine for the equilibrium reactor, we start by creating a new ``Scaler`` class which inherits from the ``CustomScalerBase`` class in ``idaes.core.scaling``. The ``CustomScalerBase`` class contains a number of useful methods to help us in developing our scaling routine, including some placeholder methods for implementing a standard scaling workflow and helper methods for doing common tasks.\n", + "\n", + "The cell below shows how to create our new class which we will name ``SolventReboilerScaler`` as well as two key methods we will fill out as part of this workshop." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "from idaes.core.scaling import CustomScalerBase\n", + "\n", + "\n", + "class SolventReboilerScaler(CustomScalerBase):\n", + " def variable_scaling_routine(\n", + " self, model, overwrite: bool = False, submodel_scalers: dict = None\n", + " ):\n", + " # Empty method for now\n", + " pass\n", + "\n", + " def constraint_scaling_routine(\n", + " self, model, overwrite: bool = False, submodel_scalers: dict = None\n", + " ):\n", + " # Empty method for now\n", + " pass" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As you know from the first scaling tutorial, the ``variable_scaling_routine`` and ``constraint_scaling_routine`` methods are used to implement subroutines for scaling the variables and constraints in the model respectively. Separately, there is a ``scale_model`` method that will call each of these in sequence in order to scale an entire model by applying the following steps:\n", + "\n", + "1. apply variable scaling routine,\n", + "2. apply first stage scaling fill-in,\n", + "3. apply constraint scaling routine,\n", + "4. apply second stage scaling fill-in.\n", + "\n", + "The second and fourth steps are intended to allow users to provide methods to fill in missing scaling information that was not provided by the first and second steps. However, these methods are prone to perform poorly on all but the simplest models (see Step 5 for more information).\n", + "\n", + "## Step 4: Apply Scaling to Sub-Models\n", + "\n", + "First, let's look at how to scale the control volume and state block sub-models. Because the property package for the ``vapor_phase`` state block is specified by the user, we do not know what variables and constraints it may contain, so we cannot (and should not) scale it directly. The property package creator (hopefully) created a scaler object that we can use. The zero-dimensional control volume ``liquid_phase`` contains two state blocks, material, energy, and pressure balance constraints, and variables corresponding to additional interaction terms. Because we are choosing which terms to create in the control volume, we could, in principle, scale it at the unit model level. However, because control volumes typically should be scaled in the same way, a submodel scaler has been provided for it as well. Thus, what we want to do here is to call the variable and constraint scaling routines from the ``Scaler`` associated with each sub-model, which we can do using the ``call_submodel_scaler_method`` method." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "class SolventReboilerScaler(CustomScalerBase):\n", + " def variable_scaling_routine(\n", + " self, model, overwrite: bool = False, submodel_scalers: ComponentMap = None\n", + " ):\n", + " # Call scaling methods for sub-models\n", + " self.call_submodel_scaler_method(\n", + " submodel=model.liquid_phase,\n", + " method=\"variable_scaling_routine\",\n", + " submodel_scalers=submodel_scalers,\n", + " overwrite=overwrite,\n", + " )\n", + "\n", + " self.call_submodel_scaler_method(\n", + " submodel=model.vapor_phase,\n", + " method=\"variable_scaling_routine\",\n", + " submodel_scalers=submodel_scalers,\n", + " overwrite=overwrite,\n", + " )\n", + "\n", + " def constraint_scaling_routine(\n", + " self, model, overwrite: bool = False, submodel_scalers: ComponentMap = None\n", + " ):\n", + " # Call scaling methods for sub-models\n", + " self.call_submodel_scaler_method(\n", + " submodel=model.liquid_phase,\n", + " method=\"constraint_scaling_routine\",\n", + " submodel_scalers=submodel_scalers,\n", + " overwrite=overwrite,\n", + " )\n", + "\n", + " self.call_submodel_scaler_method(\n", + " submodel=model.vapor_phase,\n", + " method=\"constraint_scaling_routine\",\n", + " submodel_scalers=submodel_scalers,\n", + " overwrite=overwrite,\n", + " )" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In order for the submodel scaling to function properly, default scaling factors need to be set for some variables. The property package scaler cannot know if the system is supposed to be bench scale, pilot scale, or production scale unless the user sets a default for flow rate. These defaults can be set on a unit model by unit model basis by using the `submodel_scalers` argument, or they can be set at the flowsheet level on the parameter block. We will do the latter.\n", + "\n", + "First, we need to create objects using the modular property submodel scaler class." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "liquid_properties_scaler = m.fs.liquid_properties.default_state_scaler_class()\n", + "vapor_properties_scaler = m.fs.vapor_properties.default_state_scaler_class()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, let's see what default scaling factors these scaler objects have." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'flow_mol_phase': ,\n", + " 'mole_frac_phase_comp': 10,\n", + " 'temperature': 0.0033333333333333335,\n", + " 'pressure': 1e-05,\n", + " 'enth_mol_phase': ,\n", + " 'visc_d_phase': ,\n", + " 'therm_cond_phase': ,\n", + " 'mole_frac_phase_comp_true': 10,\n", + " 'mole_frac_phase_comp_apparent': 10,\n", + " 'dens_mol_phase': ,\n", + " 'vol_mol_phase': }" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "liquid_properties_scaler.default_scaling_factors" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can see that we are required to set a default scaling factor for ``flow_mol_phase``. Furthermore, it is recommended to set a default scaling factor for ``enth_mol_phase``, ``visc_d_phase``, ``therm_cond_phase``, `dens_mol_phase`, and`vol_mol_phase`. For these latter quantities, there is a method to estimate reasonable scaling factors, but it might not be suitible for all cases.\n", + "\n", + "With an inlet flow of about 80 mol/s, a scaling factor of 1/80 is appropriate. We can ignore ``visc_d_phase`` and ``therm_cond_phase``, because this unit model does not require dynamic viscosity or thermal conductivity. Molar enthalpy is a tougher quantity to scale.\n", + "\n", + "By convention, the molar enthalpy of each element in its pure form at $25^\\circ\\text{C}$ and $1\\:\\text{atm}$ is set equal to zero. In some property packages, enthalpy of formation is taken into account for compounds, while in some property packages it is not. However, the scaling factor for enthalpy should not depend on this convention---only enthalpy *differences* are meaningful. So we need to determine how to determine what constitutes a \"significant\" enthalpy difference for this property package. The way the modular property scaler object estimates this is through the temperature scaling factor, which determines what a \"significant\" temperature difference is, and the observation that a wide range of substances have a specific heat capacity around $2\\:\\frac{\\text{J}}{\\text{g K}}$.\n", + "\n", + "This default method is good enough for our purposes now. We can revisit it later, if necessary." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "liquid_properties_scaler.default_scaling_factors[\"flow_mol_phase\"] = 1 / 80\n", + "vapor_properties_scaler.default_scaling_factors[\"flow_mol_phase\"] = 1 / 10\n", + "\n", + "m.fs.liquid_properties.default_state_scaler_object = liquid_properties_scaler\n", + "m.fs.vapor_properties.default_state_scaler_object = vapor_properties_scaler" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can see how much submodel scaling improves the conditioning of the unit model." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "====================================================================================\n", + "Model Statistics\n", + "\n", + " Jacobian Condition Number: 7.165E+10\n", + "\n", + "------------------------------------------------------------------------------------\n", + "1 WARNINGS\n", + "\n", + " WARNING: 1 Constraint with large residuals (>1.0E-05)\n", + "\n", + "------------------------------------------------------------------------------------\n", + "8 Cautions\n", + "\n", + " Caution: 9 Variables with value close to their bounds (abs=1.0E-04, rel=1.0E-04)\n", + " Caution: 14 Variables with value close to zero (tol=1.0E-08)\n", + " Caution: 27 Variables with extreme value (<1.0E-04 or >1.0E+04)\n", + " Caution: 2 Constraints with mismatched terms\n", + " Caution: 1 Constraint with potential cancellation of terms\n", + " Caution: 10 Variables with extreme Jacobian column norms (<1.0E-04 or >1.0E+04)\n", + " Caution: 4 Constraints with extreme Jacobian row norms (<1.0E-04 or >1.0E+04)\n", + " Caution: 33 extreme Jacobian Entries (<1.0E-04 or >1.0E+04)\n", + "\n", + "------------------------------------------------------------------------------------\n", + "Suggested next steps:\n", + "\n", + " display_constraints_with_large_residuals()\n", + " compute_infeasibility_explanation()\n", + "\n", + "====================================================================================\n" + ] + } + ], + "source": [ + "reboiler_scaler = SolventReboilerScaler()\n", + "reboiler_scaler.scale_model(m.fs.unit)\n", + "dt = DiagnosticsToolbox(m)\n", + "dt.report_numerical_issues()" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "tags": [ + "testing" + ] + }, + "outputs": [], + "source": [ + "assert jacobian_cond(m.fs.unit) == pytest.approx(7.165e10, rel=1e-2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We see in this case that partly scaling the model improved the condition number of the Jacobian by only two and a half orders of magnitude. This sort of marginal improvement is common for partial scaling, and sometimes partial scaling makes the model's condition number *worse*. When variables are scaled without the constraints they appear in also being scaled, it generates new extreme Jacobian entries. If we look at the number of extreme Jacobian rows and columns, however, we see the progress we've made. Before applying submodel scaling, we had 27 variables with extreme column norms and 16 constraints with extreme row norms. Now we have only 10 variables and 4 constraints.\n", + "\n", + "We are concerned with Jacobian rows and columns with extreme values because they allow us to estimate the Jacobian condition number. Determining the (Euclidean) condition number requires the computation of the *singular value decomposition* (SVD) of $\\mathbf{J}(\\mathbf{x})$. However, that process is computationally expensive for large models, and it does not identify individual variables and constraints as problematic (instead, it identifies *combinations* of variables and constraints as problematic). However, we have a lower bound to the condition number in terms of the norms of rows and columns of the Jacobian matrix:\n", + "$$\n", + "\\max\\left(\\frac{||\\mathbf{r}_\\text{max}||_2}{||\\mathbf{r}_\\text{min}||_2}, \\frac{||\\mathbf{c}_\\text{max}||_2}{||\\mathbf{c}_\\text{min}||_2}\\right) \\leq \\kappa(\\mathbf{J}(\\mathbf{x}))\n", + "$$\n", + "Consequently, Jacobian rows or columns with extremely large or extremely small norms indicate that the Jacobian is ill-conditioned. Each row is associated with a constraint and each column is associated with a variable. So the extreme Jacobian rows and columns give us a list of variables and constraints to investigate for scaling.\n", + "\n", + "
\n", + "Just because a variable or constraint has a Jacobian column or row with an extreme norm does not mean it is badly-scaled. Frequently, either a constraint containing the variable or a variable present in a constraint is the actual problem. \n", + "
\n", + "\n", + "
\n", + "NOTE\n", + "\n", + "Jacobian rows and columns with extreme norms reveal that the Jacobian matrix is ill-conditioned, but the converse is not true. A Jacobian matrix can have no rows and columns with extreme norms but still be singular or ill-conditioned.\n", + "\n", + "
\n", + "\n", + "\n", + "Let's see which variables and constraints are problematic." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "====================================================================================\n", + "The following variable(s) correspond to Jacobian columns with extreme norms(<1.0E-04 or>1.0E+04):\n", + "\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,CO2]: 3.450E+07\n", + " fs.unit.liquid_phase.enthalpy_transfer[0.0]: 1.970E+06\n", + " fs.unit.liquid_phase.properties_out[0.0].temperature: 1.586E+06\n", + " fs.unit.vapor_phase[0.0].pressure: 1.353E+05\n", + " fs.unit.vapor_phase[0.0].temperature: 1.014E+05\n", + " fs.unit.liquid_phase.properties_out[0.0].pressure: 1.000E+05\n", + " fs.unit.vapor_phase[0.0].flow_mol_phase[Vap]: 3.256E+04\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,H2O]: 1.954E+04\n", + " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]: 1.873E+04\n", + " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]: 1.863E+04\n", + "\n", + "====================================================================================\n", + "====================================================================================\n", + "The following constraint(s) correspond to Jacobian rows with extreme norms (<1.0E-04 or>1.0E+04):\n", + "\n", + " fs.unit.unit_phase_equilibrium[0.0,CO2]: 3.450E+07\n", + " fs.unit.unit_enthalpy_balance[0.0]: 1.973E+06\n", + " fs.unit.unit_phase_equilibrium[0.0,H2O]: 1.589E+06\n", + " fs.unit.unit_pressure_balance[0.0]: 1.414E+05\n", + "\n", + "====================================================================================\n" + ] + } + ], + "source": [ + "dt.display_variables_with_extreme_jacobians()\n", + "dt.display_constraints_with_extreme_jacobians()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "These four unit model level constraints are causing our remaining problems.\n", + "\n", + "## Step 5: Unit Model Level Scaling\n", + "\n", + "We should take a look at the constraints before determining their scaling factors. However, Pyomo's `pprint` method often prints out multiple terminal pages' worth of thermodynamic expressions, which are extremely difficult to parse. The output is so verbose because it descends into named `Expressions` and recursively subsititutes them into the constraint expression. Since IDAES makes heavy use of named `Expressions` to decrease the number of `Constraints` in a model, the output becomes unmanangable for all but the most simple constraints. The `print_compact_form` utility function usually results in much more readable output." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "- fs.unit.liquid_phase.enthalpy_transfer[0.0] == (kg*m**2/J/s**2)*fs.unit.vapor_phase[0.0]._enthalpy_flow_term[Vap]\n" + ] + } + ], + "source": [ + "from idaes.core.util.misc import print_compact_form\n", + "\n", + "print_compact_form(m.fs.unit.unit_enthalpy_balance[0.0])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This is a relatively straightforward constraint.\n", + "\n", + "So long as we have scaling factors set for the terms in the enthalpy balance, we can scale the constraint by the same factor. Because `liquid_phase.enthalpy_transfer[0.0]` is a `Var` created by the `ControlVolume0D`, it already has a scaling factor assigned by the `ControlVolume0DScaler`.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "5.076760620583219e-07" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "get_scaling_factor(m.fs.unit.liquid_phase.enthalpy_transfer[0.0])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "However, in the modular property framework, `get_enthalpy_flow_terms(p)` returns a named `Expression`. Expressions do not need to be scaled on their own. However, scaling hints can be assigned for them to assist in determining appropriate scaling factors for other variables and constraints. When the `get_scaling_factor` function is called on an `Expression`, it will return a scaling hint if one is assigned. (This behavior is useful, because what is a `Var` in one property package can be implemented as an `Expression` in another.)\n", + "\n", + "In this case, however, no scaling hint is assigned to `vapor_phase[0.0]._enthalpy_flow_term[\"Vap\"]`." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "None\n" + ] + } + ], + "source": [ + "print(get_scaling_factor(m.fs.unit.vapor_phase[0.0]._enthalpy_flow_term[\"Vap\"]))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To get an estimate of the size of that expression, then, we can look at its constituent terms:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "fs.unit.vapor_phase[0.0].flow_mol_phase[Vap]*fs.unit.vapor_phase[0.0].enth_mol_phase[Vap]\n" + ] + } + ], + "source": [ + "print_compact_form(m.fs.unit.vapor_phase[0.0]._enthalpy_flow_term[\"Vap\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The term `vapor_phase[0.0].flow_mol_phase[\"Vap\"]` *is* a `Var` and has a scaling factor applied." + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.1" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "get_scaling_factor(m.fs.unit.vapor_phase[0.0].flow_mol_phase[\"Vap\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "However, `vapor_phase[0.0].enth_mol_phase[\"Vap\"]` is a named `Expression`. Nevertheless, it has a scaling hint." + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "5.46268982847154e-05" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "get_scaling_factor(m.fs.unit.vapor_phase[0.0].enth_mol_phase[\"Vap\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Because the scaling factor of the molar flow rate is $0.1$, we can estimate that the molar flow rate will be about $10$. Similarly, we can estimate the size of a significant molar enthalpy difference is around the size of `1/5.46e-5`$ \\approx 18,000$. Therefore the general size of the enthalpy flow terms should be around $180,000$." + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.0125" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "get_scaling_factor(m.fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase[\"Liq\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The `get_sum_terms_nominal_values` method in `CustomScalerBase` which uses an expression walker to go through an expression to return a list of the expected magnitude (or \"nominal value\") of all additive terms in the expression based on the scaling factors for the variables involved. For example, suppose we have an expression\n", + "$$\n", + "a + b\\cdot c - d\\cdot (e - f)\n", + "$$\n", + "Let $\\sigma(v)$ denote the scaling factor of the variable $v$. Then `get_sum_terms_nominal_values` substitutes the inverse of the variable scaling factor into each term in the sum and returns it as a list:\n", + "$$\n", + "\\left[\\frac{1}{\\sigma(a)},\\; \\frac{1}{\\sigma(b) \\cdot \\sigma(c)}, \\frac{\\left(\\frac{1}{\\sigma(e)} - \\frac{1}{\\sigma(f)}\\right)}{\\sigma(d)} \\right]\n", + "$$\n", + "\n", + "This process can produce reliable estimates of expression magnitude for certain operations:\n", + " - Addition of positive numbers\n", + " - Multiplication and division\n", + " - Raising a variable to a fixed power\n", + "\n", + "For these operations, only an order-of-magnitude estimate for the variable is sufficient to get an order-of-magnitude estimate of the resulting expression. However, it is far less reliable for other operations:\n", + " - Subtraction (or addition of negative numbers to positive numbers)\n", + " - Functions with a variable exponent\n", + " - Trigometric functions\n", + " - Logarithms\n", + "\n", + "For these operations, an expression's final value is highly dependent on the exact values of its included variables. For example, suppose $\\sigma(e) = \\sigma(f)$. In that case, the term $d\\cdot (e - f)$ would have an estimated magnitude of $0$, which is useless for scaling purposes. It is in cases like this that scaling hints for named expressions. If we denote $G = e - f$ and assign $\\sigma(G) = \\sigma(e)$, we have a far better estimate of the term $d\\cdot (e - f)$ in the quantity $1/(\\sigma(d)\\cdot\\sigma(G))$.\n", + "\n", + "Logarithms are a special case. Since they convert multiplication to addition, application of a scaling factor simply shifts the zero point of the resulting expression.\n", + "$$\n", + " \\log(h \\cdot \\sigma(h)) = \\log(h) + \\log(\\sigma(h))\n", + "$$\n", + "\n", + "The output of a logarithmic expression should be considered well-scaled by default, unless its argument is an absolutely enormous number (in which case floating point arithmetic is probably inappropriate anyway).\n", + "\n", + "In the case of scaling `unit.unit_enthalpy_balance[0.0]`, we only have two additive terms, one consisting of a single variable, the other consisting of the product of a variable with an expression with a scaling hint. In this case, `get_sum_terms_nominal_values` should produce a good estimate of the order-of-magnitude of each term.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[1969759.9999999995, 183060.0]" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "reboiler_scaler.get_sum_terms_nominal_values(m.fs.unit.unit_enthalpy_balance[0.0])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The inverse of either of these numbers would be reasonable scaling factors. The `scale_constraint_by_nominal value` function automatically scales a constraint by using one of these numbers. Which number we use is selected using the `ConstraintScalingScheme` `Enum` If we take the inverse of the larger number, we are saying that the constraint needs to be satisfied with the same precision as the largest term in the sum. This corresponds to `ConstraintScalingScheme.inverseMaximum`. If we take the inverse of the smaller number, we are saying that the constraint needs to be satisfied with the same precision as the smallest term in the sum. This corresponds to `ConstraintScalingScheme.inverseMinimum`.\n", + "\n", + "In general, the `inverseMinimum` scheme is the safest to use, because it demands the most precision. Let's use the `inverseMinimum` method for this constraint in order to more precisely determine the vapor phase's temperature.\n", + "\n", + "The next two constraints can be dealt with together:" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[Liq,CO2] == fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,CO2]\n", + "\n", + "\n", + "fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[Liq,H2O] == fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,H2O]\n" + ] + } + ], + "source": [ + "print_compact_form(m.fs.unit.unit_phase_equilibrium[0.0, \"CO2\"])\n", + "print(\"\\n\")\n", + "print_compact_form(m.fs.unit.unit_phase_equilibrium[0.0, \"H2O\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "These are simple vapor-liquid equilibrium constraints for the volatile components. Let's see what `get_sum_terms_nominal_values` shows for them:" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "tags": [ + "testing" + ] + }, + "outputs": [], + "source": [ + "CO2_nom = reboiler_scaler.get_sum_terms_nominal_values(\n", + " m.fs.unit.unit_phase_equilibrium[0.0, \"CO2\"]\n", + ")\n", + "CO2_nom.sort()\n", + "assert CO2_nom[0] == pytest.approx(1e4, rel=1e-2)\n", + "assert CO2_nom[1] == pytest.approx(7623000, rel=1e-2)\n", + "\n", + "H2O_nom = reboiler_scaler.get_sum_terms_nominal_values(\n", + " m.fs.unit.unit_phase_equilibrium[0.0, \"H2O\"]\n", + ")\n", + "H2O_nom.sort()\n", + "assert H2O_nom[0] == pytest.approx(355.4, rel=1e-2)\n", + "assert H2O_nom[1] == pytest.approx(1e4, rel=1e-2)" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[7623092.433711249, 10000.0]\n", + "[355.3596511053128, 10000.0]\n" + ] + } + ], + "source": [ + "print(\n", + " reboiler_scaler.get_sum_terms_nominal_values(\n", + " m.fs.unit.unit_phase_equilibrium[0.0, \"CO2\"]\n", + " )\n", + ")\n", + "print(\n", + " reboiler_scaler.get_sum_terms_nominal_values(\n", + " m.fs.unit.unit_phase_equilibrium[0.0, \"H2O\"]\n", + " )\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here, we see that, while the vapor phase fugacities are associated with a nominal value of 10000, the liquid phase fugacities have wildly different nominal values. We do expect the vapor phase to be enriched in $\\text{CO}_2$, but not by a factor of $2\\cdot 10^4$. Let's unpack these values. We are using the ideal gas law for the vapor phase, so the fugacity is simply the product of the mole fraction and vapor pressure:" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]*fs.unit.vapor_phase[0.0].pressure\n" + ] + } + ], + "source": [ + "print_compact_form(m.fs.unit.vapor_phase[0.0].fug_phase_comp[\"Vap\", \"CO2\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The liquid phase, by contrast, contains a complicated Henry's Law type relationship for $\\text{CO}_2$ and a slightly less complicated Antoine's Law relationship for $\\text{H}_2\\text{O}$:" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,CO2]*(exp(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O])*log(244800.0*exp(-1348*K/fs.unit.liquid_phase.properties_out[0.0].temperature)*(3520000.0*exp(-2113*K/fs.unit.liquid_phase.properties_out[0.0].temperature)/(8449000.0*exp(-2283*K/fs.unit.liquid_phase.properties_out[0.0].temperature)))) + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O])*log(3520000.0*exp(-2113*K/fs.unit.liquid_phase.properties_out[0.0].temperature)) + fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O])*(fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]))*(fs.liquid_properties.CO2.lwm_coeff_1 + K**(-1)*fs.liquid_properties.CO2.lwm_coeff_2*(fs.unit.liquid_phase.properties_out[0.0].temperature - 273.15*K) + K**(-2)*fs.liquid_properties.CO2.lwm_coeff_3*(fs.unit.liquid_phase.properties_out[0.0].temperature - 273.15*K)**2 + fs.liquid_properties.CO2.lwm_coeff_4*(fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]))))*Pa*m**3*mol**(-1))\n" + ] + } + ], + "source": [ + "print_compact_form(\n", + " m.fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[\"Liq\", \"CO2\"]\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Parsing the entire pile of thermodynamic gibberish is unnecessary to plan our next move. We can plainly see that the liquid phase fugacity expression is rife with subtraction and exponentiation, both of which are dangerous for the nominal value expression walker. Even worse, we are scaling based on a failed solution, so the values may be off anyway. It is far better to base the scaling factor on the vapor phase fugacity. The `get_expression_nominal_value` function allows the user to get the nominal value of a single expression." + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "10000.0" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "reboiler_scaler.get_expression_nominal_value(\n", + " m.fs.unit.vapor_phase[0.0].fug_phase_comp[\"Vap\", \"CO2\"]\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "While in this case this value is positive, the nominal value can be negative, so you should use the absolute value when getting a scaling factor.\n", + "\n", + "Finally, we have the last constraint: mechanical equilibrium between phases.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "fs.unit.liquid_phase.properties_out[0.0].pressure == fs.unit.vapor_phase[0.0].pressure\n" + ] + } + ], + "source": [ + "print_compact_form(m.fs.unit.unit_pressure_balance[0.0])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The `inverseMinimum` scheme will work here as well.\n", + "\n", + "In addition to these problematic unit model level constraints, there are some additional constraints that need scaling factors. Although they might not be problematic under these process conditions, they may be for a scaled-up flowsheet. If we suspect they are well-scaled already, we should use the `report_scaling_factors` function to show what they are:" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Scaling Factors for block fs.unit\n", + "\n", + "Variable Scaling Factor Value Scaled Value\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol 1.250E-02 8.389E+01 1.049E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[H2O] 1.000E+01 8.589E-01 8.589E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[MEA] 1.000E+01 1.085E-01 1.085E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[CO2] 1.000E+01 3.260E-02 3.260E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].temperature 3.333E-03 3.925E+02 1.308E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol 1.250E-02 7.424E+01 9.279E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O] 1.000E+01 8.527E-01 8.527E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] 1.000E+01 1.226E-01 1.226E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[CO2] 1.000E+01 2.471E-02 2.471E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].temperature 3.333E-03 3.926E+02 1.309E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", + "fs.unit.vapor_phase[0.0].flow_mol 1.000E-01 9.654E+00 9.654E-01\n", + "fs.unit.vapor_phase[0.0].mole_frac_comp[CO2] 1.000E+01 9.329E-02 9.329E-01\n", + "fs.unit.vapor_phase[0.0].mole_frac_comp[H2O] 1.000E+01 9.067E-01 9.067E+00\n", + "fs.unit.vapor_phase[0.0].mole_frac_comp[N2] 1.000E+01 1.055E-09 1.055E-08\n", + "fs.unit.vapor_phase[0.0].mole_frac_comp[O2] 1.000E+01 1.055E-09 1.055E-08\n", + "fs.unit.vapor_phase[0.0].temperature 3.333E-03 3.926E+02 1.309E+00\n", + "fs.unit.vapor_phase[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", + "fs.unit.liquid_phase.heat[0.0] 5.077E-07 4.306E+05 2.186E-01\n", + "\n", + "Constraint Scaling Factor\n", + "fs.unit.unit_material_balance[0.0,CO2] None\n", + "fs.unit.unit_material_balance[0.0,H2O] None\n", + "fs.unit.unit_material_balance[0.0,N2] None\n", + "fs.unit.unit_material_balance[0.0,O2] None\n", + "fs.unit.unit_material_balance[0.0,MEA] None\n", + "fs.unit.unit_phase_equilibrium[0.0,CO2] None\n", + "fs.unit.unit_phase_equilibrium[0.0,H2O] None\n", + "fs.unit.unit_temperature_equality[0.0] None\n", + "fs.unit.unit_enthalpy_balance[0.0] None\n", + "fs.unit.unit_pressure_balance[0.0] None\n" + ] + } + ], + "source": [ + "from idaes.core.scaling.util import report_scaling_factors\n", + "\n", + "report_scaling_factors(m.fs.unit, descend_into=False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We have yet to scale the `unit_temperature_equality` and `unit_material_balance`constraints. The temperature equality constraint is simple." + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "fs.unit.liquid_phase.properties_out[0.0].temperature == fs.unit.vapor_phase[0.0].temperature\n" + ] + } + ], + "source": [ + "print_compact_form(m.fs.unit.unit_temperature_equality[0.0])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "`inverseMinimum` works fine here.\n", + "\n", + "The material balance constraints have different forms depending on whether a component occurs in the liquid phase, the vapor phase, or both:" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "- fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,CO2] == fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,CO2]\n", + "\n", + "\n", + "fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,MEA] == 0*(mol*s**(-1))\n", + "\n", + "\n", + "fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,N2] == fs.unit.zero_flow_param\n" + ] + } + ], + "source": [ + "print_compact_form(m.fs.unit.unit_material_balance[0.0, \"CO2\"])\n", + "print(\"\\n\")\n", + "print_compact_form(m.fs.unit.unit_material_balance[0.0, \"MEA\"])\n", + "print(\"\\n\")\n", + "print_compact_form(m.fs.unit.unit_material_balance[0.0, \"N2\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The first constraint equates the vapor flow rate to the mass transfer from the liquid phase. Either inverse maximum or inverse minimum would work. The next two are a bit trickier. For $\\text{MEA}$, which is considered nonvolatile in this property package, there is no mass transfer to the vapor phase. A common misconception is that variables should always be scaled to be order one. That is incorrect. We only need to calculate `mass_transfer_term[0.0,\"Liq\",\"MEA\"]` to the same precision as the other (nonzero) terms of the mass balance (and the `ControlVolume0D` submodel scaler does just that). Similarly, `flow_mol_phase_comp[\"Vap\",\"N2\"]` is set to a tiny nonzero value (because flows that are exactly zero often cause problems for property calculations). We do not need more significant figures for either of those variables than the rest of the terms in their correspoding material balances. Therefore we want to use the `inverseMaximum` becuase `inverseMinimum` would demand unnecessary precision.\n", + "\n", + "
\n", + "NOTE\n", + "\n", + "If we had relied on autoscaling methods to fill in scaling factors for these variables and constraints, we would have ended up with enormous scaling factors for `flow_mol_phase_comp[\"Vap\",\"N2\"]` and `flow_mol_phase_comp[\"Vap\",\"O2\"]` because they are not-quite equal to zero at the model solution.\n", + "\n", + "Similarly, `m.fs.unit.unit_phase_equilibrium[0.0,\"CO2\"]` would have been overscaled due to the enormous nominal value given by the expression walker for the liquid phase fugacity\n", + "\n", + "
\n", + "\n", + "Finally, we can complete the scaler object." + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [], + "source": [ + "from idaes.core.scaling.custom_scaler_base import ConstraintScalingScheme\n", + "\n", + "\n", + "class SolventReboilerScaler(CustomScalerBase):\n", + " def variable_scaling_routine(\n", + " self, model, overwrite: bool = False, submodel_scalers: dict = None\n", + " ):\n", + " # Call scaling methods for sub-models\n", + " self.call_submodel_scaler_method(\n", + " submodel=model.liquid_phase,\n", + " method=\"variable_scaling_routine\",\n", + " submodel_scalers=submodel_scalers,\n", + " overwrite=overwrite,\n", + " )\n", + "\n", + " self.call_submodel_scaler_method(\n", + " submodel=model.vapor_phase,\n", + " method=\"variable_scaling_routine\",\n", + " submodel_scalers=submodel_scalers,\n", + " overwrite=overwrite,\n", + " )\n", + "\n", + " def constraint_scaling_routine(\n", + " self, model, overwrite: bool = False, submodel_scalers: dict = None\n", + " ):\n", + " # Call scaling methods for sub-models\n", + " self.call_submodel_scaler_method(\n", + " submodel=model.liquid_phase,\n", + " method=\"constraint_scaling_routine\",\n", + " submodel_scalers=submodel_scalers,\n", + " overwrite=overwrite,\n", + " )\n", + "\n", + " self.call_submodel_scaler_method(\n", + " submodel=model.vapor_phase,\n", + " method=\"constraint_scaling_routine\",\n", + " submodel_scalers=submodel_scalers,\n", + " overwrite=overwrite,\n", + " )\n", + " # Note: scaling factors cannot be applied directly to indexed objects.\n", + " # They should be applied to VarData/ConstraintData/ExpressionData children instead.\n", + " for condata in model.unit_material_balance.values():\n", + " self.scale_constraint_by_nominal_value(\n", + " condata,\n", + " scheme=ConstraintScalingScheme.inverseMaximum,\n", + " overwrite=overwrite,\n", + " )\n", + " for condata in model.unit_temperature_equality.values():\n", + " self.scale_constraint_by_nominal_value(\n", + " condata,\n", + " scheme=ConstraintScalingScheme.inverseMinimum,\n", + " overwrite=overwrite,\n", + " )\n", + " for condata in model.unit_enthalpy_balance.values():\n", + " self.scale_constraint_by_nominal_value(\n", + " condata,\n", + " scheme=ConstraintScalingScheme.inverseMinimum,\n", + " overwrite=overwrite,\n", + " )\n", + " for condata in model.unit_pressure_balance.values():\n", + " self.scale_constraint_by_nominal_value(\n", + " condata,\n", + " scheme=ConstraintScalingScheme.inverseMinimum,\n", + " overwrite=overwrite,\n", + " )\n", + " for (t, j), condata in m.fs.unit.unit_phase_equilibrium.items():\n", + " nom = abs(\n", + " self.get_expression_nominal_value(\n", + " m.fs.unit.vapor_phase[t].fug_phase_comp[\"Vap\", j]\n", + " )\n", + " )\n", + " self.set_constraint_scaling_factor(condata, 1 / nom, overwrite=overwrite)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can see how this works on the model. We'll pass `overwrite=True` config option when creating the scaler object to ensure we have up-to-date scaling factors." + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Starting initialization routine\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Bubble, dew, and critical point initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Equilibrium temperature initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: State variable initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Phase equilibrium initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Property initialization routine finished.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Starting initialization routine\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Bubble, dew, and critical point initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Equilibrium temperature initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: State variable initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Phase equilibrium initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Property initialization routine finished.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: Starting initialization routine\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: Bubble, dew, and critical point initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: Equilibrium temperature initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: State variable initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: Phase equilibrium initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: Property initialization routine finished.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit: Initialization Complete: optimal - \n" + ] + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "scaler_obj = SolventReboilerScaler(overwrite=True)\n", + "scaler_obj.scale_model(m.fs.unit)\n", + "reboiler_init.initialize(m.fs.unit)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We see that scaling improved the model enough so that initialization could succeed. Now let's look at the numerical issues." + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "====================================================================================\n", + "Model Statistics\n", + "\n", + " Jacobian Condition Number: 5.400E+06\n", + "\n", + "------------------------------------------------------------------------------------\n", + "0 WARNINGS\n", + "\n", + " No warnings found!\n", + "\n", + "------------------------------------------------------------------------------------\n", + "6 Cautions\n", + "\n", + " Caution: 9 Variables with value close to their bounds (abs=1.0E-04, rel=1.0E-04)\n", + " Caution: 14 Variables with value close to zero (tol=1.0E-08)\n", + " Caution: 27 Variables with extreme value (<1.0E-04 or >1.0E+04)\n", + " Caution: 2 Constraints with mismatched terms\n", + " Caution: 1 Constraint with potential cancellation of terms\n", + " Caution: 20 extreme Jacobian Entries (<1.0E-04 or >1.0E+04)\n", + "\n", + "------------------------------------------------------------------------------------\n", + "Suggested next steps:\n", + "\n", + " If you still have issues converging your model consider:\n", + "\n", + " prepare_degeneracy_hunter()\n", + " prepare_svd_toolbox()\n", + "\n", + "====================================================================================\n" + ] + } + ], + "source": [ + "dt = DiagnosticsToolbox(m)\n", + "dt.report_numerical_issues()" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": { + "tags": [ + "testing" + ] + }, + "outputs": [], + "source": [ + "assert jacobian_cond(m.fs.unit) == pytest.approx(5.40e6, rel=1e-2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We have reduced the Jacobian condition number by another four orders of magnitude, as well as eliminating all extreme Jacobian rows and columns. A condition number of $5\\cdot 10^6$ is still higher than we'd like for a single unit model, especially for a simple unit model like this one, because connecting units together as part of a flowsheet inevitably increases the condition number. \n", + "\n", + "## Step 6: Singular Value Decomposition\n", + "\n", + "With no more extreme Jacobian rows or columns, we have two avenues to proceed:\n", + "1. Check the extreme Jacobian *entries*\n", + "2. Check the singular value decomposition (SVD) of the Jacobian\n", + "\n", + "Extreme Jacobian entries only *suggest* that the variable and constraint might be contributing to ill-conditioning\u2014they might also be false positives. However, extreme singular values are *guaranteed* to be contributing to the Jacobian's ill-conditioning. Therefore, we will look at the SVD next.\n", + "\n", + "The singular value decomposition factorizes a matrix into three parts:\n", + "$$\n", + "\\mathbf{J} = \\mathbf{U \\Sigma V}^T\n", + "$$\n", + "Both $\\mathbf{U}$ and $\\mathbf{V}$ are orthogonal matrices, i.e., $\\mathbf{U}^T \\mathbf{U} = \\mathbf{I}$ and $\\mathbf{V}^T\\mathbf{V} = \\mathbf{I}$. If $\\mathbf{J}$ is square, then $\\mathbf{\\Sigma}$ is a diagonal matrix of the form:\n", + "$$\n", + "\\mathbf{\\Sigma} = \\begin{bmatrix}\n", + " \\sigma_1 & 0 & \\dots & 0 \\\\\n", + " 0 & \\sigma_2 & \\dots & 0 \\\\\n", + " \\vdots & \\vdots & \\ddots & \\vdots\\\\\n", + " 0 & 0 & \\dots & \\sigma_n\n", + " \\end{bmatrix}\n", + "$$\n", + "in which $\\sigma_j$ are the singular values. The singular values are arranged in descending order, i.e., $\\sigma_{j+1} \\leq \\sigma_{j}$. If any $\\sigma_j=0$, then the matrix is singular.\n", + "\n", + "The condition number is given by:\n", + "$$\n", + "\\kappa(\\mathbf{J}) = \\sigma_1 / \\sigma_n\n", + "$$\n", + "Thus, extremely large and extremely small singular values cause matrix ill-conditioning. However, extremely large singular values typically show up as rows and columns with extreme norms. Therefore we will look at the smallest singular values.\n", + "\n", + "Because $\\mathbf{U}$ and $\\mathbf{V}$ are orthogonal and $\\mathbf{\\Sigma}$ is diagonal, computing a Newton step is easy once the SVD is calculated.\n", + "$$\n", + "\\mathbf{\\delta x}_k = -\\mathbf{V \\Sigma^{-1} U}^T \\cdot \\mathbf{f}(\\mathbf{x}_k)\n", + "$$\n", + "Since we have to refactorize $\\mathbf{J}$ at each iteration, the SVD is not an efficient method to calculate a Newton step. However, this process has a geometric interpretation that is useful for model diagnostics and scaling. First, the constraint residual is decomposed into orthogonal components by $\\mathbf{U}$:\n", + "$$\n", + "\\mathbf{s} = -\\mathbf{U}^T \\cdot \\mathbf{f}(\\mathbf{x}_k)\n", + "$$\n", + "Next, these orthogonal components are scaled by the inverse of the associated singular value:\n", + "$$\n", + "\\mathbf{\\tilde{s}} = \\Sigma^{-1} \\cdot \\mathbf{s}\n", + "$$\n", + "Finally, these independent components are translated into the variable space by $\\mathbf{V}$:\n", + "$$\n", + "\\mathbf{\\delta x}_k = \\mathbf{V} \\cdot \\mathbf{\\tilde{s}}\n", + "$$\n", + "So each orthogonal component of the constraint residual space is associated with an orthogonal component of the variable space. In particular, each singular value $\\sigma_j$ is associated with a left singular vector $\\mathbf{u}_j$ and right singular vector $\\mathbf{v}_j$, the $j\\text{th}$ columns of $\\mathbf{U}$ and $\\mathbf{V}$, respectively. Any constraint error in the direction of $\\mathbf{u}_j$ *must* be satisfied by a corresponding change in the direction of $\\mathbf{v}_j$. When $\\sigma_j$ is extremely small, tiny changes in the direction of $\\mathbf{u}_j$ translate into enormous changes in $\\mathbf{v}_j$. This dysfunctional relationship can be a sign of bad scaling, but also can be a sign of some other model issue like numerical singularity. Typically, singular values in the range $10^{-12}$ to $10^{-4}$ are signs of either bad scaling or a highly sensitive model (for example, a flowsheet with a large recycle stream). Values below $10^{-12}$ are indicative of numerical singularity.\n", + "\n", + "
\n", + "NOTE\n", + "\n", + "The singular vectors $\\mathbf{u}_j$ and $\\mathbf{v}_j$ are typically dense. In order to link them with specific variables and constraints, a thresholding scheme is applied. The `size_cutoff_in_singular_vector` config option for the `SVDToolbox` controls the magnitude of an entry in $\\mathbf{u}_j$ and $\\mathbf{v}_j$ that is sufficient to link a variable or constraint to the $\\sigma_j$. It is `0.1` by default, but can take on values between about `0.05` and `0.3`. Decrease it to show fewer variables and constraints, increase it to show more variables and constraints.\n", + "\n", + "
\n", + "\n", + "So let's create an instance of the `SVDToolbox` and display the variables and constraints associated with the 5 smallest singular values.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "====================================================================================\n", + "Constraints and Variables associated with smallest singular values\n", + "\n", + " 1st Smallest Singular Value: 6.356e-04\n", + "\n", + " Variables:\n", + "\n", + " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_comp[CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_comp[H2O]\n", + "\n", + " Constraints:\n", + "\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2]\n", + "\n", + " 2nd Smallest Singular Value: 2.781e-02\n", + "\n", + " Variables:\n", + "\n", + " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_comp[CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_comp[H2O]\n", + "\n", + " Constraints:\n", + "\n", + " fs.unit.unit_material_balance[0.0,CO2]\n", + " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", + "\n", + " 3rd Smallest Singular Value: 3.679e-02\n", + "\n", + " Variables:\n", + "\n", + " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_comp[CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_comp[H2O]\n", + "\n", + " Constraints:\n", + "\n", + " fs.unit.unit_material_balance[0.0,CO2]\n", + " fs.unit.liquid_phase.material_balances[0.0,MEA]\n", + " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", + " fs.unit.liquid_phase.enthalpy_balances[0.0]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", + " fs.unit.unit_material_balance[0.0,MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,HCO3_-]\n", + " fs.unit.vapor_phase[0.0].sum_mole_frac_out\n", + "\n", + " 4th Smallest Singular Value: 6.842e-02\n", + "\n", + " Variables:\n", + "\n", + " fs.unit.vapor_phase[0.0].flow_mol_phase[Vap]\n", + " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,H2O]\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]\n", + " fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,H2O]\n", + " fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,H2O]\n", + " fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,H2O]\n", + " fs.unit.vapor_phase[0.0].mole_frac_comp[H2O]\n", + " fs.unit.vapor_phase[0.0].flow_mol\n", + "\n", + " Constraints:\n", + "\n", + " fs.unit.unit_material_balance[0.0,CO2]\n", + " fs.unit.liquid_phase.material_balances[0.0,MEA]\n", + " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", + " fs.unit.liquid_phase.enthalpy_balances[0.0]\n", + " fs.unit.unit_material_balance[0.0,MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].total_flow_balance\n", + " fs.unit.vapor_phase[0.0].sum_mole_frac_out\n", + "\n", + " 5th Smallest Singular Value: 7.703e-02\n", + "\n", + " Variables:\n", + "\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,H2O]\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]\n", + " fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,H2O]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_k_eq[bicarbonate]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_k_eq[carbamate]\n", + "\n", + " Constraints:\n", + "\n", + " fs.unit.liquid_phase.material_balances[0.0,MEA]\n", + " fs.unit.unit_material_balance[0.0,MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].total_flow_balance\n", + " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[MEA]\n", + " fs.unit.liquid_phase.properties_out[0.0].sum_mole_frac_out\n", + "\n", + "====================================================================================\n" + ] + } + ], + "source": [ + "st = dt.prepare_svd_toolbox()\n", + "# The SVD toolbox displays 10 singular values by default, but we are going to\n", + "# view the only the first five to reduce the amount of output.\n", + "st.display_underdetermined_variables_and_constraints(singular_values=[1, 2, 3, 4, 5])" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": { + "tags": [ + "testing" + ] + }, + "outputs": [], + "source": [ + "assert st.s[0] == pytest.approx(6.356e-04, rel=1e-2)\n", + "assert st.s[1] == pytest.approx(2.781e-02, rel=1e-2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The smallest singular value is 40 times smaller than the second smallest singular value. This usually means that we can significantly improve the matrix conditioning by scaling only a small number of variables and constraints. There is only one constraint strongly associated with the smallest singular value, so let's start with that." + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "exp(fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]) == fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,CO2]/(mol/m**3)\n" + ] + } + ], + "source": [ + "print_compact_form(\n", + " m.fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[\n", + " \"Liq\", \"CO2\"\n", + " ]\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This constraint converts between the $\\text{CO}_2$ concentration and its logarithm. Using these sorts of log-form variables can increase the number of significant digits when dealing with reactions involving components in small quantities. (They can also introduce degeneracy when dealing with trace quantities that *do not* appear in reactions.)\n", + "\n", + "The SVD Toolbox also has two helper functions: `display_variables_in_constraint`, which displays the Jacobian row corresponding to a constraint, and `display_constraints_including_variable`, which displays the Jacobian column corresponding to a variable." + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "====================================================================================\n", + "The following variables are involved in fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2]:\n", + "\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,H2O]: 4.333e-05\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,MEA]: 1.441e-04\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,CO2]: 6.126e-05\n", + " fs.unit.liquid_phase.properties_out[0.0].temperature: 1.576e-04\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]: -5.255e-07\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA]: 5.123e-06\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,CO2]: -1.648e+00\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]: 5.621e-04\n", + "\n", + "====================================================================================\n" + ] + } + ], + "source": [ + "st.display_variables_in_constraint(\n", + " m.fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[\n", + " \"Liq\", \"CO2\"\n", + " ]\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "NOTE\n", + "\n", + "At this point of the process, the original author found a shortcoming in the `ModularPropertiesScaler`. No scaling hint was set for the molar density expression, so the expression walker descended into it and came back with an inappropriate nominal value. Revising the scaler to estimate the phase density resulted in a condition number improvement of 1-2 orders of magnitude.\n", + "\n", + "Remember:\n", + "1. Scaling is an iterative process.\n", + "2. Submodel scalers may need to be revised to fix scaling issues.\n", + "3. Using the expression walker in an expression tree that involves subtraction or exponential functions is dangerous.\n", + "
\n", + "\n", + "From our knowledge of the physical properties, `mole_frac_phase_comp_true[\"Liq\",\"CO2\"]` and `log_conc_mol_phase_comp_true[\"Liq\",\"CO2\"]` should have the largest effects on this equation. The other variables affect the concentration indirectly through the phase density. But while `mole_frac_phase_comp_true[\"Liq\",\"CO2\"]` does have an appropriately-sized impact, `log_conc_mol_phase_comp_true[\"Liq\",\"CO2\"]` is several orders-of-magnitude too small. A naive approach might be to decrease the scaling factor on `log_conc_mol_phase_comp_true[\"Liq\",\"CO2\"]` until it has an appropriately-sized effect in the equation. Remember, though, that log variables are well-scaled by default. Something else must be wrong.\n", + "\n", + "Let's take a look at the values on both sides of the equation." + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Left hand side value: 1.3698e+00\n", + "CO2 true concentration value: 1.3698e+00\n" + ] + } + ], + "source": [ + "print(\n", + " f\"Left hand side value: {value(exp(m.fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[\"Liq\",\"CO2\"])):.4e}\"\n", + ")\n", + "print(\n", + " f\"CO2 true concentration value: {value(m.fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[\"Liq\",\"CO2\"]):.4e}\"\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Since the left hand side and right hand side both have values of order one, we expect the equation to have a similar scaling factor." + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": { + "tags": [ + "testing" + ] + }, + "outputs": [], + "source": [ + "assert get_scaling_factor(\n", + " (\n", + " m.fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[\n", + " \"Liq\", \"CO2\"\n", + " ]\n", + " )\n", + ") == pytest.approx(4.104e-4, rel=1e-2)" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.0004103666666666667\n" + ] + } + ], + "source": [ + "print(\n", + " get_scaling_factor(\n", + " (\n", + " m.fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[\n", + " \"Liq\", \"CO2\"\n", + " ]\n", + " )\n", + " )\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "However, it actually has an extremely small scaling factor. To what can we attribute this?\n", + "\n", + "It is a result of not setting good default values for the true species mole fractions in the liquid phase. Although the apparent $\\text{CO}_2$ mole fraction is about 0.03, almost all of that is in the form of a carbamate salt formed through reaction with $\\text{MEA}$. The true mole fraction is significantly lower." + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True CO2 mole fraction: 3.410357e-05\n", + "True MEACOO- mole fraction: 2.796223e-02\n" + ] + } + ], + "source": [ + "print(\n", + " f\"True CO2 mole fraction: {m.fs.unit.liquid_phase.properties_out[0].mole_frac_phase_comp_true[\"Liq\",\"CO2\"].value:4e}\"\n", + ")\n", + "print(\n", + " f\"True MEACOO- mole fraction: {m.fs.unit.liquid_phase.properties_out[0].mole_frac_phase_comp_true[\"Liq\",\"MEACOO_-\"].value:4e}\"\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Nevertheless, the true value of the $\\text{CO}_2$ mole fraction is important because it is used in the calculation of fugacity. It should therefore be assigned a larger scaling factor. Therefore, let's revisit the default scaling factors for the liquid properties:" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": {}, + "outputs": [], + "source": [ + "default_scaling_factors = (\n", + " m.fs.liquid_properties.default_state_scaler_object.default_scaling_factors\n", + ")\n", + "# Dictionaries are mutable, so changing its value here also changes it on the scaler object\n", + "# First scale the apparent mole fractions\n", + "default_scaling_factors[\"mole_frac_phase_comp[Liq, H2O]\"] = 1\n", + "default_scaling_factors[\"mole_frac_phase_comp[Liq, CO2]\"] = 10\n", + "default_scaling_factors[\"mole_frac_phase_comp[Liq, MEA]\"] = 10\n", + "# Next scale the true mole fractions\n", + "default_scaling_factors[\"mole_frac_phase_comp_true[Liq, H2O]\"] = 1\n", + "default_scaling_factors[\"mole_frac_phase_comp_true[Liq, CO2]\"] = 1e4\n", + "default_scaling_factors[\"mole_frac_phase_comp_true[Liq, MEA]\"] = 10\n", + "default_scaling_factors[\"mole_frac_phase_comp_true[Liq, MEA_+]\"] = 10\n", + "default_scaling_factors[\"mole_frac_phase_comp_true[Liq, MEACOO_-]\"] = 10\n", + "default_scaling_factors[\"mole_frac_phase_comp_true[Liq, HCO3_-]\"] = 100" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "With these new scaling factors, let's rescale and resolve the mode, then check the new condition number." + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Starting initialization routine\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Bubble, dew, and critical point initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Equilibrium temperature initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: State variable initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Phase equilibrium initialization completed.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Property initialization routine finished.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Starting initialization routine\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Bubble, dew, and critical point initialization completed.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Equilibrium temperature initialization completed.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: State variable initialization completed.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Phase equilibrium initialization completed.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Property initialization routine finished.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: Starting initialization routine\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: Bubble, dew, and critical point initialization completed.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: Equilibrium temperature initialization completed.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: State variable initialization completed.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: Phase equilibrium initialization completed.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: Property initialization routine finished.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit: Initialization Complete: optimal - \n", + "====================================================================================\n", + "Model Statistics\n", + "\n", + " Jacobian Condition Number: 2.945E+05\n", + "\n", + "------------------------------------------------------------------------------------\n", + "0 WARNINGS\n", + "\n", + " No warnings found!\n", + "\n", + "------------------------------------------------------------------------------------\n", + "6 Cautions\n", + "\n", + " Caution: 9 Variables with value close to their bounds (abs=1.0E-04, rel=1.0E-04)\n", + " Caution: 14 Variables with value close to zero (tol=1.0E-08)\n", + " Caution: 27 Variables with extreme value (<1.0E-04 or >1.0E+04)\n", + " Caution: 2 Constraints with mismatched terms\n", + " Caution: 1 Constraint with potential cancellation of terms\n", + " Caution: 16 extreme Jacobian Entries (<1.0E-04 or >1.0E+04)\n", + "\n", + "------------------------------------------------------------------------------------\n", + "Suggested next steps:\n", + "\n", + " If you still have issues converging your model consider:\n", + "\n", + " prepare_degeneracy_hunter()\n", + " prepare_svd_toolbox()\n", + "\n", + "====================================================================================\n" + ] + } + ], + "source": [ + "scaler_obj = SolventReboilerScaler(overwrite=True)\n", + "scaler_obj.scale_model(m.fs.unit)\n", + "reboiler_init.initialize(m.fs.unit)\n", + "dt = DiagnosticsToolbox(m)\n", + "dt.report_numerical_issues()" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": { + "tags": [ + "testing" + ] + }, + "outputs": [], + "source": [ + "assert jacobian_cond(m.fs.unit) == pytest.approx(2.945e05, rel=1e-2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The condition number decreased by a factor of 18, which is less than what we might have hoped for. Let's check out the SVD toolbox again." + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "====================================================================================\n", + "Constraints and Variables associated with smallest singular values\n", + "\n", + " 1st Smallest Singular Value: 6.965e-04\n", + "\n", + " Variables:\n", + "\n", + " fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[bicarbonate]\n", + " fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[carbamate]\n", + " fs.unit.liquid_phase.properties_out[0.0].apparent_inherent_reaction_extent[carbamate]\n", + "\n", + " Constraints:\n", + "\n", + " fs.unit.unit_material_balance[0.0,CO2]\n", + " fs.unit.unit_material_balance[0.0,H2O]\n", + " fs.unit.liquid_phase.material_balances[0.0,H2O]\n", + " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].total_flow_balance\n", + " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", + "\n", + " 2nd Smallest Singular Value: 1.047e-03\n", + "\n", + " Variables:\n", + "\n", + " fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[carbamate]\n", + " fs.unit.liquid_phase.properties_out[0.0].apparent_inherent_reaction_extent[carbamate]\n", + "\n", + " Constraints:\n", + "\n", + " fs.unit.unit_material_balance[0.0,CO2]\n", + " fs.unit.unit_material_balance[0.0,H2O]\n", + " fs.unit.liquid_phase.material_balances[0.0,H2O]\n", + " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEA_+]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA_+]\n", + "\n", + " 3rd Smallest Singular Value: 4.024e-03\n", + "\n", + " Variables:\n", + "\n", + " fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[bicarbonate]\n", + " fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[carbamate]\n", + "\n", + " Constraints:\n", + "\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,H2O]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,H2O]\n", + " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,H2O]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", + "\n", + " 4th Smallest Singular Value: 5.218e-03\n", + "\n", + " Variables:\n", + "\n", + " fs.unit.liquid_phase.properties_out[0.0].apparent_inherent_reaction_extent[bicarbonate]\n", + "\n", + " Constraints:\n", + "\n", + " fs.unit.unit_material_balance[0.0,CO2]\n", + " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,HCO3_-]\n", + "\n", + " 5th Smallest Singular Value: 5.115e-02\n", + "\n", + " Variables:\n", + "\n", + " fs.unit.vapor_phase[0.0].flow_mol_phase[Vap]\n", + " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_comp[CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_comp[H2O]\n", + " fs.unit.vapor_phase[0.0].flow_mol\n", + "\n", + " Constraints:\n", + "\n", + " fs.unit.unit_material_balance[0.0,CO2]\n", + " fs.unit.unit_material_balance[0.0,H2O]\n", + " fs.unit.liquid_phase.material_balances[0.0,H2O]\n", + " fs.unit.liquid_phase.material_balances[0.0,MEA]\n", + " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEA_+]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA_+]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA]\n", + " fs.unit.unit_material_balance[0.0,MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].total_flow_balance\n", + " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA_+]\n", + " fs.unit.liquid_phase.properties_out[0.0].sum_mole_frac_out\n", + " fs.unit.vapor_phase[0.0].sum_mole_frac_out\n", + "\n", + "====================================================================================\n" + ] + } + ], + "source": [ + "st = dt.prepare_svd_toolbox()\n", + "st.display_underdetermined_variables_and_constraints([1, 2, 3, 4, 5])" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": {}, + "outputs": [], + "source": [ + "assert st.s[0] == pytest.approx(6.965e-04, rel=1e-2)\n", + "assert st.s[3] == pytest.approx(5.218e-03, rel=1e-2)\n", + "assert st.s[4] == pytest.approx(5.115e-02, rel=1e-2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can see an order-of-magnitude difference between the first four smallest singular values and the fifth-smallest singular value. Inspecting the variables and constraints involved, they all involve the inherent reaction calculations for ionic speciation. Improving the scaling of those variables and constraints might improve the condition number by another one to two orders of magnitude. However, we are reaching the point of diminishing returns for scaling. We can leave the scaler here unless a solver failure forces us to revisit it again.\n", + "\n", + "## Step 7: Reviewing Model Scaling\n", + "\n", + "Before we conclude entirely, let's take a look at all the variable and constraint scaling factors used." + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Scaling Factors for block fs.unit\n", + "\n", + "Variable Scaling Factor Value Scaled Value\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol 1.250E-02 8.389E+01 1.049E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[H2O] 1.000E+00 8.589E-01 8.589E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[MEA] 1.000E+01 1.085E-01 1.085E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[CO2] 1.000E+01 3.260E-02 3.260E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].temperature 3.333E-03 3.925E+02 1.308E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol 1.250E-02 7.410E+01 9.263E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O] 1.000E+00 8.487E-01 8.487E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] 1.000E+01 1.228E-01 1.228E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[CO2] 1.000E+01 2.851E-02 2.851E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].temperature 3.333E-03 3.938E+02 1.313E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", + "fs.unit.vapor_phase[0.0].flow_mol 1.000E-01 9.785E+00 9.785E-01\n", + "fs.unit.vapor_phase[0.0].mole_frac_comp[CO2] 1.000E+01 6.361E-02 6.361E-01\n", + "fs.unit.vapor_phase[0.0].mole_frac_comp[H2O] 1.000E+01 9.364E-01 9.364E+00\n", + "fs.unit.vapor_phase[0.0].mole_frac_comp[N2] 1.000E+01 1.022E-09 1.022E-08\n", + "fs.unit.vapor_phase[0.0].mole_frac_comp[O2] 1.000E+01 1.022E-09 1.022E-08\n", + "fs.unit.vapor_phase[0.0].temperature 3.333E-03 3.938E+02 1.313E+00\n", + "fs.unit.vapor_phase[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", + "fs.unit.liquid_phase.heat[0.0] 8.763E-07 4.306E+05 3.773E-01\n", + "fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,H2O] 1.250E-02 -9.163E+00 -1.145E-01\n", + "fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,MEA] 1.250E-01 0.000E+00 0.000E+00\n", + "fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,CO2] 1.250E-01 -6.224E-01 -7.780E-02\n", + "fs.unit.liquid_phase.enthalpy_transfer[0.0] 8.763E-07 -3.209E+04 -2.812E-02\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase[Liq] 1.250E-02 8.389E+01 1.049E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp[Liq,H2O] 1.000E+00 8.589E-01 8.589E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp[Liq,MEA] 1.000E+01 1.085E-01 1.085E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp[Liq,CO2] 1.000E+01 3.260E-02 3.260E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].phase_frac[Liq] 1.000E+00 1.000E+00 1.000E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,MEACOO_-] 1.250E-01 2.550E+00 3.187E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,HCO3_-] 1.250E+00 1.785E-01 2.231E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,MEA_+] 1.250E-01 2.728E+00 3.410E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,H2O] 1.250E-02 7.187E+01 8.984E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,MEA] 1.250E-01 3.825E+00 4.781E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,CO2] 1.250E+02 6.803E-03 8.504E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,MEACOO_-] 1.000E+01 3.141E-02 3.141E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,HCO3_-] 1.000E+02 2.199E-03 2.199E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,MEA_+] 1.000E+01 3.361E-02 3.361E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,H2O] 1.000E+00 8.856E-01 8.856E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,MEA] 1.000E+01 4.712E-02 4.712E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,CO2] 1.000E+04 8.383E-05 8.383E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[bicarbonate] 1.250E+02 1.785E-01 2.231E+01\n", + "fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[carbamate] 1.250E+02 2.550E+00 3.187E+02\n", + "fs.unit.liquid_phase.properties_in[0.0].log_k_eq[bicarbonate] None -7.578E+00 -7.578E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].log_k_eq[carbamate] None -1.985E+00 -1.985E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-] 1.000E+00 7.168E+00 7.168E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-] 1.000E+00 4.509E+00 4.509E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+] 1.000E+00 7.236E+00 7.236E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,H2O] 1.000E+00 1.051E+01 1.051E+01\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEA] 1.000E+00 7.573E+00 7.573E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,CO2] 1.000E+00 1.242E+00 1.242E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase[Liq] 1.250E-02 7.410E+01 9.263E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,H2O] 1.000E+00 8.487E-01 8.487E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,MEA] 1.000E+01 1.228E-01 1.228E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,CO2] 1.000E+01 2.851E-02 2.851E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].phase_frac[Liq] 1.000E+00 1.000E+00 1.000E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,MEACOO_-] 1.250E-01 2.013E+00 2.516E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,HCO3_-] 1.250E+00 9.684E-02 1.210E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,MEA_+] 1.250E-01 2.110E+00 2.637E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,H2O] 1.250E-02 6.279E+01 7.849E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,MEA] 1.250E-01 4.979E+00 6.224E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,CO2] 1.250E+02 2.455E-03 3.069E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,MEACOO_-] 1.000E+01 2.796E-02 2.796E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,HCO3_-] 1.000E+02 1.345E-03 1.345E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,MEA_+] 1.000E+01 2.931E-02 2.931E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,H2O] 1.000E+00 8.722E-01 8.722E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,MEA] 1.000E+01 6.916E-02 6.916E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,CO2] 1.000E+04 3.410E-05 3.410E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].apparent_inherent_reaction_extent[bicarbonate] 1.250E+02 9.684E-02 1.210E+01\n", + "fs.unit.liquid_phase.properties_out[0.0].apparent_inherent_reaction_extent[carbamate] 1.250E+02 2.013E+00 2.516E+02\n", + "fs.unit.liquid_phase.properties_out[0.0].log_k_eq[bicarbonate] None -7.648E+00 -7.648E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].log_k_eq[carbamate] None -2.079E+00 -2.079E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-] 1.000E+00 7.024E+00 7.024E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-] 1.000E+00 3.989E+00 3.989E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+] 1.000E+00 7.071E+00 7.071E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,H2O] 1.000E+00 1.046E+01 1.046E+01\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA] 1.000E+00 7.929E+00 7.929E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2] 1.000E+00 3.147E-01 3.147E-01\n", + "fs.unit.vapor_phase[0.0].flow_mol_phase[Vap] 1.000E-01 9.785E+00 9.785E-01\n", + "fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2] 1.000E+01 6.361E-02 6.361E-01\n", + "fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O] 1.000E+01 9.364E-01 9.364E+00\n", + "fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,N2] 1.000E+01 1.022E-09 1.022E-08\n", + "fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,O2] 1.000E+01 1.022E-09 1.022E-08\n", + "fs.unit.vapor_phase[0.0].phase_frac[Vap] 1.000E+00 1.000E+00 1.000E+00\n", + "\n", + "Constraint Scaling Factor\n", + "fs.unit.unit_material_balance[0.0,CO2] 1.250E-01\n", + "fs.unit.unit_material_balance[0.0,H2O] 1.250E-02\n", + "fs.unit.unit_material_balance[0.0,N2] 1.000E+00\n", + "fs.unit.unit_material_balance[0.0,O2] 1.000E+00\n", + "fs.unit.unit_material_balance[0.0,MEA] 1.250E-01\n", + "fs.unit.unit_phase_equilibrium[0.0,CO2] 1.000E-04\n", + "fs.unit.unit_phase_equilibrium[0.0,H2O] 1.000E-04\n", + "fs.unit.unit_temperature_equality[0.0] 3.333E-03\n", + "fs.unit.unit_enthalpy_balance[0.0] 5.463E-06\n", + "fs.unit.unit_pressure_balance[0.0] 1.000E-05\n", + "fs.unit.liquid_phase.material_balances[0.0,H2O] 1.250E-02\n", + "fs.unit.liquid_phase.material_balances[0.0,MEA] 1.250E-01\n", + "fs.unit.liquid_phase.material_balances[0.0,CO2] 1.250E-01\n", + "fs.unit.liquid_phase.enthalpy_balances[0.0] 8.763E-07\n", + "fs.unit.liquid_phase.pressure_balance[0.0] 1.000E-05\n", + "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEACOO_-] 1.250E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,HCO3_-] 1.250E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEA_+] 1.250E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,H2O] 1.250E-02\n", + "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEA] 1.250E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2] 1.250E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEACOO_-] 1.250E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,HCO3_-] 1.250E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEA_+] 1.250E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,H2O] 1.250E-02\n", + "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEA] 1.250E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,CO2] 1.250E+02\n", + "fs.unit.liquid_phase.properties_in[0.0].total_flow_balance 1.250E-02\n", + "fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[H2O] 1.000E+01\n", + "fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[MEA] 1.000E+01\n", + "fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2] 1.000E+01\n", + "fs.unit.liquid_phase.properties_in[0.0].phase_fraction_constraint[Liq] 1.000E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].log_k_eq_constraint[bicarbonate] None\n", + "fs.unit.liquid_phase.properties_in[0.0].log_k_eq_constraint[carbamate] None\n", + "fs.unit.liquid_phase.properties_in[0.0].inherent_equilibrium_constraint[bicarbonate] 1.000E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].inherent_equilibrium_constraint[carbamate] 1.000E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-] 2.377E-04\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-] 2.377E-03\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA_+] 2.377E-04\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,H2O] 2.377E-05\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA] 2.377E-04\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2] 2.377E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEACOO_-] 1.250E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,HCO3_-] 1.250E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA_+] 1.250E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,H2O] 1.250E-02\n", + "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA] 1.250E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2] 1.250E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEACOO_-] 1.250E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,HCO3_-] 1.250E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEA_+] 1.250E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,H2O] 1.250E-02\n", + "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEA] 1.250E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,CO2] 1.250E+02\n", + "fs.unit.liquid_phase.properties_out[0.0].sum_mole_frac_out 1.000E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].total_flow_balance 1.250E-02\n", + "fs.unit.liquid_phase.properties_out[0.0].component_flow_balances[H2O] 1.000E+01\n", + "fs.unit.liquid_phase.properties_out[0.0].component_flow_balances[MEA] 1.000E+01\n", + "fs.unit.liquid_phase.properties_out[0.0].component_flow_balances[CO2] 1.000E+01\n", + "fs.unit.liquid_phase.properties_out[0.0].phase_fraction_constraint[Liq] 1.000E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].log_k_eq_constraint[bicarbonate] None\n", + "fs.unit.liquid_phase.properties_out[0.0].log_k_eq_constraint[carbamate] None\n", + "fs.unit.liquid_phase.properties_out[0.0].inherent_equilibrium_constraint[bicarbonate] 1.000E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].inherent_equilibrium_constraint[carbamate] 1.000E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-] 2.377E-04\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-] 2.377E-03\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA_+] 2.377E-04\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,H2O] 2.377E-05\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA] 2.377E-04\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2] 2.377E-01\n", + "fs.unit.vapor_phase[0.0].sum_mole_frac_out 1.000E+00\n", + "fs.unit.vapor_phase[0.0].total_flow_balance 1.000E-01\n", + "fs.unit.vapor_phase[0.0].component_flow_balances[CO2] 1.000E+01\n", + "fs.unit.vapor_phase[0.0].component_flow_balances[H2O] 1.000E+01\n", + "fs.unit.vapor_phase[0.0].component_flow_balances[N2] 1.000E+01\n", + "fs.unit.vapor_phase[0.0].component_flow_balances[O2] 1.000E+01\n", + "fs.unit.vapor_phase[0.0].phase_fraction_constraint[Vap] 1.000E+00\n", + "\n", + "Expression Scaling Hint\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp[Liq,H2O] 1.250E-02\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp[Liq,MEA] 1.250E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp[Liq,CO2] 1.250E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].k_eq[bicarbonate] None\n", + "fs.unit.liquid_phase.properties_in[0.0].k_eq[carbamate] None\n", + "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,MEACOO_-] None\n", + "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,HCO3_-] None\n", + "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,MEA_+] None\n", + "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,H2O] None\n", + "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,MEA] None\n", + "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,CO2] None\n", + "fs.unit.liquid_phase.properties_in[0.0].dens_mol_phase[Liq] 2.377E-05\n", + "fs.unit.liquid_phase.properties_in[0.0].vol_mol_phase[Liq] 4.206E+04\n", + "fs.unit.liquid_phase.properties_in[0.0]._enthalpy_flow_term[Liq] None\n", + "fs.unit.liquid_phase.properties_in[0.0].enth_mol_phase[Liq] 7.010E-05\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_comp[H2O] 1.250E-02\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_comp[MEA] 1.250E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_comp[CO2] 1.250E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp[Liq,H2O] 1.250E-02\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp[Liq,MEA] 1.250E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp[Liq,CO2] 1.250E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].k_eq[bicarbonate] None\n", + "fs.unit.liquid_phase.properties_out[0.0].k_eq[carbamate] None\n", + "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,MEACOO_-] None\n", + "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,HCO3_-] None\n", + "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,MEA_+] None\n", + "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,H2O] None\n", + "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,MEA] None\n", + "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,CO2] None\n", + "fs.unit.liquid_phase.properties_out[0.0].dens_mol_phase[Liq] 2.377E-05\n", + "fs.unit.liquid_phase.properties_out[0.0].vol_mol_phase[Liq] 4.206E+04\n", + "fs.unit.liquid_phase.properties_out[0.0]._enthalpy_flow_term[Liq] None\n", + "fs.unit.liquid_phase.properties_out[0.0].enth_mol_phase[Liq] 7.010E-05\n", + "fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[Liq,H2O] None\n", + "fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[Liq,MEA] None\n", + "fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[Liq,CO2] None\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_comp[H2O] 1.250E-02\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_comp[MEA] 1.250E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_comp[CO2] 1.250E-01\n", + "fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,CO2] 1.000E+00\n", + "fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,H2O] 1.000E+00\n", + "fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,N2] 1.000E+00\n", + "fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,O2] 1.000E+00\n", + "fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,CO2] None\n", + "fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,H2O] None\n", + "fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,N2] None\n", + "fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,O2] None\n", + "fs.unit.vapor_phase[0.0]._enthalpy_flow_term[Vap] None\n", + "fs.unit.vapor_phase[0.0].enth_mol_phase[Vap] 5.463E-05\n", + "fs.unit.vapor_phase[0.0].enth_mol_phase_comp[Vap,CO2] 3.787E-05\n", + "fs.unit.vapor_phase[0.0].enth_mol_phase_comp[Vap,H2O] 9.249E-05\n", + "fs.unit.vapor_phase[0.0].enth_mol_phase_comp[Vap,N2] 5.950E-05\n", + "fs.unit.vapor_phase[0.0].enth_mol_phase_comp[Vap,O2] 5.208E-05\n", + "fs.unit.vapor_phase[0.0].flow_mol_comp[CO2] 1.000E+00\n", + "fs.unit.vapor_phase[0.0].flow_mol_comp[H2O] 1.000E+00\n", + "fs.unit.vapor_phase[0.0].flow_mol_comp[N2] 1.000E+00\n", + "fs.unit.vapor_phase[0.0].flow_mol_comp[O2] 1.000E+00\n" + ] + } + ], + "source": [ + "from idaes.core.scaling.util import report_scaling_factors\n", + "\n", + "report_scaling_factors(m.fs.unit, descend_into=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Most variable values have scaled values within a couple orders of magnitude of one, which is what we like. The outliers are inherent reaction extents, which we already know are a bit problematic, and variables corresponding to the components $\\text{N}_2$ and $\\text{O}_2$, which are present in the vapor property package but not the vapor stream.\n", + "\n", + "We have reduced the condition number to $3 \\cdot 10^5$, which is not quite as low as we would have liked, but is a vast improvement over the value $3 \\cdot 10^{13}$, which we started out with. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# References\n", + "\n", + "[[1](https://doi.org/10.1016/j.compchemeng.2025.109312)] Allan, D. A., Ostace, A. G., & Polley, T. (2025). Jacobian-based model diagnostics and application to equation oriented modeling of a carbon capture system. Computers & Chemical Engineering, 109312.\n", + "\n", + "[[2](https://link.springer.com/article/10.1007/S10107-004-0559-Y)] W\u00e4chter, A., & Biegler, L. T. (2006). On the implementation of an interior-point filter line-search algorithm for large-scale nonlinear programming. Mathematical programming, 106(1), 25-57." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.12" + } + }, + "nbformat": 4, + "nbformat_minor": 3 +} \ No newline at end of file diff --git a/idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques_usr.ipynb b/idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques_usr.ipynb new file mode 100644 index 00000000..693c14b1 --- /dev/null +++ b/idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques_usr.ipynb @@ -0,0 +1,3110 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "###############################################################################\n", + "# The Institute for the Design of Advanced Energy Systems Integrated Platform\n", + "# Framework (IDAES IP) was produced under the DOE Institute for the\n", + "# Design of Advanced Energy Systems (IDAES).\n", + "#\n", + "# Copyright (c) 2018-2026 by the software owners: The Regents of the\n", + "# University of California, through Lawrence Berkeley National Laboratory,\n", + "# National Technology & Engineering Solutions of Sandia, LLC, Carnegie Mellon\n", + "# University, West Virginia University Research Corporation, et al.\n", + "# All rights reserved. Please see the files COPYRIGHT.md and LICENSE.md\n", + "# for full copyright and license information.\n", + "###############################################################################" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Advanced Scaling Techniques\n", + "\n", + "Author: Doug Allan\\\n", + "Maintainer: Doug Allan\\\n", + "Updated: 2026-04-30\n", + "\n", + "## Introduction\n", + "\n", + "This notebook is intended to give the user further insight into how the scaling toolbox can be used to improve robustness. A large portion of the material is an adaptation of [Allan, Ostace, and Polly (2025)](#references). By the end of this study, the user should understand:\n", + "* How a default scaler object can be specified for a property package\n", + "* How to set default scaling factors for property package variables\n", + "* The strengths and weaknesses of the ``NominalValueExpressionWalker`` used in ``CustomScalerBase.get_sum_terms_nominal_values`` and ``CustomScalerBase.get_expression_nominal_value`` for use in constraint scaling\n", + "* How to use the ``SVDToolbox`` to troubleshoot scaling issues\n", + "\n", + "## Step 1: Set Up Test Case\n", + "We will use the `SolventReboiler` unit model as a case study. It is a component in a stripping column used for solvent regeneration. It is modeled as a single equilibrium stage with an external heat duty. The inlet stream is entirely liquid, while it has both boilup and bottoms outlet streams. The liquid and vapor phases use different configurations of the modular property framework.\n", + "\n", + "First, we set up and attempt to initialize the unit model." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2026-04-29 17:11:54 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Starting initialization routine\n", + "2026-04-29 17:11:54 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Bubble, dew, and critical point initialization completed.\n", + "2026-04-29 17:11:54 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Equilibrium temperature initialization completed.\n", + "2026-04-29 17:11:54 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: State variable initialization completed.\n", + "2026-04-29 17:11:54 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Phase equilibrium initialization completed.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Ipopt 3.13.2: linear_solver=\"ma57\"\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: max_iter=200\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: nlp_scaling_method=\"gradient-based\"\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: tol=1e-06\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: ******************************************************************************\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: For more information visit http://projects.coin-or.org/Ipopt\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: This version of Ipopt was compiled from source code available at\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: for large-scale scientific computation. All technical papers, sales and\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: publicity material resulting from use of the HSL codes within IPOPT must\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: contain the following acknowledgement:\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: HSL, a collection of Fortran codes for large-scale scientific\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: computation. See http://www.hsl.rl.ac.uk.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: ******************************************************************************\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of nonzeros in equality constraint Jacobian...: 74\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of nonzeros in inequality constraint Jacobian.: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of nonzeros in Lagrangian Hessian.............: 42\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Total number of variables............................: 18\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: variables with only lower bounds: 6\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: variables with lower and upper bounds: 12\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: variables with only upper bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Total number of equality constraints.................: 18\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Total number of inequality constraints...............: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: inequality constraints with only lower bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: inequality constraints with lower and upper bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: inequality constraints with only upper bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 0 0.0000000e+00 4.13e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Reallocating memory for MA57: lfact (1377)\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 1 0.0000000e+00 4.05e+02 1.89e+12 -1.0 6.07e+01 - 1.92e-01 1.98e-02H 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 2 0.0000000e+00 1.62e+04 1.56e+17 -1.0 8.76e+01 - 1.69e-01 5.07e-01H 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 3 0.0000000e+00 1.62e+04 1.55e+17 -1.0 4.59e+01 - 1.21e-07 3.23e-03H 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 4 0.0000000e+00 2.15e+04 1.93e+17 -1.0 4.88e+01 - 1.06e-02 9.12e-01h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Reallocating memory for MA57: lfact (1542)\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 5 0.0000000e+00 2.15e+04 1.93e+17 -1.0 3.05e+02 - 4.08e-04 6.58e-04h 2\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Reallocating memory for MA57: lfact (1662)\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 6 0.0000000e+00 2.09e+04 1.87e+17 -1.0 1.11e+01 - 4.04e-03 3.08e-02h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 7 0.0000000e+00 1.50e+04 1.37e+17 -1.0 1.37e+01 - 1.44e-04 3.14e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 8 0.0000000e+00 1.49e+04 1.36e+17 -1.0 4.21e+00 - 5.37e-01 9.11e-03h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 9 0.0000000e+00 1.49e+04 1.36e+17 -1.0 4.10e+00 - 9.86e-01 9.35e-05h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 10r 0.0000000e+00 1.49e+04 1.00e+03 1.6 0.00e+00 - 0.00e+00 4.68e-07R 2\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 11r 0.0000000e+00 5.25e+03 2.22e+03 1.6 3.13e+04 - 3.88e-03 1.14e-03f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 12r 0.0000000e+00 5.08e+03 4.24e+04 1.6 1.22e+03 - 1.88e-01 5.18e-03f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 13r 0.0000000e+00 4.77e+03 3.36e+04 1.6 6.27e+01 - 3.06e-02 6.76e-02f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 14r 0.0000000e+00 4.33e+03 1.32e+05 1.6 8.06e+00 - 5.05e-01 9.81e-02f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 15r 0.0000000e+00 4.19e+03 1.12e+05 1.6 9.20e+00 - 3.38e-01 3.25e-02f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 16r 0.0000000e+00 1.89e+03 5.50e+04 1.6 2.54e+00 - 8.42e-02 7.08e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 17r 0.0000000e+00 1.72e+03 4.73e+04 1.6 7.82e+00 - 2.36e-01 1.01e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 18r 0.0000000e+00 1.14e+03 2.84e+04 1.6 1.92e+00 - 7.10e-01 4.02e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 19r 0.0000000e+00 1.06e+03 2.92e+04 1.6 5.12e+00 - 7.85e-01 7.79e-02f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 20r 0.0000000e+00 2.69e+02 3.66e+03 1.6 5.52e-01 - 1.00e+00 9.33e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 21r 0.0000000e+00 1.64e+01 3.96e+02 0.9 1.63e-01 - 9.76e-01 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 22r 0.0000000e+00 6.87e-01 1.09e+02 0.2 3.52e-02 - 1.00e+00 9.59e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 23r 0.0000000e+00 2.05e-01 8.47e+03 -0.5 2.72e-03 - 1.00e+00 6.98e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 24r 0.0000000e+00 1.34e-03 2.18e-01 -0.5 1.87e-03 - 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 25r 0.0000000e+00 1.29e-02 1.88e+02 -2.9 3.36e-04 - 1.00e+00 9.47e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 26r 0.0000000e+00 2.90e-06 4.04e-05 -2.9 7.48e-05 - 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of Iterations....: 26\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: (scaled) (unscaled)\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Constraint violation....: 2.1131334015933589e-08 2.8957967970200116e-06\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Overall NLP error.......: 2.1131334015933589e-08 2.8957967970200116e-06\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of objective function evaluations = 34\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of objective gradient evaluations = 12\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of equality constraint evaluations = 36\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of inequality constraint evaluations = 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of equality constraint Jacobian evaluations = 28\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of inequality constraint Jacobian evaluations = 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of Lagrangian Hessian evaluations = 26\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Total CPU secs in IPOPT (w/o function evaluations) = 0.006\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Total CPU secs in NLP function evaluations = 0.000\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: EXIT: Optimal Solution Found.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Property initialization routine finished.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Starting initialization routine\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Bubble, dew, and critical point initialization completed.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Equilibrium temperature initialization completed.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: State variable initialization completed.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Phase equilibrium initialization completed.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Ipopt 3.13.2: linear_solver=\"ma57\"\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: max_iter=200\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: nlp_scaling_method=\"gradient-based\"\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: tol=1e-06\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: ******************************************************************************\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: For more information visit http://projects.coin-or.org/Ipopt\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: This version of Ipopt was compiled from source code available at\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: for large-scale scientific computation. All technical papers, sales and\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: publicity material resulting from use of the HSL codes within IPOPT must\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: contain the following acknowledgement:\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: HSL, a collection of Fortran codes for large-scale scientific\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: computation. See http://www.hsl.rl.ac.uk.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: ******************************************************************************\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of nonzeros in equality constraint Jacobian...: 74\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of nonzeros in inequality constraint Jacobian.: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of nonzeros in Lagrangian Hessian.............: 42\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Total number of variables............................: 18\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: variables with only lower bounds: 6\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: variables with lower and upper bounds: 12\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: variables with only upper bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Total number of equality constraints.................: 18\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Total number of inequality constraints...............: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: inequality constraints with only lower bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: inequality constraints with lower and upper bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: inequality constraints with only upper bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 0 0.0000000e+00 4.13e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Reallocating memory for MA57: lfact (1377)\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 1 0.0000000e+00 4.05e+02 1.89e+12 -1.0 6.07e+01 - 1.92e-01 1.98e-02H 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 2 0.0000000e+00 1.62e+04 1.56e+17 -1.0 8.76e+01 - 1.69e-01 5.07e-01H 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 3 0.0000000e+00 1.62e+04 1.55e+17 -1.0 4.59e+01 - 1.21e-07 3.23e-03H 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 4 0.0000000e+00 2.15e+04 1.93e+17 -1.0 4.88e+01 - 1.06e-02 9.12e-01h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Reallocating memory for MA57: lfact (1542)\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 5 0.0000000e+00 2.15e+04 1.93e+17 -1.0 3.05e+02 - 4.08e-04 6.58e-04h 2\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Reallocating memory for MA57: lfact (1662)\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 6 0.0000000e+00 2.09e+04 1.87e+17 -1.0 1.11e+01 - 4.04e-03 3.08e-02h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 7 0.0000000e+00 1.50e+04 1.37e+17 -1.0 1.37e+01 - 1.44e-04 3.14e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 8 0.0000000e+00 1.49e+04 1.36e+17 -1.0 4.21e+00 - 5.37e-01 9.11e-03h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 9 0.0000000e+00 1.49e+04 1.36e+17 -1.0 4.10e+00 - 9.86e-01 9.35e-05h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 10r 0.0000000e+00 1.49e+04 1.00e+03 1.6 0.00e+00 - 0.00e+00 4.68e-07R 2\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 11r 0.0000000e+00 5.25e+03 2.22e+03 1.6 3.13e+04 - 3.88e-03 1.14e-03f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 12r 0.0000000e+00 5.08e+03 4.24e+04 1.6 1.22e+03 - 1.88e-01 5.18e-03f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 13r 0.0000000e+00 4.77e+03 3.36e+04 1.6 6.27e+01 - 3.06e-02 6.76e-02f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 14r 0.0000000e+00 4.33e+03 1.32e+05 1.6 8.06e+00 - 5.05e-01 9.81e-02f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 15r 0.0000000e+00 4.19e+03 1.12e+05 1.6 9.20e+00 - 3.38e-01 3.25e-02f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 16r 0.0000000e+00 1.89e+03 5.50e+04 1.6 2.54e+00 - 8.42e-02 7.08e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 17r 0.0000000e+00 1.72e+03 4.73e+04 1.6 7.82e+00 - 2.36e-01 1.01e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 18r 0.0000000e+00 1.14e+03 2.84e+04 1.6 1.92e+00 - 7.10e-01 4.02e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 19r 0.0000000e+00 1.06e+03 2.92e+04 1.6 5.12e+00 - 7.85e-01 7.79e-02f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 20r 0.0000000e+00 2.69e+02 3.66e+03 1.6 5.52e-01 - 1.00e+00 9.33e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 21r 0.0000000e+00 1.64e+01 3.96e+02 0.9 1.63e-01 - 9.76e-01 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 22r 0.0000000e+00 6.87e-01 1.09e+02 0.2 3.52e-02 - 1.00e+00 9.59e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 23r 0.0000000e+00 2.05e-01 8.47e+03 -0.5 2.72e-03 - 1.00e+00 6.98e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 24r 0.0000000e+00 1.34e-03 2.18e-01 -0.5 1.87e-03 - 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 25r 0.0000000e+00 1.29e-02 1.88e+02 -2.9 3.36e-04 - 1.00e+00 9.47e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 26r 0.0000000e+00 2.90e-06 4.04e-05 -2.9 7.48e-05 - 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of Iterations....: 26\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: (scaled) (unscaled)\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Constraint violation....: 2.1131334015933589e-08 2.8957967970200116e-06\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Overall NLP error.......: 2.1131334015933589e-08 2.8957967970200116e-06\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of objective function evaluations = 34\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of objective gradient evaluations = 12\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of equality constraint evaluations = 36\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of inequality constraint evaluations = 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of equality constraint Jacobian evaluations = 28\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of inequality constraint Jacobian evaluations = 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of Lagrangian Hessian evaluations = 26\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Total CPU secs in IPOPT (w/o function evaluations) = 0.008\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Total CPU secs in NLP function evaluations = 0.000\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: EXIT: Optimal Solution Found.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Property initialization routine finished.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase: Control volume properties initialization complete\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase: Control volume reactions initialization complete\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit: Initialization Step 1 Complete.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: Starting initialization routine\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: Bubble, dew, and critical point initialization completed.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: Equilibrium temperature initialization completed.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: State variable initialization completed.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: Phase equilibrium initialization completed.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: Property initialization routine finished.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit: Initialization Step 2 Complete.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Ipopt 3.13.2: linear_solver=\"ma57\"\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: max_iter=200\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: nlp_scaling_method=\"gradient-based\"\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: tol=1e-06\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: ******************************************************************************\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: For more information visit http://projects.coin-or.org/Ipopt\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: This version of Ipopt was compiled from source code available at\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: for large-scale scientific computation. All technical papers, sales and\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: publicity material resulting from use of the HSL codes within IPOPT must\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: contain the following acknowledgement:\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: HSL, a collection of Fortran codes for large-scale scientific\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: computation. See http://www.hsl.rl.ac.uk.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: ******************************************************************************\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of nonzeros in equality constraint Jacobian...: 231\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of nonzeros in inequality constraint Jacobian.: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of nonzeros in Lagrangian Hessian.............: 149\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Total number of variables............................: 51\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: variables with only lower bounds: 12\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: variables with lower and upper bounds: 34\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: variables with only upper bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Total number of equality constraints.................: 51\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Total number of inequality constraints...............: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: inequality constraints with only lower bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: inequality constraints with lower and upper bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: inequality constraints with only upper bounds: 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 0 0.0000000e+00 3.62e+06 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Reallocating memory for MA57: lfact (3323)\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 1 0.0000000e+00 3.00e+06 1.18e+02 -1.0 3.71e+04 - 5.00e-01 1.73e-01h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 2 0.0000000e+00 2.99e+06 3.06e+03 -1.0 2.81e+04 - 8.76e-01 3.30e-03h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 3 0.0000000e+00 2.99e+06 8.95e+07 -1.0 2.80e+04 - 9.79e-01 3.34e-05h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 4r 0.0000000e+00 2.99e+06 1.00e+03 1.9 0.00e+00 - 0.00e+00 1.74e-07R 2\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 5r 0.0000000e+00 2.93e+06 9.98e+02 1.9 3.19e+04 - 2.43e-03 2.43e-03f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 6r 0.0000000e+00 2.86e+06 1.02e+03 1.2 3.69e+02 - 3.26e-01 2.09e-03f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 7r 0.0000000e+00 2.23e+06 1.04e+03 1.2 2.85e+02 - 1.93e-01 8.65e-02f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 8r 0.0000000e+00 1.90e+06 1.12e+05 1.2 2.94e+02 - 7.31e-02 2.42e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 9r 0.0000000e+00 1.44e+06 7.08e+04 1.2 1.51e+02 - 7.79e-01 2.13e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 10r 0.0000000e+00 1.21e+06 3.79e+04 1.2 1.60e+00 2.0 4.46e-01 1.46e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 11r 0.0000000e+00 7.63e+04 1.14e+04 1.2 9.97e+01 - 3.46e-01 9.00e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 12r 0.0000000e+00 4.57e+04 2.79e+04 1.2 8.49e+01 - 1.00e+00 2.61e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 13r 0.0000000e+00 5.79e+04 9.55e+03 1.2 3.35e+01 - 1.00e+00 7.44e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 14r 0.0000000e+00 1.21e+05 1.45e+04 1.2 2.11e+01 - 1.00e+00 1.00e+00h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 15r 0.0000000e+00 2.24e+05 6.34e+02 1.2 7.86e+00 - 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 16r 0.0000000e+00 2.19e+05 4.22e+03 0.5 1.77e+00 - 1.00e+00 9.43e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 17r 0.0000000e+00 3.93e+05 6.53e+02 0.5 1.02e+02 - 5.02e-01 4.46e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 18r 0.0000000e+00 4.24e+05 4.17e+03 0.5 1.55e+01 - 1.00e+00 2.17e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 19r 0.0000000e+00 4.87e+05 1.47e+01 0.5 7.37e+00 - 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 20r 0.0000000e+00 5.23e+05 2.31e+03 -0.9 1.53e+00 - 9.40e-01 7.50e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 21r 0.0000000e+00 5.39e+05 7.30e+03 -0.9 2.08e+02 - 8.07e-01 3.86e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 22r 0.0000000e+00 5.39e+05 5.05e+03 -0.9 1.37e+02 - 1.00e+00 4.43e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 23r 0.0000000e+00 5.38e+05 7.93e+00 -0.9 7.27e+01 - 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 24r 0.0000000e+00 5.39e+05 1.75e-03 -0.9 2.41e-01 - 1.00e+00 1.00e+00h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 25r 0.0000000e+00 5.44e+05 2.59e+01 -3.6 3.79e+00 - 9.90e-01 9.73e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 26r 0.0000000e+00 4.44e+05 3.73e+02 -3.6 6.08e+03 - 7.62e-02 6.44e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 27r 0.0000000e+00 3.34e+05 7.09e+02 -3.6 2.85e+03 - 5.42e-02 9.37e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 28r 0.0000000e+00 2.87e+03 9.51e+02 -3.6 1.42e+03 - 1.73e-01 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 29r 0.0000000e+00 8.65e+04 2.35e+02 -3.6 1.10e+03 - 1.00e+00 1.00e+00H 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 30r 0.0000000e+00 8.28e+04 4.88e-01 -3.6 1.19e+02 - 1.00e+00 1.00e+00h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 31r 0.0000000e+00 8.28e+04 9.25e-05 -3.6 2.69e-01 - 1.00e+00 1.00e+00h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 32r 0.0000000e+00 8.28e+04 2.10e+00 -5.4 5.64e-02 - 1.00e+00 9.70e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 33r 0.0000000e+00 8.28e+04 2.49e+02 -5.4 1.00e-03 1.5 8.85e-01 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 34r 0.0000000e+00 8.27e+04 3.33e-02 -5.4 3.00e-03 1.0 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 35r 0.0000000e+00 8.27e+04 3.31e-02 -5.4 8.93e-03 0.6 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 36r 0.0000000e+00 8.26e+04 3.24e-02 -5.4 2.63e-02 0.1 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 37r 0.0000000e+00 8.23e+04 3.06e-02 -5.4 7.43e-02 -0.4 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 38r 0.0000000e+00 8.16e+04 2.59e-02 -5.4 1.89e-01 -0.9 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 39r 0.0000000e+00 8.02e+04 4.92e-02 -5.4 3.67e-01 -1.3 1.00e+00 1.00e+00h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 40r 0.0000000e+00 7.85e+04 6.76e-02 -5.4 1.01e+00 -1.8 1.00e+00 1.00e+00h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 41r 0.0000000e+00 7.76e+04 2.21e-02 -5.4 3.03e+00 -2.3 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 42r 0.0000000e+00 7.73e+04 1.54e-02 -5.4 9.07e+00 -2.8 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 43r 0.0000000e+00 7.69e+04 1.54e-02 -5.4 2.72e+01 -3.2 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 44r 0.0000000e+00 7.57e+04 9.45e-02 -5.4 8.16e+01 -3.7 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 45r 0.0000000e+00 7.21e+04 7.98e-01 -5.4 2.45e+02 -4.2 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 46r 0.0000000e+00 6.17e+04 5.91e+00 -5.4 7.40e+02 -4.7 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 47r 0.0000000e+00 3.69e+04 5.13e+01 -5.4 2.31e+03 -5.2 1.00e+00 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 48r 0.0000000e+00 7.15e+04 1.47e+02 -5.4 1.10e+04 -5.6 1.00e+00 2.17e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 49r 0.0000000e+00 7.15e+04 4.98e+02 -5.4 4.07e+03 -5.2 1.00e+00 5.56e-06h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 50r 0.0000000e+00 2.07e+05 4.58e+03 -5.4 2.01e+04 -5.7 4.61e-01 1.75e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 51r 0.0000000e+00 1.19e+06 4.31e+04 -5.4 9.31e+03 -5.3 2.11e-06 1.00e+00f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 52r 0.0000000e+00 1.16e+06 3.63e+04 -5.4 1.14e+02 -0.3 4.01e-01 1.23e-01f 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 53r 0.0000000e+00 1.16e+06 3.63e+04 -5.4 2.83e+01 0.1 7.36e-01 7.74e-07h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 54r 0.0000000e+00 1.16e+06 3.63e+04 -5.4 3.94e+03 - 1.59e-01 7.41e-06h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 55r 0.0000000e+00 7.95e+05 2.50e+04 -5.4 4.00e+03 - 7.84e-01 3.17e-01h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 56r 0.0000000e+00 3.83e+05 1.19e+04 -5.4 1.69e+03 - 1.35e-05 5.23e-01h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 57r 0.0000000e+00 2.95e+05 9.19e+03 -5.4 9.94e+00 -0.4 5.56e-01 2.31e-01h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 58r 0.0000000e+00 1.29e+04 7.45e+02 -5.4 1.55e+03 - 2.88e-06 1.00e+00h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 59r 0.0000000e+00 1.05e+04 3.57e+00 -5.4 8.95e-02 -0.8 1.00e+00 1.00e+00h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 60r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 7.60e-02 -1.3 1.00e+00 1.00e+00h 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 61r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 2.28e-01 -1.8 1.00e+00 2.50e-01h 3\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 62r 0.0000000e+00 1.05e+04 1.03e-02 -5.4 6.84e-01 -2.3 1.00e+00 1.56e-02h 7\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 63r 0.0000000e+00 1.05e+04 3.12e-02 -5.4 2.05e+00 -2.8 1.00e+00 9.77e-04h 11\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 64r 0.0000000e+00 1.05e+04 9.35e-02 -5.4 6.16e+00 -3.2 1.00e+00 1.22e-04h 14\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 65r 0.0000000e+00 1.05e+04 2.81e-01 -5.4 1.85e+01 -3.7 1.00e+00 7.45e-09h 28\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 66r 0.0000000e+00 1.05e+04 8.49e-01 -5.4 5.60e+01 -4.2 1.00e+00 1.86e-09h 30\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 67r 0.0000000e+00 1.05e+04 2.61e+00 -5.4 1.72e+02 -4.7 1.00e+00 1.16e-10h 34\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 68r 0.0000000e+00 1.05e+04 8.40e+00 -5.4 5.54e+02 -5.1 1.00e+00 3.64e-12h 39\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 69r 0.0000000e+00 1.05e+04 8.40e+00 -5.4 2.14e+03 -5.6 0.00e+00 3.59e-18R 58\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 70r 0.0000000e+00 1.05e+04 1.94e+01 -5.4 4.50e+04 -6.1 1.63e-02 1.43e-12f 35\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 71r 0.0000000e+00 1.05e+04 3.85e+01 -5.4 2.54e+03 -5.7 1.00e+00 1.27e-11f 36\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 72r 0.0000000e+00 1.05e+04 1.11e+01 -5.4 7.22e+02 -5.2 9.93e-01 2.91e-11f 36\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 73r 0.0000000e+00 1.05e+04 3.70e+01 -5.4 3.05e+03 -5.7 7.35e-01 1.32e-12f 39\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 74r 0.0000000e+00 1.05e+04 1.25e+01 -5.4 8.27e+02 -5.3 1.00e+00 3.64e-12f 39\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 75r 0.0000000e+00 1.05e+04 3.60e+01 -5.4 3.72e+03 -5.8 5.36e-01 1.35e-13f 42\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 76r 0.0000000e+00 1.05e+04 1.44e+01 -5.4 9.51e+02 -5.3 1.00e+00 1.14e-13f 44\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 77r 0.0000000e+00 1.05e+04 2.35e+01 -5.4 4.61e+03 -5.8 1.64e-01 1.36e-14f 45\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 78r 0.0000000e+00 1.05e+04 1.66e+01 -5.4 1.10e+03 -5.4 1.00e+00 3.55e-15f 49\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 79r 0.0000000e+00 1.05e+04 2.55e+01 -5.4 5.86e+03 -5.9 1.22e-01 3.35e-16f 50\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 80r 0.0000000e+00 2.67e+04 5.84e+01 -5.4 1.27e+03 -5.4 1.00e+00 8.72e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 81r 0.0000000e+00 2.67e+04 2.19e+03 -5.4 1.28e+03 - 4.11e-03 2.62e-05w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 82r 0.0000000e+00 4.42e+04 8.23e+02 -5.4 3.84e+03 -5.9 5.02e-01 4.78e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 83r 0.0000000e+00 1.05e+04 1.92e+01 -5.4 1.21e+04 - 1.00e+00 7.74e-16f 50\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 84r 0.0000000e+00 1.05e+04 2.07e+01 -5.4 1.47e+03 -5.5 4.87e-01 3.33e-16h 52\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 85r 0.0000000e+00 1.05e+04 5.09e+01 -5.4 1.08e+04 -6.0 2.11e-01 1.14e-17f 54\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 86r 0.0000000e+00 1.05e+04 6.78e+01 -5.4 1.72e+03 -5.5 1.00e+00 1.78e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 87r 0.0000000e+00 1.05e+04 1.11e+02 -5.4 1.65e+04 -6.0 4.54e-02 1.86e-18f 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 88r 0.0000000e+00 1.05e+04 2.03e+02 -5.4 2.02e+03 -5.6 1.00e+00 1.52e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 89r 0.0000000e+00 1.05e+04 3.30e+02 -5.4 3.06e+04 -6.1 2.34e-02 1.00e-18f 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 90r 0.0000000e+00 1.05e+04 7.12e+02 -5.4 2.38e+03 -5.7 1.00e+00 1.29e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 91r 0.0000000e+00 1.05e+04 7.29e+02 -5.4 9.01e+04 -6.1 3.00e-04 3.41e-19f 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 92r 0.0000000e+00 1.05e+04 3.99e+01 -5.4 2.95e+03 -5.7 3.70e-01 2.84e-18h 59\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 93r 0.0000000e+00 2.20e+04 3.07e+01 -5.4 7.91e+02 -5.3 1.00e+00 1.00e+00w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 94r 0.0000000e+00 3.01e+04 4.20e+01 -5.4 2.61e+03 -5.8 7.22e-01 2.55e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 95r 0.0000000e+00 3.01e+04 1.37e+03 -5.4 1.07e+03 - 1.99e-03 3.17e-05w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 96r 0.0000000e+00 1.05e+04 1.20e+01 -5.4 7.00e+03 -6.2 1.00e+00 1.78e-15h 49\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 97r 0.0000000e+00 1.05e+04 2.31e+01 -5.4 4.29e+03 -5.8 2.10e-01 6.00e-11f 33\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 98r 0.0000000e+00 1.05e+04 1.59e+01 -5.4 1.05e+03 -5.4 1.00e+00 7.28e-12f 38\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 99r 0.0000000e+00 1.05e+04 2.46e+01 -5.4 5.40e+03 -5.9 1.33e-01 4.76e-11f 33\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 100r 0.0000000e+00 1.05e+04 1.83e+01 -5.4 1.21e+03 -5.4 1.00e+00 1.07e-10f 34\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 101r 0.0000000e+00 1.05e+04 2.73e+01 -5.4 7.03e+03 -5.9 1.02e-01 3.66e-11f 33\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 102r 0.0000000e+00 1.05e+04 2.77e+01 -5.4 1.40e+03 -5.5 1.00e+00 1.43e-12f 40\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 103r 0.0000000e+00 1.05e+04 4.37e+01 -5.4 9.60e+03 -6.0 7.47e-02 5.24e-14f 42\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 104r 0.0000000e+00 1.05e+04 6.49e+01 -5.4 1.63e+03 -5.5 1.00e+00 7.69e-14f 44\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 105r 0.0000000e+00 1.05e+04 1.04e+02 -5.4 1.42e+04 -6.0 5.06e-02 1.11e-15f 47\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 106r 0.0000000e+00 2.67e+04 1.58e+01 -5.4 1.91e+03 -5.6 1.00e+00 5.77e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 107r 0.0000000e+00 2.67e+04 1.40e+03 -5.4 9.67e+02 - 2.90e-03 3.66e-04w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 108r 0.0000000e+00 4.39e+04 4.78e+02 -5.4 5.57e+03 -6.1 3.84e-01 3.25e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 109r 0.0000000e+00 1.05e+04 1.80e+02 -5.4 6.38e+03 - 1.00e+00 4.10e-15f 47\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 110r 0.0000000e+00 1.05e+04 2.40e+02 -5.4 2.26e+03 -5.6 3.17e-01 3.47e-15f 48\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 111r 0.0000000e+00 1.05e+04 5.44e+02 -5.4 6.90e+04 -6.1 2.06e-02 1.14e-16f 48\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 112r 0.0000000e+00 1.05e+04 4.95e+01 -5.4 2.79e+03 -5.7 2.55e-01 7.69e-16f 51\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 113r 0.0000000e+00 1.05e+04 1.15e+01 -5.4 7.57e+02 -5.3 1.00e+00 7.11e-15f 48\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 114r 0.0000000e+00 1.05e+04 2.06e+01 -5.4 3.26e+03 -5.7 2.41e-01 6.02e-16f 50\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 115r 0.0000000e+00 1.05e+04 1.32e+01 -5.4 8.68e+02 -5.3 1.00e+00 2.22e-16h 53\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 116r 0.0000000e+00 1.05e+04 2.17e+01 -5.4 3.99e+03 -5.8 1.79e-01 3.07e-17h 54\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 117r 0.0000000e+00 1.05e+04 1.51e+01 -5.4 9.98e+02 -5.4 1.00e+00 2.78e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 118r 0.0000000e+00 1.05e+04 2.38e+01 -5.4 4.99e+03 -5.8 1.44e-01 6.14e-18h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 119r 0.0000000e+00 2.67e+04 5.98e+01 -5.4 1.15e+03 -5.4 1.00e+00 9.60e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 120r 0.0000000e+00 2.67e+04 2.31e+03 -5.4 1.66e+03 - 4.25e-03 1.30e-05w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 121r 0.0000000e+00 4.43e+04 8.41e+02 -5.4 3.52e+03 -5.9 5.33e-01 5.24e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 122r 0.0000000e+00 1.05e+04 1.75e+01 -5.4 1.31e+04 - 1.00e+00 2.66e-17h 55\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 123r 0.0000000e+00 1.05e+04 1.89e+01 -5.4 1.33e+03 -5.5 5.38e-01 2.30e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 124r 0.0000000e+00 1.05e+04 4.92e+01 -5.4 8.61e+03 -5.9 2.71e-01 3.56e-18h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 125r 0.0000000e+00 1.05e+04 2.98e+01 -5.4 1.55e+03 -5.5 1.00e+00 1.98e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 126r 0.0000000e+00 1.05e+04 4.92e+01 -5.4 1.23e+04 -6.0 6.33e-02 2.48e-18h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 127r 0.0000000e+00 1.05e+04 8.12e+01 -5.4 1.82e+03 -5.6 1.00e+00 1.69e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 128r 0.0000000e+00 1.05e+04 1.31e+02 -5.4 2.00e+04 -6.0 3.59e-02 1.53e-18f 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 129r 0.0000000e+00 1.05e+04 2.54e+02 -5.4 2.14e+03 -5.6 1.00e+00 1.43e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 130r 0.0000000e+00 1.05e+04 4.15e+02 -5.4 4.32e+04 -6.1 1.66e-02 7.10e-19f 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 131r 0.0000000e+00 1.05e+04 9.52e+02 -5.4 2.53e+03 -5.7 1.00e+00 1.21e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 132r 0.0000000e+00 2.67e+04 2.24e+01 -5.4 4.51e+05 -6.1 1.18e-04 2.45e-03w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 133r 0.0000000e+00 4.32e+04 1.53e+02 -5.4 4.75e+04 -6.6 3.50e-02 3.68e-02w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 134r 0.0000000e+00 4.32e+04 3.80e+02 -5.4 3.44e+03 - 1.99e-02 3.86e-06w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 135r 0.0000000e+00 1.05e+04 9.98e+02 -5.4 8.04e+02 - 1.18e-04 6.81e-20f 55\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 136r 0.0000000e+00 1.05e+04 2.21e+01 -5.4 8.37e+02 -5.3 6.52e-01 5.55e-17h 55\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 137r 0.0000000e+00 1.05e+04 2.91e+01 -5.4 3.73e+03 -5.8 2.04e-01 8.22e-18h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 138r 0.0000000e+00 1.05e+04 1.45e+01 -5.4 9.53e+02 -5.3 1.00e+00 5.55e-17h 55\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 139r 0.0000000e+00 1.05e+04 2.31e+01 -5.4 4.63e+03 -5.8 1.55e-01 6.62e-18h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 140r 0.0000000e+00 1.05e+04 1.67e+01 -5.4 1.10e+03 -5.4 1.00e+00 2.78e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 141r 0.0000000e+00 1.05e+04 2.55e+01 -5.4 5.89e+03 -5.9 1.22e-01 5.20e-18h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 142r 0.0000000e+00 1.05e+04 1.93e+01 -5.4 1.27e+03 -5.4 1.00e+00 2.41e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 143r 0.0000000e+00 1.05e+04 2.84e+01 -5.4 7.78e+03 -5.9 9.22e-02 3.94e-18h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 144r 0.0000000e+00 1.05e+04 3.40e+01 -5.4 1.48e+03 -5.5 1.00e+00 2.08e-17h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 145r 0.0000000e+00 2.67e+04 4.04e+01 -5.4 1.09e+04 -6.0 6.60e-02 1.02e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 146r 0.0000000e+00 2.67e+04 1.47e+03 -5.4 1.02e+03 - 2.88e-03 1.10e-04w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 147r 0.0000000e+00 4.33e+04 7.00e+02 -5.4 1.97e+04 -6.5 1.24e-01 8.93e-02w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 148r 0.0000000e+00 1.05e+04 5.40e+01 -5.4 6.24e+03 - 6.60e-02 2.82e-18h 55\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 149r 0.0000000e+00 1.05e+04 1.51e+02 -5.4 1.68e+04 -6.0 1.26e-01 1.83e-18h 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 150r 0.0000000e+00 1.05e+04 5.58e+01 -5.4 2.10e+03 -5.6 1.51e-01 9.25e-19h 60\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 151r 0.0000000e+00 1.05e+04 6.31e+01 -5.4 3.28e+04 -6.1 1.66e-02 9.36e-19f 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 152r 0.0000000e+00 1.05e+04 6.32e+01 -5.4 3.63e+03 -5.7 8.61e-03 1.56e-18h 54\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 153r 0.0000000e+00 1.05e+04 6.33e+01 -5.4 2.10e+05 -6.1 1.98e-05 1.48e-19f 56\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 154r 0.0000000e+00 1.05e+04 8.87e-01 -5.4 1.46e-02 -0.3 1.00e+00 1.43e-06h 4\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 155r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 2.09e-02 -0.8 1.00e+00 5.00e-01f 2\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 156r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 6.26e-02 -1.2 1.00e+00 2.44e-04h 13\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 157r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 1.88e-01 -1.7 1.00e+00 1.53e-05h 17\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 158r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 5.64e-01 -2.2 1.00e+00 1.00e+00w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 159r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 1.69e+00 -2.7 1.00e+00 1.00e+00w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 160r 0.0000000e+00 1.06e+04 3.62e-03 -5.4 5.08e+00 -3.1 1.00e+00 1.00e+00w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 161r 0.0000000e+00 1.05e+04 8.60e-03 -5.4 1.53e+01 -3.6 1.00e+00 7.45e-09h 27\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 162r 0.0000000e+00 1.05e+04 6.99e-01 -5.4 4.61e+01 -4.1 1.00e+00 1.14e-13h 44\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 163r 0.0000000e+00 1.05e+04 2.14e+00 -5.4 1.41e+02 -4.6 1.00e+00 2.84e-14h 46\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 164r 0.0000000e+00 1.05e+04 6.79e+00 -5.4 4.48e+02 -5.1 1.00e+00 4.66e-10f 32\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 165r 0.0000000e+00 1.05e+04 2.13e+01 -5.4 1.64e+03 -5.5 8.03e-01 1.96e-11f 36\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 166r 0.0000000e+00 1.05e+04 5.45e+01 -5.4 1.44e+04 -6.0 1.69e-01 5.60e-13f 38\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 167r 0.0000000e+00 1.05e+04 2.91e+01 -5.4 1.92e+03 -5.6 1.00e+00 1.31e-13f 43\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 168r 0.0000000e+00 1.05e+04 3.94e+01 -5.4 2.52e+04 -6.1 2.91e-02 3.11e-16f 48\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 169r 0.0000000e+00 1.05e+04 3.44e+01 -5.4 2.27e+03 -5.6 1.00e+00 3.46e-15h 48\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 170r 0.0000000e+00 1.05e+04 4.50e+01 -5.4 7.69e+04 -6.1 9.32e-03 1.28e-17f 51\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 171r 0.0000000e+00 2.67e+04 3.33e+01 -5.4 2.71e+03 -5.7 1.00e+00 4.08e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 172r 0.0000000e+00 2.67e+04 9.73e+02 -5.4 1.12e+03 - 1.93e-03 9.14e-05w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 173r 0.0000000e+00 4.37e+04 5.94e+02 -5.4 7.46e+03 -6.2 2.29e-01 2.40e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 174r 0.0000000e+00 1.05e+04 4.51e+01 -5.4 3.87e+03 - 1.00e+00 2.97e-12f 37\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 175r 0.0000000e+00 1.05e+04 6.47e+01 -5.4 3.27e+03 -5.7 2.19e-01 7.69e-14f 43\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 176r 0.0000000e+00 1.05e+04 5.10e+01 -5.4 8.69e+02 -5.3 1.00e+00 1.14e-13h 44\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 177r 0.0000000e+00 1.05e+04 7.51e+01 -5.4 4.00e+03 -5.8 1.79e-01 6.43e-11f 33\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 178r 0.0000000e+00 1.05e+04 6.82e+01 -5.4 1.00e+03 -5.4 1.00e+00 4.66e-10f 32\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 179r 0.0000000e+00 1.05e+04 1.03e+02 -5.4 5.00e+03 -5.8 1.43e-01 1.29e-11f 35\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 180r 0.0000000e+00 1.05e+04 1.08e+02 -5.4 1.15e+03 -5.4 1.00e+00 1.39e-11f 37\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 181r 0.0000000e+00 1.05e+04 1.65e+02 -5.4 6.42e+03 -5.9 1.12e-01 5.01e-12f 36\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 182r 0.0000000e+00 1.05e+04 2.00e+02 -5.4 1.34e+03 -5.5 1.00e+00 1.20e-11f 37\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 183r 0.0000000e+00 1.05e+04 3.13e+02 -5.4 8.54e+03 -5.9 8.39e-02 9.41e-13f 38\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 184r 0.0000000e+00 2.67e+04 6.63e+01 -5.4 1.55e+03 -5.5 1.00e+00 7.13e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 185r 0.0000000e+00 2.67e+04 8.09e+02 -5.4 1.01e+03 - 2.25e-03 8.90e-04w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 186r 0.0000000e+00 4.40e+04 1.17e+02 -5.4 4.65e+03 -6.0 4.39e-01 3.92e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 187r 0.0000000e+00 1.05e+04 4.40e+02 -5.4 8.89e+03 - 1.00e+00 2.07e-11f 35\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 188r 0.0000000e+00 1.05e+04 5.51e+02 -5.4 1.81e+03 -5.6 3.96e-01 8.88e-12f 37\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 189r 0.0000000e+00 1.05e+04 8.25e+02 -5.4 1.87e+04 -6.0 3.12e-02 1.08e-13f 40\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 190r 0.0000000e+00 1.05e+04 3.35e+01 -5.4 2.20e+03 -5.6 4.67e-01 2.27e-13f 43\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 191r 0.0000000e+00 1.05e+04 4.40e+01 -5.4 4.69e+04 -6.1 1.56e-02 5.36e-15f 43\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 192r 0.0000000e+00 1.05e+04 3.87e+01 -5.4 2.56e+03 -5.7 1.00e+00 2.46e-14f 45\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 193r 0.0000000e+00 1.05e+04 1.92e+01 -5.4 7.26e+02 -5.2 9.88e-01 1.14e-13h 44\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 194r 0.0000000e+00 1.05e+04 4.68e+01 -5.4 3.07e+03 -5.7 7.96e-01 1.68e-10f 32\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 195r 0.0000000e+00 1.05e+04 3.54e+01 -5.4 8.31e+02 -5.3 1.00e+00 5.82e-11f 35\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 196r 0.0000000e+00 1.05e+04 8.07e+01 -5.4 3.74e+03 -5.8 5.32e-01 6.87e-11f 33\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 197r 0.0000000e+00 2.44e+04 4.51e+01 -5.4 9.55e+02 -5.3 1.00e+00 1.00e+00w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 198r 0.0000000e+00 2.90e+04 1.83e+02 -5.4 3.03e+03 -5.8 6.02e-01 1.26e-01w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 199r 0.0000000e+00 2.90e+04 3.65e+02 -5.4 1.03e+03 - 1.58e-03 1.30e-03w 1\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 200r 0.0000000e+00 1.05e+04 6.99e+01 -5.4 9.09e+03 -6.3 1.00e+00 2.91e-11f 35\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of Iterations....: 200\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: (scaled) (unscaled)\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Dual infeasibility......: 6.9908071367141474e+01 6.9908071367141474e+01\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Constraint violation....: 2.8645094423111342e-03 1.0458847092153306e+04\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Complementarity.........: 1.3579265591895737e-03 1.3579265591895737e-03\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Overall NLP error.......: 2.8645094423111342e-03 1.0458847092153306e+04\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of objective function evaluations = 5209\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of objective gradient evaluations = 6\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of equality constraint evaluations = 5210\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of inequality constraint evaluations = 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of equality constraint Jacobian evaluations = 203\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of inequality constraint Jacobian evaluations = 0\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of Lagrangian Hessian evaluations = 200\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Total CPU secs in IPOPT (w/o function evaluations) = 0.176\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Total CPU secs in NLP function evaluations = 0.014\n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", + "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: EXIT: Maximum Number of Iterations Exceeded.\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit: Initialization Step 3 maxIterations - .\n", + "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit: Initialization Complete: maxIterations - \n", + "Initialization failed.\n" + ] + } + ], + "source": [ + "import logging\n", + "from pyomo.environ import (\n", + " ComponentMap,\n", + " ConcreteModel,\n", + " Constraint,\n", + " exp,\n", + " Param,\n", + " Reference,\n", + " units as pyunits,\n", + " value,\n", + ")\n", + "\n", + "from idaes.core import (\n", + " ControlVolume0DBlock,\n", + " FlowsheetBlock,\n", + " MaterialFlowBasis,\n", + " MomentumBalanceType,\n", + ")\n", + "import idaes.logger as idaeslog\n", + "from idaes.core.scaling.util import get_scaling_factor\n", + "from idaes.core.util.exceptions import ConfigurationError, InitializationError\n", + "\n", + "from idaes.models.properties.modular_properties.base.generic_property import (\n", + " GenericParameterBlock,\n", + ")\n", + "\n", + "from idaes.models_extra.column_models.solvent_reboiler import SolventReboiler\n", + "from idaes.models_extra.column_models.properties.MEA_solvent import (\n", + " configuration as aqueous_mea,\n", + ")\n", + "from idaes.models_extra.column_models.properties.MEA_vapor import flue_gas\n", + "\n", + "logging.getLogger(\"pyomo.repn.plugins.nl_writer\").setLevel(logging.ERROR)\n", + "\n", + "\n", + "def create_model():\n", + " m = ConcreteModel()\n", + " m.fs = FlowsheetBlock(dynamic=False)\n", + "\n", + " m.fs.liquid_properties = GenericParameterBlock(**aqueous_mea)\n", + " m.fs.vapor_properties = GenericParameterBlock(**flue_gas)\n", + "\n", + " m.fs.unit = SolventReboiler(\n", + " liquid_property_package=m.fs.liquid_properties,\n", + " vapor_property_package=m.fs.vapor_properties,\n", + " )\n", + "\n", + " m.fs.unit.inlet.flow_mol[0].fix(83.89)\n", + " m.fs.unit.inlet.temperature[0].fix(392.5)\n", + " m.fs.unit.inlet.pressure[0].fix(183700)\n", + " m.fs.unit.inlet.mole_frac_comp[0, \"CO2\"].fix(0.0326)\n", + " m.fs.unit.inlet.mole_frac_comp[0, \"H2O\"].fix(0.8589)\n", + " m.fs.unit.inlet.mole_frac_comp[0, \"MEA\"].fix(0.1085)\n", + "\n", + " m.fs.unit.heat_duty.fix(430.61e3)\n", + " return m\n", + "\n", + "\n", + "if __name__ == \"__main__\":\n", + " m = create_model()\n", + "\n", + " reboiler_init = m.fs.unit.default_initializer(always_estimate_states=True)\n", + " try:\n", + " reboiler_init.initialize(m.fs.unit, output_level=idaeslog.DEBUG)\n", + " except InitializationError:\n", + " print(\"Initialization failed.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Step 2: Run Model Diagnostics\n", + "\n", + "We see that the unit model failed to initialize. When confronted with a bad solution state, we should first use the `DiagnosticsToolbox` to check to see if there are structural issues with the model." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "====================================================================================\n", + "Model Statistics\n", + "\n", + " Activated Blocks: 23 (Deactivated: 0)\n", + " Free Variables in Activated Constraints: 77 (External: 0)\n", + " Free Variables with only lower bounds: 15\n", + " Free Variables with only upper bounds: 0\n", + " Free Variables with upper and lower bounds: 50\n", + " Fixed Variables in Activated Constraints: 66 (External: 0)\n", + " Activated Equality Constraints: 77 (Deactivated: 0)\n", + " Activated Inequality Constraints: 0 (Deactivated: 0)\n", + " Activated Objectives: 0 (Deactivated: 0)\n", + "\n", + "------------------------------------------------------------------------------------\n", + "1 WARNINGS\n", + "\n", + " WARNING: Found 9 potential evaluation errors.\n", + "\n", + "------------------------------------------------------------------------------------\n", + "2 Cautions\n", + "\n", + " Caution: 11 variables fixed to 0\n", + " Caution: 82 unused variables (82 fixed)\n", + "\n", + "------------------------------------------------------------------------------------\n", + "Suggested next steps:\n", + "\n", + " display_potential_evaluation_errors()\n", + "\n", + "====================================================================================\n" + ] + } + ], + "source": [ + "from idaes.core.util import DiagnosticsToolbox\n", + "\n", + "dt = DiagnosticsToolbox(m)\n", + "dt.report_structural_issues()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The density relationship is being flagged for potential evaluation errors. The interval arithmetic used to identify potential evaluation errors can produce relatively loose bounds, especially for the sort of large polynomial expressions favored in the literature. Independent testing of the density relationship over a wide range of values has demonstrated that no evaluation errors occur, so we can ignore these warnings.\n", + "\n", + "The next step is determining which numerical issues exist." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "====================================================================================\n", + "Model Statistics\n", + "\n", + " Jacobian Condition Number: 2.718E+13\n", + "\n", + "------------------------------------------------------------------------------------\n", + "3 WARNINGS\n", + "\n", + " WARNING: 3 Constraints with large residuals (>1.0E-05)\n", + " WARNING: 1 Variable with extreme Jacobian column norms (<1.0E-08 or >1.0E+08)\n", + " WARNING: 1 Constraint with extreme Jacobian row norms (<1.0E-08 or >1.0E+08)\n", + "\n", + "------------------------------------------------------------------------------------\n", + "8 Cautions\n", + "\n", + " Caution: 9 Variables with value close to their bounds (abs=1.0E-04, rel=1.0E-04)\n", + " Caution: 18 Variables with value close to zero (tol=1.0E-08)\n", + " Caution: 30 Variables with extreme value (<1.0E-04 or >1.0E+04)\n", + " Caution: 2 Constraints with mismatched terms\n", + " Caution: 1 Constraint with potential cancellation of terms\n", + " Caution: 27 Variables with extreme Jacobian column norms (<1.0E-04 or >1.0E+04)\n", + " Caution: 16 Constraints with extreme Jacobian row norms (<1.0E-04 or >1.0E+04)\n", + " Caution: 50 extreme Jacobian Entries (<1.0E-04 or >1.0E+04)\n", + "\n", + "------------------------------------------------------------------------------------\n", + "Suggested next steps:\n", + "\n", + " display_constraints_with_large_residuals()\n", + " compute_infeasibility_explanation()\n", + " display_variables_with_extreme_jacobians()\n", + " display_constraints_with_extreme_jacobians()\n", + "\n", + "====================================================================================\n" + ] + } + ], + "source": [ + "dt.report_numerical_issues()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In order to help interpret this output, we need to review the solution of systems of nonlinear equations.\n", + "\n", + "When we try to solve a square problem (i.e., a problem with zero degrees of freedom) using IPOPT, we are asking it to solve an equation of the form\n", + "$$\n", + "\\mathbf{f}(\\mathbf{x}) = \\mathbf{0}\n", + "$$\n", + "in which $\\mathbf{f}(\\cdot)$ is a vector-valued function of length $n$, and $\\mathbf{x}$ is a vector also of length $n$. Due to the finite accuracy of floating point arithmetic, the most we can ask for is $||\\mathbf{f}(\\mathbf{x})|| < \\varepsilon$, for some small value of $\\varepsilon$. The IDAES default solver configuration sets $\\varepsilon = 10^{-6}$. For some constraint $j$, the value of $f_j(x_k)$ is the called its *residual*, i.e., the remaining error in constraint satisfaction. IPOPT displays the infinity norm of the constraint residual,\n", + "$$\n", + "\\lvert\\lvert \\mathbf{f}(\\mathbf{x}_k)\\rvert\\rvert_{\\infty} := \\max_j \\lvert f_j(\\mathbf{x}_k)\\rvert\n", + "$$\n", + "i.e., the constraint residual with largest magnitude, for each step $k$ in the primal infeasibility (`inf_pr`) column.\n", + "\n", + "Problems of this form are typically solved with some variation on Newton's method. We denote the Jacobian matrix for function $\\mathbf{f}(\\mathbf{x})$ as\n", + "$$\n", + "\\mathbf{J}(\\mathbf{x}) := \\begin{bmatrix}\n", + " \\frac{\\partial f_1}{\\partial x_1} & \\dots & \\frac{\\partial f_1}{\\partial x_n} \\\\\n", + " \\vdots & \\ddots & \\vdots \\\\\n", + " \\frac{\\partial f_n}{\\partial x_1} & \\dots & \\frac{\\partial f_n}{\\partial x_n}\n", + "\\end{bmatrix}\n", + "$$\n", + "Note that each row of $\\mathbf{J}(\\cdot)$ is associated with a constraint and every column is associated with a variable.\n", + "\n", + "In the classical form of Newton's method, we start with an initial guess $\\mathbf{x}_0$, then iterate using the relationship\n", + "\n", + "\\begin{align}\n", + "\\mathbf{J}(\\mathbf{x}_k)\\cdot\\mathbf{\\delta x}_k &= -\\mathbf{f}(\\mathbf{x}_k) \\\\\n", + "\\mathbf{x}_{k+1} &= \\mathbf{x}_k + \\mathbf{\\delta x}_k\n", + "\\end{align}\n", + "\n", + "IPOPT incorporates additional features, such as a line search, in order to enhance its robustness to bad initial guesses, but it is designed to take full Newton steps in the neighborhood of a solution (for the full details, refer to [W\u00e4chter and Biegler (2006)](#references)).\n", + "\n", + "The condition number $\\kappa_2(\\cdot)$ (for the Euclidean norm) is a worst-case error bound in the solution of a system of linear equations. In this case, we have\n", + "$$\n", + "\\lvert\\lvert\\mathbf{\\delta x}_k\\rvert\\rvert_2 \\leq \\kappa(\\mathbf{J}(\\mathbf{x}_k)) \\cdot \\lvert\\lvert \\mathbf{f}(\\mathbf{x}_k)\\rvert\\rvert_2\n", + "$$\n", + "If we terminate under the condition $||\\mathbf{f}(\\mathbf{x}_f)||_2 < \\varepsilon$, then\n", + "$$\n", + "\\lvert\\lvert\\mathbf{\\delta x}_f\\rvert\\rvert_2 \\leq \\kappa(\\mathbf{J}(\\mathbf{x}_f)) \\cdot \\varepsilon\n", + "$$\n", + "With a condition number on the order of $10^{13}$ and the default tolerance $\\varepsilon = 10^{-6}$, then the difference between the computed solution $x_f$ and the true solution $x$ could be on the order of $10^7$.\n", + "\n", + "In practice, however, we frequently end up with much better results than those predicted by this worst-case bound. Frequently, we find that most constraints have residuals on the order of $10^{-10}$ or less, with a few problematic constraints having larger residuals. That is the case here." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Number of constraints: 77\n", + "====================================================================================\n", + "The following constraint(s) have large residuals (>1.0E-10):\n", + "\n", + " fs.unit.unit_material_balance[0.0,CO2]: 1.84866E-10\n", + " fs.unit.unit_material_balance[0.0,N2]: 1.89950E-10\n", + " fs.unit.unit_material_balance[0.0,O2]: 1.87656E-10\n", + " fs.unit.unit_phase_equilibrium[0.0,CO2]: 1.04588E+04\n", + " fs.unit.unit_phase_equilibrium[0.0,H2O]: 8.88278E-07\n", + " fs.unit.unit_enthalpy_balance[0.0]: 5.05679E-10\n", + " fs.unit.liquid_phase.material_balances[0.0,CO2]: 1.70459E-10\n", + " fs.unit.liquid_phase.enthalpy_balances[0.0]: 1.17285E-05\n", + " fs.unit.liquid_phase.properties_out[0.0].sum_mole_frac_out: 2.08134E-10\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-]: 8.83857E-06\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]: 1.54414E-07\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA_+]: 7.69821E-06\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,H2O]: 2.50511E-08\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA]: 4.55346E-06\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2]: 4.42749E-05\n", + " fs.unit.vapor_phase[0.0].sum_mole_frac_out: 1.71144E-10\n", + "\n", + "====================================================================================\n" + ] + } + ], + "source": [ + "import idaes.core.util.model_statistics as mstat\n", + "\n", + "print(f\"Number of constraints: {mstat.number_activated_constraints(m)}\")\n", + "dt.config.constraint_residual_tolerance = 1e-10\n", + "dt.display_constraints_with_large_residuals()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Even with a non-optimal termination, we have only three constraints with residuals greater than $10^{-5}$ for a model with 77 active constraints. Two of those constraints are on the order of $10^{-5}$, but the third is on the order of $10^4$.\n", + "\n", + "Nevertheless, a condition number on the order of $10^{13}$ is significantly higher than we'd like, because large condition numbers can degrade the convergence of Newton's method or even prevent it from converging entirely. Ideally, we want flowsheets to have condition numbers less than $10^8$. Connecting unit models together with things like recycle streams can amplify the overall flowsheet condition number to be multiple orders of magnitude greater than that of its individual components. Consequently, we want unit models to have condition numbers less than $10^4$.\n", + "\n", + "Model scaling can both reduce the Jacobian's condition number and help ensure that constraints are satisfied to an appropriate precision. Both of those effects can help the model initialization to converge. Before beginning to write a scaler object, however, we should look at the structure of the unit model." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "def build(self):\n", + " \"\"\"Build the model.\n", + "\n", + " Args:\n", + " None\n", + " Returns:\n", + " None\n", + " \"\"\"\n", + " # Call UnitModel.build to setup dynamics\n", + " super().build()\n", + "\n", + " # Check phase lists match assumptions\n", + " if self.config.vapor_property_package.phase_list != [\"Vap\"]:\n", + " raise ConfigurationError(\n", + " f\"{self.name} SolventReboiler model requires that the vapor \"\n", + " f\"phase property package have a single phase named 'Vap'\"\n", + " )\n", + " if self.config.liquid_property_package.phase_list != [\"Liq\"]:\n", + " raise ConfigurationError(\n", + " f\"{self.name} SolventReboiler model requires that the liquid \"\n", + " f\"phase property package have a single phase named 'Liq'\"\n", + " )\n", + "\n", + " # Check for at least one common component in component lists\n", + " if not any(\n", + " j in self.config.vapor_property_package.component_list\n", + " for j in self.config.liquid_property_package.component_list\n", + " ):\n", + " raise ConfigurationError(\n", + " f\"{self.name} SolventReboiler model requires that the liquid \"\n", + " f\"and vapor phase property packages have at least one \"\n", + " f\"common component.\"\n", + " )\n", + "\n", + " # ---------------------------------------------------------------------\n", + " # Add Control Volume for the Liquid Phase\n", + " self.liquid_phase = ControlVolume0DBlock(\n", + " dynamic=self.config.dynamic,\n", + " has_holdup=self.config.has_holdup,\n", + " property_package=self.config.liquid_property_package,\n", + " property_package_args=self.config.liquid_property_package_args,\n", + " )\n", + "\n", + " self.liquid_phase.add_state_blocks(has_phase_equilibrium=True)\n", + "\n", + " # Separate liquid and vapor phases means that phase equilibrium will\n", + " # be handled at the unit model level, thus has_phase_equilibrium is\n", + " # False, but has_mass_transfer is True.\n", + " self.liquid_phase.add_material_balances(\n", + " balance_type=self.config.material_balance_type,\n", + " has_mass_transfer=True,\n", + " has_phase_equilibrium=False,\n", + " )\n", + "\n", + " # Need to include enthalpy transfer term for the mass transfer\n", + " self.liquid_phase.add_energy_balances(\n", + " balance_type=self.config.energy_balance_type,\n", + " has_heat_transfer=True,\n", + " has_enthalpy_transfer=True,\n", + " )\n", + "\n", + " self.liquid_phase.add_momentum_balances(\n", + " balance_type=self.config.momentum_balance_type,\n", + " has_pressure_change=self.config.has_pressure_change,\n", + " )\n", + "\n", + " # ---------------------------------------------------------------------\n", + " # Add single state block for vapor phase\n", + " tmp_dict = dict(**self.config.vapor_property_package_args)\n", + " tmp_dict[\"has_phase_equilibrium\"] = False\n", + " tmp_dict[\"defined_state\"] = False\n", + " self.vapor_phase = self.config.vapor_property_package.build_state_block(\n", + " self.flowsheet().time, doc=\"Vapor phase properties\", **tmp_dict\n", + " )\n", + "\n", + " # ---------------------------------------------------------------------\n", + " # Check flow basis is compatible\n", + " t_init = self.flowsheet().time.first()\n", + " if (\n", + " self.vapor_phase[t_init].get_material_flow_basis()\n", + " != self.liquid_phase.properties_out[t_init].get_material_flow_basis()\n", + " ):\n", + " raise ConfigurationError(\n", + " f\"{self.name} vapor and liquid property packages must use the \"\n", + " f\"same material flow basis.\"\n", + " )\n", + "\n", + " # ---------------------------------------------------------------------\n", + " # Add Ports for the reboiler\n", + " self.add_inlet_port(name=\"inlet\", block=self.liquid_phase, doc=\"Liquid feed\")\n", + " self.add_outlet_port(name=\"bottoms\", block=self.liquid_phase, doc=\"Bottoms stream\")\n", + " self.add_outlet_port(\n", + " name=\"vapor_reboil\",\n", + " block=self.vapor_phase,\n", + " doc=\"Vapor stream from reboiler\",\n", + " )\n", + "\n", + " # ---------------------------------------------------------------------\n", + " # Add unit level constraints\n", + " # First, need the union and intersection of component lists\n", + " all_comps = (\n", + " self.vapor_phase.component_list\n", + " | self.liquid_phase.properties_out.component_list\n", + " )\n", + " common_comps = (\n", + " self.vapor_phase.component_list\n", + " & self.liquid_phase.properties_out.component_list\n", + " )\n", + "\n", + " # Get units for unit conversion\n", + " vunits = self.config.vapor_property_package.get_metadata().get_derived_units\n", + " lunits = self.config.liquid_property_package.get_metadata().get_derived_units\n", + " flow_basis = self.vapor_phase[t_init].get_material_flow_basis()\n", + " if flow_basis == MaterialFlowBasis.molar:\n", + " fb = \"flow_mole\"\n", + " elif flow_basis == MaterialFlowBasis.mass:\n", + " fb = \"flow_mass\"\n", + " else:\n", + " raise ConfigurationError(\n", + " f\"{self.name} SolventReboiler only supports mass or molar \"\n", + " f\"basis for MaterialFlowBasis.\"\n", + " )\n", + "\n", + " if any(j not in common_comps for j in self.vapor_phase.component_list):\n", + " # We have non-condensable components present, need zero-flow param\n", + " self.zero_flow_param = Param(\n", + " mutable=True, default=1e-8, units=vunits(\"flow_mole\")\n", + " )\n", + "\n", + " # Material balances\n", + " def rule_material_balance(blk, t, j):\n", + " if j in common_comps:\n", + " # Component is in equilibrium\n", + " # Mass transfer equals vapor flowrate\n", + " return -blk.liquid_phase.mass_transfer_term[t, \"Liq\", j] == pyunits.convert(\n", + " blk.vapor_phase[t].get_material_flow_terms(\"Vap\", j),\n", + " to_units=lunits(fb),\n", + " )\n", + " elif j in self.vapor_phase.component_list:\n", + " # Non-condensable component\n", + " # No mass transfer term\n", + " # Set vapor flowrate to an arbitrary small value\n", + " return (\n", + " blk.vapor_phase[t].get_material_flow_terms(\"Vap\", j)\n", + " == blk.zero_flow_param\n", + " )\n", + " else:\n", + " # Non-vaporisable component\n", + " # Mass transfer term is zero, no vapor flowrate\n", + " return blk.liquid_phase.mass_transfer_term[t, \"Liq\", j] == 0 * lunits(fb)\n", + "\n", + " self.unit_material_balance = Constraint(\n", + " self.flowsheet().time,\n", + " all_comps,\n", + " rule=rule_material_balance,\n", + " doc=\"Unit level material balances\",\n", + " )\n", + "\n", + " # Phase equilibrium constraints\n", + " # For all common components, equate fugacity in vapor and liquid\n", + " def rule_phase_equilibrium(blk, t, j):\n", + " return blk.liquid_phase.properties_out[t].fug_phase_comp[\n", + " \"Liq\", j\n", + " ] == pyunits.convert(\n", + " blk.vapor_phase[t].fug_phase_comp[\"Vap\", j], to_units=lunits(\"pressure\")\n", + " )\n", + "\n", + " self.unit_phase_equilibrium = Constraint(\n", + " self.flowsheet().time,\n", + " common_comps,\n", + " rule=rule_phase_equilibrium,\n", + " doc=\"Unit level phase equilibrium constraints\",\n", + " )\n", + "\n", + " # Temperature equality constraint\n", + " def rule_temperature_balance(blk, t):\n", + " return blk.liquid_phase.properties_out[t].temperature == pyunits.convert(\n", + " blk.vapor_phase[t].temperature, to_units=lunits(\"temperature\")\n", + " )\n", + "\n", + " self.unit_temperature_equality = Constraint(\n", + " self.flowsheet().time,\n", + " rule=rule_temperature_balance,\n", + " doc=\"Unit level temperature equality\",\n", + " )\n", + "\n", + " # Unit level energy balance\n", + " # Energy leaving in vapor phase must be equal and opposite to enthalpy\n", + " # transfer from liquid phase\n", + " def rule_energy_balance(blk, t):\n", + " return -blk.liquid_phase.enthalpy_transfer[t] == pyunits.convert(\n", + " blk.vapor_phase[t].get_enthalpy_flow_terms(\"Vap\"),\n", + " to_units=lunits(\"energy\") / lunits(\"time\"),\n", + " )\n", + "\n", + " self.unit_enthalpy_balance = Constraint(\n", + " self.flowsheet().time,\n", + " rule=rule_energy_balance,\n", + " doc=\"Unit level enthalpy_balance\",\n", + " )\n", + "\n", + " # Pressure balance constraint\n", + " def rule_pressure_balance(blk, t):\n", + " return blk.liquid_phase.properties_out[t].pressure == pyunits.convert(\n", + " blk.vapor_phase[t].pressure, to_units=lunits(\"pressure\")\n", + " )\n", + "\n", + " self.unit_pressure_balance = Constraint(\n", + " self.flowsheet().time,\n", + " rule=rule_pressure_balance,\n", + " doc=\"Unit level pressure balance\",\n", + " )\n", + "\n", + " # Set references to balance terms at unit level\n", + " self.heat_duty = Reference(self.liquid_phase.heat[:])\n", + "\n", + " if (\n", + " self.config.has_pressure_change is True\n", + " and self.config.momentum_balance_type != MomentumBalanceType.none\n", + " ):\n", + " self.deltaP = Reference(self.liquid_phase.deltaP[:])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As is typical with IDAES models, two submodels are created: the `ControlVolume0D` named `liquid_phase` and the `StateBlock` named `vapor_phase`. Then several unit model level constraints are written. \n", + "\n", + "## Step 3: Creating a New Scaler Class\n", + "\n", + "To create a new scaling routine for the equilibrium reactor, we start by creating a new ``Scaler`` class which inherits from the ``CustomScalerBase`` class in ``idaes.core.scaling``. The ``CustomScalerBase`` class contains a number of useful methods to help us in developing our scaling routine, including some placeholder methods for implementing a standard scaling workflow and helper methods for doing common tasks.\n", + "\n", + "The cell below shows how to create our new class which we will name ``SolventReboilerScaler`` as well as two key methods we will fill out as part of this workshop." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "from idaes.core.scaling import CustomScalerBase\n", + "\n", + "\n", + "class SolventReboilerScaler(CustomScalerBase):\n", + " def variable_scaling_routine(\n", + " self, model, overwrite: bool = False, submodel_scalers: dict = None\n", + " ):\n", + " # Empty method for now\n", + " pass\n", + "\n", + " def constraint_scaling_routine(\n", + " self, model, overwrite: bool = False, submodel_scalers: dict = None\n", + " ):\n", + " # Empty method for now\n", + " pass" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As you know from the first scaling tutorial, the ``variable_scaling_routine`` and ``constraint_scaling_routine`` methods are used to implement subroutines for scaling the variables and constraints in the model respectively. Separately, there is a ``scale_model`` method that will call each of these in sequence in order to scale an entire model by applying the following steps:\n", + "\n", + "1. apply variable scaling routine,\n", + "2. apply first stage scaling fill-in,\n", + "3. apply constraint scaling routine,\n", + "4. apply second stage scaling fill-in.\n", + "\n", + "The second and fourth steps are intended to allow users to provide methods to fill in missing scaling information that was not provided by the first and second steps. However, these methods are prone to perform poorly on all but the simplest models (see Step 5 for more information).\n", + "\n", + "## Step 4: Apply Scaling to Sub-Models\n", + "\n", + "First, let's look at how to scale the control volume and state block sub-models. Because the property package for the ``vapor_phase`` state block is specified by the user, we do not know what variables and constraints it may contain, so we cannot (and should not) scale it directly. The property package creator (hopefully) created a scaler object that we can use. The zero-dimensional control volume ``liquid_phase`` contains two state blocks, material, energy, and pressure balance constraints, and variables corresponding to additional interaction terms. Because we are choosing which terms to create in the control volume, we could, in principle, scale it at the unit model level. However, because control volumes typically should be scaled in the same way, a submodel scaler has been provided for it as well. Thus, what we want to do here is to call the variable and constraint scaling routines from the ``Scaler`` associated with each sub-model, which we can do using the ``call_submodel_scaler_method`` method." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "class SolventReboilerScaler(CustomScalerBase):\n", + " def variable_scaling_routine(\n", + " self, model, overwrite: bool = False, submodel_scalers: ComponentMap = None\n", + " ):\n", + " # Call scaling methods for sub-models\n", + " self.call_submodel_scaler_method(\n", + " submodel=model.liquid_phase,\n", + " method=\"variable_scaling_routine\",\n", + " submodel_scalers=submodel_scalers,\n", + " overwrite=overwrite,\n", + " )\n", + "\n", + " self.call_submodel_scaler_method(\n", + " submodel=model.vapor_phase,\n", + " method=\"variable_scaling_routine\",\n", + " submodel_scalers=submodel_scalers,\n", + " overwrite=overwrite,\n", + " )\n", + "\n", + " def constraint_scaling_routine(\n", + " self, model, overwrite: bool = False, submodel_scalers: ComponentMap = None\n", + " ):\n", + " # Call scaling methods for sub-models\n", + " self.call_submodel_scaler_method(\n", + " submodel=model.liquid_phase,\n", + " method=\"constraint_scaling_routine\",\n", + " submodel_scalers=submodel_scalers,\n", + " overwrite=overwrite,\n", + " )\n", + "\n", + " self.call_submodel_scaler_method(\n", + " submodel=model.vapor_phase,\n", + " method=\"constraint_scaling_routine\",\n", + " submodel_scalers=submodel_scalers,\n", + " overwrite=overwrite,\n", + " )" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In order for the submodel scaling to function properly, default scaling factors need to be set for some variables. The property package scaler cannot know if the system is supposed to be bench scale, pilot scale, or production scale unless the user sets a default for flow rate. These defaults can be set on a unit model by unit model basis by using the `submodel_scalers` argument, or they can be set at the flowsheet level on the parameter block. We will do the latter.\n", + "\n", + "First, we need to create objects using the modular property submodel scaler class." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "liquid_properties_scaler = m.fs.liquid_properties.default_state_scaler_class()\n", + "vapor_properties_scaler = m.fs.vapor_properties.default_state_scaler_class()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, let's see what default scaling factors these scaler objects have." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'flow_mol_phase': ,\n", + " 'mole_frac_phase_comp': 10,\n", + " 'temperature': 0.0033333333333333335,\n", + " 'pressure': 1e-05,\n", + " 'enth_mol_phase': ,\n", + " 'visc_d_phase': ,\n", + " 'therm_cond_phase': ,\n", + " 'mole_frac_phase_comp_true': 10,\n", + " 'mole_frac_phase_comp_apparent': 10,\n", + " 'dens_mol_phase': ,\n", + " 'vol_mol_phase': }" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "liquid_properties_scaler.default_scaling_factors" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can see that we are required to set a default scaling factor for ``flow_mol_phase``. Furthermore, it is recommended to set a default scaling factor for ``enth_mol_phase``, ``visc_d_phase``, ``therm_cond_phase``, `dens_mol_phase`, and`vol_mol_phase`. For these latter quantities, there is a method to estimate reasonable scaling factors, but it might not be suitible for all cases.\n", + "\n", + "With an inlet flow of about 80 mol/s, a scaling factor of 1/80 is appropriate. We can ignore ``visc_d_phase`` and ``therm_cond_phase``, because this unit model does not require dynamic viscosity or thermal conductivity. Molar enthalpy is a tougher quantity to scale.\n", + "\n", + "By convention, the molar enthalpy of each element in its pure form at $25^\\circ\\text{C}$ and $1\\:\\text{atm}$ is set equal to zero. In some property packages, enthalpy of formation is taken into account for compounds, while in some property packages it is not. However, the scaling factor for enthalpy should not depend on this convention---only enthalpy *differences* are meaningful. So we need to determine how to determine what constitutes a \"significant\" enthalpy difference for this property package. The way the modular property scaler object estimates this is through the temperature scaling factor, which determines what a \"significant\" temperature difference is, and the observation that a wide range of substances have a specific heat capacity around $2\\:\\frac{\\text{J}}{\\text{g K}}$.\n", + "\n", + "This default method is good enough for our purposes now. We can revisit it later, if necessary." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "liquid_properties_scaler.default_scaling_factors[\"flow_mol_phase\"] = 1 / 80\n", + "vapor_properties_scaler.default_scaling_factors[\"flow_mol_phase\"] = 1 / 10\n", + "\n", + "m.fs.liquid_properties.default_state_scaler_object = liquid_properties_scaler\n", + "m.fs.vapor_properties.default_state_scaler_object = vapor_properties_scaler" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can see how much submodel scaling improves the conditioning of the unit model." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "====================================================================================\n", + "Model Statistics\n", + "\n", + " Jacobian Condition Number: 7.165E+10\n", + "\n", + "------------------------------------------------------------------------------------\n", + "1 WARNINGS\n", + "\n", + " WARNING: 1 Constraint with large residuals (>1.0E-05)\n", + "\n", + "------------------------------------------------------------------------------------\n", + "8 Cautions\n", + "\n", + " Caution: 9 Variables with value close to their bounds (abs=1.0E-04, rel=1.0E-04)\n", + " Caution: 14 Variables with value close to zero (tol=1.0E-08)\n", + " Caution: 27 Variables with extreme value (<1.0E-04 or >1.0E+04)\n", + " Caution: 2 Constraints with mismatched terms\n", + " Caution: 1 Constraint with potential cancellation of terms\n", + " Caution: 10 Variables with extreme Jacobian column norms (<1.0E-04 or >1.0E+04)\n", + " Caution: 4 Constraints with extreme Jacobian row norms (<1.0E-04 or >1.0E+04)\n", + " Caution: 33 extreme Jacobian Entries (<1.0E-04 or >1.0E+04)\n", + "\n", + "------------------------------------------------------------------------------------\n", + "Suggested next steps:\n", + "\n", + " display_constraints_with_large_residuals()\n", + " compute_infeasibility_explanation()\n", + "\n", + "====================================================================================\n" + ] + } + ], + "source": [ + "reboiler_scaler = SolventReboilerScaler()\n", + "reboiler_scaler.scale_model(m.fs.unit)\n", + "dt = DiagnosticsToolbox(m)\n", + "dt.report_numerical_issues()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We see in this case that partly scaling the model improved the condition number of the Jacobian by only two and a half orders of magnitude. This sort of marginal improvement is common for partial scaling, and sometimes partial scaling makes the model's condition number *worse*. When variables are scaled without the constraints they appear in also being scaled, it generates new extreme Jacobian entries. If we look at the number of extreme Jacobian rows and columns, however, we see the progress we've made. Before applying submodel scaling, we had 27 variables with extreme column norms and 16 constraints with extreme row norms. Now we have only 10 variables and 4 constraints.\n", + "\n", + "We are concerned with Jacobian rows and columns with extreme values because they allow us to estimate the Jacobian condition number. Determining the (Euclidean) condition number requires the computation of the *singular value decomposition* (SVD) of $\\mathbf{J}(\\mathbf{x})$. However, that process is computationally expensive for large models, and it does not identify individual variables and constraints as problematic (instead, it identifies *combinations* of variables and constraints as problematic). However, we have a lower bound to the condition number in terms of the norms of rows and columns of the Jacobian matrix:\n", + "$$\n", + "\\max\\left(\\frac{||\\mathbf{r}_\\text{max}||_2}{||\\mathbf{r}_\\text{min}||_2}, \\frac{||\\mathbf{c}_\\text{max}||_2}{||\\mathbf{c}_\\text{min}||_2}\\right) \\leq \\kappa(\\mathbf{J}(\\mathbf{x}))\n", + "$$\n", + "Consequently, Jacobian rows or columns with extremely large or extremely small norms indicate that the Jacobian is ill-conditioned. Each row is associated with a constraint and each column is associated with a variable. So the extreme Jacobian rows and columns give us a list of variables and constraints to investigate for scaling.\n", + "\n", + "
\n", + "Just because a variable or constraint has a Jacobian column or row with an extreme norm does not mean it is badly-scaled. Frequently, either a constraint containing the variable or a variable present in a constraint is the actual problem. \n", + "
\n", + "\n", + "
\n", + "NOTE\n", + "\n", + "Jacobian rows and columns with extreme norms reveal that the Jacobian matrix is ill-conditioned, but the converse is not true. A Jacobian matrix can have no rows and columns with extreme norms but still be singular or ill-conditioned.\n", + "\n", + "
\n", + "\n", + "\n", + "Let's see which variables and constraints are problematic." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "====================================================================================\n", + "The following variable(s) correspond to Jacobian columns with extreme norms(<1.0E-04 or>1.0E+04):\n", + "\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,CO2]: 3.450E+07\n", + " fs.unit.liquid_phase.enthalpy_transfer[0.0]: 1.970E+06\n", + " fs.unit.liquid_phase.properties_out[0.0].temperature: 1.586E+06\n", + " fs.unit.vapor_phase[0.0].pressure: 1.353E+05\n", + " fs.unit.vapor_phase[0.0].temperature: 1.014E+05\n", + " fs.unit.liquid_phase.properties_out[0.0].pressure: 1.000E+05\n", + " fs.unit.vapor_phase[0.0].flow_mol_phase[Vap]: 3.256E+04\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,H2O]: 1.954E+04\n", + " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]: 1.873E+04\n", + " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]: 1.863E+04\n", + "\n", + "====================================================================================\n", + "====================================================================================\n", + "The following constraint(s) correspond to Jacobian rows with extreme norms (<1.0E-04 or>1.0E+04):\n", + "\n", + " fs.unit.unit_phase_equilibrium[0.0,CO2]: 3.450E+07\n", + " fs.unit.unit_enthalpy_balance[0.0]: 1.973E+06\n", + " fs.unit.unit_phase_equilibrium[0.0,H2O]: 1.589E+06\n", + " fs.unit.unit_pressure_balance[0.0]: 1.414E+05\n", + "\n", + "====================================================================================\n" + ] + } + ], + "source": [ + "dt.display_variables_with_extreme_jacobians()\n", + "dt.display_constraints_with_extreme_jacobians()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "These four unit model level constraints are causing our remaining problems.\n", + "\n", + "## Step 5: Unit Model Level Scaling\n", + "\n", + "We should take a look at the constraints before determining their scaling factors. However, Pyomo's `pprint` method often prints out multiple terminal pages' worth of thermodynamic expressions, which are extremely difficult to parse. The output is so verbose because it descends into named `Expressions` and recursively subsititutes them into the constraint expression. Since IDAES makes heavy use of named `Expressions` to decrease the number of `Constraints` in a model, the output becomes unmanangable for all but the most simple constraints. The `print_compact_form` utility function usually results in much more readable output." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "- fs.unit.liquid_phase.enthalpy_transfer[0.0] == (kg*m**2/J/s**2)*fs.unit.vapor_phase[0.0]._enthalpy_flow_term[Vap]\n" + ] + } + ], + "source": [ + "from idaes.core.util.misc import print_compact_form\n", + "\n", + "print_compact_form(m.fs.unit.unit_enthalpy_balance[0.0])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This is a relatively straightforward constraint.\n", + "\n", + "So long as we have scaling factors set for the terms in the enthalpy balance, we can scale the constraint by the same factor. Because `liquid_phase.enthalpy_transfer[0.0]` is a `Var` created by the `ControlVolume0D`, it already has a scaling factor assigned by the `ControlVolume0DScaler`.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "5.076760620583219e-07" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "get_scaling_factor(m.fs.unit.liquid_phase.enthalpy_transfer[0.0])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "However, in the modular property framework, `get_enthalpy_flow_terms(p)` returns a named `Expression`. Expressions do not need to be scaled on their own. However, scaling hints can be assigned for them to assist in determining appropriate scaling factors for other variables and constraints. When the `get_scaling_factor` function is called on an `Expression`, it will return a scaling hint if one is assigned. (This behavior is useful, because what is a `Var` in one property package can be implemented as an `Expression` in another.)\n", + "\n", + "In this case, however, no scaling hint is assigned to `vapor_phase[0.0]._enthalpy_flow_term[\"Vap\"]`." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "None\n" + ] + } + ], + "source": [ + "print(get_scaling_factor(m.fs.unit.vapor_phase[0.0]._enthalpy_flow_term[\"Vap\"]))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To get an estimate of the size of that expression, then, we can look at its constituent terms:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "fs.unit.vapor_phase[0.0].flow_mol_phase[Vap]*fs.unit.vapor_phase[0.0].enth_mol_phase[Vap]\n" + ] + } + ], + "source": [ + "print_compact_form(m.fs.unit.vapor_phase[0.0]._enthalpy_flow_term[\"Vap\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The term `vapor_phase[0.0].flow_mol_phase[\"Vap\"]` *is* a `Var` and has a scaling factor applied." + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.1" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "get_scaling_factor(m.fs.unit.vapor_phase[0.0].flow_mol_phase[\"Vap\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "However, `vapor_phase[0.0].enth_mol_phase[\"Vap\"]` is a named `Expression`. Nevertheless, it has a scaling hint." + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "5.46268982847154e-05" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "get_scaling_factor(m.fs.unit.vapor_phase[0.0].enth_mol_phase[\"Vap\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Because the scaling factor of the molar flow rate is $0.1$, we can estimate that the molar flow rate will be about $10$. Similarly, we can estimate the size of a significant molar enthalpy difference is around the size of `1/5.46e-5`$ \\approx 18,000$. Therefore the general size of the enthalpy flow terms should be around $180,000$." + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.0125" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "get_scaling_factor(m.fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase[\"Liq\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The `get_sum_terms_nominal_values` method in `CustomScalerBase` which uses an expression walker to go through an expression to return a list of the expected magnitude (or \"nominal value\") of all additive terms in the expression based on the scaling factors for the variables involved. For example, suppose we have an expression\n", + "$$\n", + "a + b\\cdot c - d\\cdot (e - f)\n", + "$$\n", + "Let $\\sigma(v)$ denote the scaling factor of the variable $v$. Then `get_sum_terms_nominal_values` substitutes the inverse of the variable scaling factor into each term in the sum and returns it as a list:\n", + "$$\n", + "\\left[\\frac{1}{\\sigma(a)},\\; \\frac{1}{\\sigma(b) \\cdot \\sigma(c)}, \\frac{\\left(\\frac{1}{\\sigma(e)} - \\frac{1}{\\sigma(f)}\\right)}{\\sigma(d)} \\right]\n", + "$$\n", + "\n", + "This process can produce reliable estimates of expression magnitude for certain operations:\n", + " - Addition of positive numbers\n", + " - Multiplication and division\n", + " - Raising a variable to a fixed power\n", + "\n", + "For these operations, only an order-of-magnitude estimate for the variable is sufficient to get an order-of-magnitude estimate of the resulting expression. However, it is far less reliable for other operations:\n", + " - Subtraction (or addition of negative numbers to positive numbers)\n", + " - Functions with a variable exponent\n", + " - Trigometric functions\n", + " - Logarithms\n", + "\n", + "For these operations, an expression's final value is highly dependent on the exact values of its included variables. For example, suppose $\\sigma(e) = \\sigma(f)$. In that case, the term $d\\cdot (e - f)$ would have an estimated magnitude of $0$, which is useless for scaling purposes. It is in cases like this that scaling hints for named expressions. If we denote $G = e - f$ and assign $\\sigma(G) = \\sigma(e)$, we have a far better estimate of the term $d\\cdot (e - f)$ in the quantity $1/(\\sigma(d)\\cdot\\sigma(G))$.\n", + "\n", + "Logarithms are a special case. Since they convert multiplication to addition, application of a scaling factor simply shifts the zero point of the resulting expression.\n", + "$$\n", + " \\log(h \\cdot \\sigma(h)) = \\log(h) + \\log(\\sigma(h))\n", + "$$\n", + "\n", + "The output of a logarithmic expression should be considered well-scaled by default, unless its argument is an absolutely enormous number (in which case floating point arithmetic is probably inappropriate anyway).\n", + "\n", + "In the case of scaling `unit.unit_enthalpy_balance[0.0]`, we only have two additive terms, one consisting of a single variable, the other consisting of the product of a variable with an expression with a scaling hint. In this case, `get_sum_terms_nominal_values` should produce a good estimate of the order-of-magnitude of each term.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[1969759.9999999995, 183060.0]" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "reboiler_scaler.get_sum_terms_nominal_values(m.fs.unit.unit_enthalpy_balance[0.0])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The inverse of either of these numbers would be reasonable scaling factors. The `scale_constraint_by_nominal value` function automatically scales a constraint by using one of these numbers. Which number we use is selected using the `ConstraintScalingScheme` `Enum` If we take the inverse of the larger number, we are saying that the constraint needs to be satisfied with the same precision as the largest term in the sum. This corresponds to `ConstraintScalingScheme.inverseMaximum`. If we take the inverse of the smaller number, we are saying that the constraint needs to be satisfied with the same precision as the smallest term in the sum. This corresponds to `ConstraintScalingScheme.inverseMinimum`.\n", + "\n", + "In general, the `inverseMinimum` scheme is the safest to use, because it demands the most precision. Let's use the `inverseMinimum` method for this constraint in order to more precisely determine the vapor phase's temperature.\n", + "\n", + "The next two constraints can be dealt with together:" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[Liq,CO2] == fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,CO2]\n", + "\n", + "\n", + "fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[Liq,H2O] == fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,H2O]\n" + ] + } + ], + "source": [ + "print_compact_form(m.fs.unit.unit_phase_equilibrium[0.0, \"CO2\"])\n", + "print(\"\\n\")\n", + "print_compact_form(m.fs.unit.unit_phase_equilibrium[0.0, \"H2O\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "These are simple vapor-liquid equilibrium constraints for the volatile components. Let's see what `get_sum_terms_nominal_values` shows for them:" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[7623092.433711249, 10000.0]\n", + "[355.3596511053128, 10000.0]\n" + ] + } + ], + "source": [ + "print(\n", + " reboiler_scaler.get_sum_terms_nominal_values(\n", + " m.fs.unit.unit_phase_equilibrium[0.0, \"CO2\"]\n", + " )\n", + ")\n", + "print(\n", + " reboiler_scaler.get_sum_terms_nominal_values(\n", + " m.fs.unit.unit_phase_equilibrium[0.0, \"H2O\"]\n", + " )\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here, we see that, while the vapor phase fugacities are associated with a nominal value of 10000, the liquid phase fugacities have wildly different nominal values. We do expect the vapor phase to be enriched in $\\text{CO}_2$, but not by a factor of $2\\cdot 10^4$. Let's unpack these values. We are using the ideal gas law for the vapor phase, so the fugacity is simply the product of the mole fraction and vapor pressure:" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]*fs.unit.vapor_phase[0.0].pressure\n" + ] + } + ], + "source": [ + "print_compact_form(m.fs.unit.vapor_phase[0.0].fug_phase_comp[\"Vap\", \"CO2\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The liquid phase, by contrast, contains a complicated Henry's Law type relationship for $\\text{CO}_2$ and a slightly less complicated Antoine's Law relationship for $\\text{H}_2\\text{O}$:" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,CO2]*(exp(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O])*log(244800.0*exp(-1348*K/fs.unit.liquid_phase.properties_out[0.0].temperature)*(3520000.0*exp(-2113*K/fs.unit.liquid_phase.properties_out[0.0].temperature)/(8449000.0*exp(-2283*K/fs.unit.liquid_phase.properties_out[0.0].temperature)))) + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O])*log(3520000.0*exp(-2113*K/fs.unit.liquid_phase.properties_out[0.0].temperature)) + fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O])*(fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]))*(fs.liquid_properties.CO2.lwm_coeff_1 + K**(-1)*fs.liquid_properties.CO2.lwm_coeff_2*(fs.unit.liquid_phase.properties_out[0.0].temperature - 273.15*K) + K**(-2)*fs.liquid_properties.CO2.lwm_coeff_3*(fs.unit.liquid_phase.properties_out[0.0].temperature - 273.15*K)**2 + fs.liquid_properties.CO2.lwm_coeff_4*(fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]))))*Pa*m**3*mol**(-1))\n" + ] + } + ], + "source": [ + "print_compact_form(\n", + " m.fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[\"Liq\", \"CO2\"]\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Parsing the entire pile of thermodynamic gibberish is unnecessary to plan our next move. We can plainly see that the liquid phase fugacity expression is rife with subtraction and exponentiation, both of which are dangerous for the nominal value expression walker. Even worse, we are scaling based on a failed solution, so the values may be off anyway. It is far better to base the scaling factor on the vapor phase fugacity. The `get_expression_nominal_value` function allows the user to get the nominal value of a single expression." + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "10000.0" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "reboiler_scaler.get_expression_nominal_value(\n", + " m.fs.unit.vapor_phase[0.0].fug_phase_comp[\"Vap\", \"CO2\"]\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "While in this case this value is positive, the nominal value can be negative, so you should use the absolute value when getting a scaling factor.\n", + "\n", + "Finally, we have the last constraint: mechanical equilibrium between phases.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "fs.unit.liquid_phase.properties_out[0.0].pressure == fs.unit.vapor_phase[0.0].pressure\n" + ] + } + ], + "source": [ + "print_compact_form(m.fs.unit.unit_pressure_balance[0.0])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The `inverseMinimum` scheme will work here as well.\n", + "\n", + "In addition to these problematic unit model level constraints, there are some additional constraints that need scaling factors. Although they might not be problematic under these process conditions, they may be for a scaled-up flowsheet. If we suspect they are well-scaled already, we should use the `report_scaling_factors` function to show what they are:" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Scaling Factors for block fs.unit\n", + "\n", + "Variable Scaling Factor Value Scaled Value\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol 1.250E-02 8.389E+01 1.049E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[H2O] 1.000E+01 8.589E-01 8.589E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[MEA] 1.000E+01 1.085E-01 1.085E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[CO2] 1.000E+01 3.260E-02 3.260E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].temperature 3.333E-03 3.925E+02 1.308E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol 1.250E-02 7.424E+01 9.279E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O] 1.000E+01 8.527E-01 8.527E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] 1.000E+01 1.226E-01 1.226E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[CO2] 1.000E+01 2.471E-02 2.471E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].temperature 3.333E-03 3.926E+02 1.309E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", + "fs.unit.vapor_phase[0.0].flow_mol 1.000E-01 9.654E+00 9.654E-01\n", + "fs.unit.vapor_phase[0.0].mole_frac_comp[CO2] 1.000E+01 9.329E-02 9.329E-01\n", + "fs.unit.vapor_phase[0.0].mole_frac_comp[H2O] 1.000E+01 9.067E-01 9.067E+00\n", + "fs.unit.vapor_phase[0.0].mole_frac_comp[N2] 1.000E+01 1.055E-09 1.055E-08\n", + "fs.unit.vapor_phase[0.0].mole_frac_comp[O2] 1.000E+01 1.055E-09 1.055E-08\n", + "fs.unit.vapor_phase[0.0].temperature 3.333E-03 3.926E+02 1.309E+00\n", + "fs.unit.vapor_phase[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", + "fs.unit.liquid_phase.heat[0.0] 5.077E-07 4.306E+05 2.186E-01\n", + "\n", + "Constraint Scaling Factor\n", + "fs.unit.unit_material_balance[0.0,CO2] None\n", + "fs.unit.unit_material_balance[0.0,H2O] None\n", + "fs.unit.unit_material_balance[0.0,N2] None\n", + "fs.unit.unit_material_balance[0.0,O2] None\n", + "fs.unit.unit_material_balance[0.0,MEA] None\n", + "fs.unit.unit_phase_equilibrium[0.0,CO2] None\n", + "fs.unit.unit_phase_equilibrium[0.0,H2O] None\n", + "fs.unit.unit_temperature_equality[0.0] None\n", + "fs.unit.unit_enthalpy_balance[0.0] None\n", + "fs.unit.unit_pressure_balance[0.0] None\n" + ] + } + ], + "source": [ + "from idaes.core.scaling.util import report_scaling_factors\n", + "\n", + "report_scaling_factors(m.fs.unit, descend_into=False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We have yet to scale the `unit_temperature_equality` and `unit_material_balance`constraints. The temperature equality constraint is simple." + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "fs.unit.liquid_phase.properties_out[0.0].temperature == fs.unit.vapor_phase[0.0].temperature\n" + ] + } + ], + "source": [ + "print_compact_form(m.fs.unit.unit_temperature_equality[0.0])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "`inverseMinimum` works fine here.\n", + "\n", + "The material balance constraints have different forms depending on whether a component occurs in the liquid phase, the vapor phase, or both:" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "- fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,CO2] == fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,CO2]\n", + "\n", + "\n", + "fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,MEA] == 0*(mol*s**(-1))\n", + "\n", + "\n", + "fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,N2] == fs.unit.zero_flow_param\n" + ] + } + ], + "source": [ + "print_compact_form(m.fs.unit.unit_material_balance[0.0, \"CO2\"])\n", + "print(\"\\n\")\n", + "print_compact_form(m.fs.unit.unit_material_balance[0.0, \"MEA\"])\n", + "print(\"\\n\")\n", + "print_compact_form(m.fs.unit.unit_material_balance[0.0, \"N2\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The first constraint equates the vapor flow rate to the mass transfer from the liquid phase. Either inverse maximum or inverse minimum would work. The next two are a bit trickier. For $\\text{MEA}$, which is considered nonvolatile in this property package, there is no mass transfer to the vapor phase. A common misconception is that variables should always be scaled to be order one. That is incorrect. We only need to calculate `mass_transfer_term[0.0,\"Liq\",\"MEA\"]` to the same precision as the other (nonzero) terms of the mass balance (and the `ControlVolume0D` submodel scaler does just that). Similarly, `flow_mol_phase_comp[\"Vap\",\"N2\"]` is set to a tiny nonzero value (because flows that are exactly zero often cause problems for property calculations). We do not need more significant figures for either of those variables than the rest of the terms in their correspoding material balances. Therefore we want to use the `inverseMaximum` becuase `inverseMinimum` would demand unnecessary precision.\n", + "\n", + "
\n", + "NOTE\n", + "\n", + "If we had relied on autoscaling methods to fill in scaling factors for these variables and constraints, we would have ended up with enormous scaling factors for `flow_mol_phase_comp[\"Vap\",\"N2\"]` and `flow_mol_phase_comp[\"Vap\",\"O2\"]` because they are not-quite equal to zero at the model solution.\n", + "\n", + "Similarly, `m.fs.unit.unit_phase_equilibrium[0.0,\"CO2\"]` would have been overscaled due to the enormous nominal value given by the expression walker for the liquid phase fugacity\n", + "\n", + "
\n", + "\n", + "Finally, we can complete the scaler object." + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [], + "source": [ + "from idaes.core.scaling.custom_scaler_base import ConstraintScalingScheme\n", + "\n", + "\n", + "class SolventReboilerScaler(CustomScalerBase):\n", + " def variable_scaling_routine(\n", + " self, model, overwrite: bool = False, submodel_scalers: dict = None\n", + " ):\n", + " # Call scaling methods for sub-models\n", + " self.call_submodel_scaler_method(\n", + " submodel=model.liquid_phase,\n", + " method=\"variable_scaling_routine\",\n", + " submodel_scalers=submodel_scalers,\n", + " overwrite=overwrite,\n", + " )\n", + "\n", + " self.call_submodel_scaler_method(\n", + " submodel=model.vapor_phase,\n", + " method=\"variable_scaling_routine\",\n", + " submodel_scalers=submodel_scalers,\n", + " overwrite=overwrite,\n", + " )\n", + "\n", + " def constraint_scaling_routine(\n", + " self, model, overwrite: bool = False, submodel_scalers: dict = None\n", + " ):\n", + " # Call scaling methods for sub-models\n", + " self.call_submodel_scaler_method(\n", + " submodel=model.liquid_phase,\n", + " method=\"constraint_scaling_routine\",\n", + " submodel_scalers=submodel_scalers,\n", + " overwrite=overwrite,\n", + " )\n", + "\n", + " self.call_submodel_scaler_method(\n", + " submodel=model.vapor_phase,\n", + " method=\"constraint_scaling_routine\",\n", + " submodel_scalers=submodel_scalers,\n", + " overwrite=overwrite,\n", + " )\n", + " # Note: scaling factors cannot be applied directly to indexed objects.\n", + " # They should be applied to VarData/ConstraintData/ExpressionData children instead.\n", + " for condata in model.unit_material_balance.values():\n", + " self.scale_constraint_by_nominal_value(\n", + " condata,\n", + " scheme=ConstraintScalingScheme.inverseMaximum,\n", + " overwrite=overwrite,\n", + " )\n", + " for condata in model.unit_temperature_equality.values():\n", + " self.scale_constraint_by_nominal_value(\n", + " condata,\n", + " scheme=ConstraintScalingScheme.inverseMinimum,\n", + " overwrite=overwrite,\n", + " )\n", + " for condata in model.unit_enthalpy_balance.values():\n", + " self.scale_constraint_by_nominal_value(\n", + " condata,\n", + " scheme=ConstraintScalingScheme.inverseMinimum,\n", + " overwrite=overwrite,\n", + " )\n", + " for condata in model.unit_pressure_balance.values():\n", + " self.scale_constraint_by_nominal_value(\n", + " condata,\n", + " scheme=ConstraintScalingScheme.inverseMinimum,\n", + " overwrite=overwrite,\n", + " )\n", + " for (t, j), condata in m.fs.unit.unit_phase_equilibrium.items():\n", + " nom = abs(\n", + " self.get_expression_nominal_value(\n", + " m.fs.unit.vapor_phase[t].fug_phase_comp[\"Vap\", j]\n", + " )\n", + " )\n", + " self.set_constraint_scaling_factor(condata, 1 / nom, overwrite=overwrite)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can see how this works on the model. We'll pass `overwrite=True` config option when creating the scaler object to ensure we have up-to-date scaling factors." + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Starting initialization routine\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Bubble, dew, and critical point initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Equilibrium temperature initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: State variable initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Phase equilibrium initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Property initialization routine finished.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Starting initialization routine\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Bubble, dew, and critical point initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Equilibrium temperature initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: State variable initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Phase equilibrium initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Property initialization routine finished.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: Starting initialization routine\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: Bubble, dew, and critical point initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: Equilibrium temperature initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: State variable initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: Phase equilibrium initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: Property initialization routine finished.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit: Initialization Complete: optimal - \n" + ] + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "scaler_obj = SolventReboilerScaler(overwrite=True)\n", + "scaler_obj.scale_model(m.fs.unit)\n", + "reboiler_init.initialize(m.fs.unit)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We see that scaling improved the model enough so that initialization could succeed. Now let's look at the numerical issues." + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "====================================================================================\n", + "Model Statistics\n", + "\n", + " Jacobian Condition Number: 5.400E+06\n", + "\n", + "------------------------------------------------------------------------------------\n", + "0 WARNINGS\n", + "\n", + " No warnings found!\n", + "\n", + "------------------------------------------------------------------------------------\n", + "6 Cautions\n", + "\n", + " Caution: 9 Variables with value close to their bounds (abs=1.0E-04, rel=1.0E-04)\n", + " Caution: 14 Variables with value close to zero (tol=1.0E-08)\n", + " Caution: 27 Variables with extreme value (<1.0E-04 or >1.0E+04)\n", + " Caution: 2 Constraints with mismatched terms\n", + " Caution: 1 Constraint with potential cancellation of terms\n", + " Caution: 20 extreme Jacobian Entries (<1.0E-04 or >1.0E+04)\n", + "\n", + "------------------------------------------------------------------------------------\n", + "Suggested next steps:\n", + "\n", + " If you still have issues converging your model consider:\n", + "\n", + " prepare_degeneracy_hunter()\n", + " prepare_svd_toolbox()\n", + "\n", + "====================================================================================\n" + ] + } + ], + "source": [ + "dt = DiagnosticsToolbox(m)\n", + "dt.report_numerical_issues()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We have reduced the Jacobian condition number by another four orders of magnitude, as well as eliminating all extreme Jacobian rows and columns. A condition number of $5\\cdot 10^6$ is still higher than we'd like for a single unit model, especially for a simple unit model like this one, because connecting units together as part of a flowsheet inevitably increases the condition number. \n", + "\n", + "## Step 6: Singular Value Decomposition\n", + "\n", + "With no more extreme Jacobian rows or columns, we have two avenues to proceed:\n", + "1. Check the extreme Jacobian *entries*\n", + "2. Check the singular value decomposition (SVD) of the Jacobian\n", + "\n", + "Extreme Jacobian entries only *suggest* that the variable and constraint might be contributing to ill-conditioning\u2014they might also be false positives. However, extreme singular values are *guaranteed* to be contributing to the Jacobian's ill-conditioning. Therefore, we will look at the SVD next.\n", + "\n", + "The singular value decomposition factorizes a matrix into three parts:\n", + "$$\n", + "\\mathbf{J} = \\mathbf{U \\Sigma V}^T\n", + "$$\n", + "Both $\\mathbf{U}$ and $\\mathbf{V}$ are orthogonal matrices, i.e., $\\mathbf{U}^T \\mathbf{U} = \\mathbf{I}$ and $\\mathbf{V}^T\\mathbf{V} = \\mathbf{I}$. If $\\mathbf{J}$ is square, then $\\mathbf{\\Sigma}$ is a diagonal matrix of the form:\n", + "$$\n", + "\\mathbf{\\Sigma} = \\begin{bmatrix}\n", + " \\sigma_1 & 0 & \\dots & 0 \\\\\n", + " 0 & \\sigma_2 & \\dots & 0 \\\\\n", + " \\vdots & \\vdots & \\ddots & \\vdots\\\\\n", + " 0 & 0 & \\dots & \\sigma_n\n", + " \\end{bmatrix}\n", + "$$\n", + "in which $\\sigma_j$ are the singular values. The singular values are arranged in descending order, i.e., $\\sigma_{j+1} \\leq \\sigma_{j}$. If any $\\sigma_j=0$, then the matrix is singular.\n", + "\n", + "The condition number is given by:\n", + "$$\n", + "\\kappa(\\mathbf{J}) = \\sigma_1 / \\sigma_n\n", + "$$\n", + "Thus, extremely large and extremely small singular values cause matrix ill-conditioning. However, extremely large singular values typically show up as rows and columns with extreme norms. Therefore we will look at the smallest singular values.\n", + "\n", + "Because $\\mathbf{U}$ and $\\mathbf{V}$ are orthogonal and $\\mathbf{\\Sigma}$ is diagonal, computing a Newton step is easy once the SVD is calculated.\n", + "$$\n", + "\\mathbf{\\delta x}_k = -\\mathbf{V \\Sigma^{-1} U}^T \\cdot \\mathbf{f}(\\mathbf{x}_k)\n", + "$$\n", + "Since we have to refactorize $\\mathbf{J}$ at each iteration, the SVD is not an efficient method to calculate a Newton step. However, this process has a geometric interpretation that is useful for model diagnostics and scaling. First, the constraint residual is decomposed into orthogonal components by $\\mathbf{U}$:\n", + "$$\n", + "\\mathbf{s} = -\\mathbf{U}^T \\cdot \\mathbf{f}(\\mathbf{x}_k)\n", + "$$\n", + "Next, these orthogonal components are scaled by the inverse of the associated singular value:\n", + "$$\n", + "\\mathbf{\\tilde{s}} = \\Sigma^{-1} \\cdot \\mathbf{s}\n", + "$$\n", + "Finally, these independent components are translated into the variable space by $\\mathbf{V}$:\n", + "$$\n", + "\\mathbf{\\delta x}_k = \\mathbf{V} \\cdot \\mathbf{\\tilde{s}}\n", + "$$\n", + "So each orthogonal component of the constraint residual space is associated with an orthogonal component of the variable space. In particular, each singular value $\\sigma_j$ is associated with a left singular vector $\\mathbf{u}_j$ and right singular vector $\\mathbf{v}_j$, the $j\\text{th}$ columns of $\\mathbf{U}$ and $\\mathbf{V}$, respectively. Any constraint error in the direction of $\\mathbf{u}_j$ *must* be satisfied by a corresponding change in the direction of $\\mathbf{v}_j$. When $\\sigma_j$ is extremely small, tiny changes in the direction of $\\mathbf{u}_j$ translate into enormous changes in $\\mathbf{v}_j$. This dysfunctional relationship can be a sign of bad scaling, but also can be a sign of some other model issue like numerical singularity. Typically, singular values in the range $10^{-12}$ to $10^{-4}$ are signs of either bad scaling or a highly sensitive model (for example, a flowsheet with a large recycle stream). Values below $10^{-12}$ are indicative of numerical singularity.\n", + "\n", + "
\n", + "NOTE\n", + "\n", + "The singular vectors $\\mathbf{u}_j$ and $\\mathbf{v}_j$ are typically dense. In order to link them with specific variables and constraints, a thresholding scheme is applied. The `size_cutoff_in_singular_vector` config option for the `SVDToolbox` controls the magnitude of an entry in $\\mathbf{u}_j$ and $\\mathbf{v}_j$ that is sufficient to link a variable or constraint to the $\\sigma_j$. It is `0.1` by default, but can take on values between about `0.05` and `0.3`. Decrease it to show fewer variables and constraints, increase it to show more variables and constraints.\n", + "\n", + "
\n", + "\n", + "So let's create an instance of the `SVDToolbox` and display the variables and constraints associated with the 5 smallest singular values.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "====================================================================================\n", + "Constraints and Variables associated with smallest singular values\n", + "\n", + " 1st Smallest Singular Value: 6.356e-04\n", + "\n", + " Variables:\n", + "\n", + " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_comp[CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_comp[H2O]\n", + "\n", + " Constraints:\n", + "\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2]\n", + "\n", + " 2nd Smallest Singular Value: 2.781e-02\n", + "\n", + " Variables:\n", + "\n", + " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_comp[CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_comp[H2O]\n", + "\n", + " Constraints:\n", + "\n", + " fs.unit.unit_material_balance[0.0,CO2]\n", + " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", + "\n", + " 3rd Smallest Singular Value: 3.679e-02\n", + "\n", + " Variables:\n", + "\n", + " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_comp[CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_comp[H2O]\n", + "\n", + " Constraints:\n", + "\n", + " fs.unit.unit_material_balance[0.0,CO2]\n", + " fs.unit.liquid_phase.material_balances[0.0,MEA]\n", + " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", + " fs.unit.liquid_phase.enthalpy_balances[0.0]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", + " fs.unit.unit_material_balance[0.0,MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,HCO3_-]\n", + " fs.unit.vapor_phase[0.0].sum_mole_frac_out\n", + "\n", + " 4th Smallest Singular Value: 6.842e-02\n", + "\n", + " Variables:\n", + "\n", + " fs.unit.vapor_phase[0.0].flow_mol_phase[Vap]\n", + " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,H2O]\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]\n", + " fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,H2O]\n", + " fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,H2O]\n", + " fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,H2O]\n", + " fs.unit.vapor_phase[0.0].mole_frac_comp[H2O]\n", + " fs.unit.vapor_phase[0.0].flow_mol\n", + "\n", + " Constraints:\n", + "\n", + " fs.unit.unit_material_balance[0.0,CO2]\n", + " fs.unit.liquid_phase.material_balances[0.0,MEA]\n", + " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", + " fs.unit.liquid_phase.enthalpy_balances[0.0]\n", + " fs.unit.unit_material_balance[0.0,MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].total_flow_balance\n", + " fs.unit.vapor_phase[0.0].sum_mole_frac_out\n", + "\n", + " 5th Smallest Singular Value: 7.703e-02\n", + "\n", + " Variables:\n", + "\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,H2O]\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]\n", + " fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,H2O]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_k_eq[bicarbonate]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_k_eq[carbamate]\n", + "\n", + " Constraints:\n", + "\n", + " fs.unit.liquid_phase.material_balances[0.0,MEA]\n", + " fs.unit.unit_material_balance[0.0,MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].total_flow_balance\n", + " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[MEA]\n", + " fs.unit.liquid_phase.properties_out[0.0].sum_mole_frac_out\n", + "\n", + "====================================================================================\n" + ] + } + ], + "source": [ + "st = dt.prepare_svd_toolbox()\n", + "# The SVD toolbox displays 10 singular values by default, but we are going to\n", + "# view the only the first five to reduce the amount of output.\n", + "st.display_underdetermined_variables_and_constraints(singular_values=[1, 2, 3, 4, 5])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The smallest singular value is 40 times smaller than the second smallest singular value. This usually means that we can significantly improve the matrix conditioning by scaling only a small number of variables and constraints. There is only one constraint strongly associated with the smallest singular value, so let's start with that." + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "exp(fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]) == fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,CO2]/(mol/m**3)\n" + ] + } + ], + "source": [ + "print_compact_form(\n", + " m.fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[\n", + " \"Liq\", \"CO2\"\n", + " ]\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This constraint converts between the $\\text{CO}_2$ concentration and its logarithm. Using these sorts of log-form variables can increase the number of significant digits when dealing with reactions involving components in small quantities. (They can also introduce degeneracy when dealing with trace quantities that *do not* appear in reactions.)\n", + "\n", + "The SVD Toolbox also has two helper functions: `display_variables_in_constraint`, which displays the Jacobian row corresponding to a constraint, and `display_constraints_including_variable`, which displays the Jacobian column corresponding to a variable." + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "====================================================================================\n", + "The following variables are involved in fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2]:\n", + "\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,H2O]: 4.333e-05\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,MEA]: 1.441e-04\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,CO2]: 6.126e-05\n", + " fs.unit.liquid_phase.properties_out[0.0].temperature: 1.576e-04\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]: -5.255e-07\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA]: 5.123e-06\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,CO2]: -1.648e+00\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]: 5.621e-04\n", + "\n", + "====================================================================================\n" + ] + } + ], + "source": [ + "st.display_variables_in_constraint(\n", + " m.fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[\n", + " \"Liq\", \"CO2\"\n", + " ]\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "NOTE\n", + "\n", + "At this point of the process, the original author found a shortcoming in the `ModularPropertiesScaler`. No scaling hint was set for the molar density expression, so the expression walker descended into it and came back with an inappropriate nominal value. Revising the scaler to estimate the phase density resulted in a condition number improvement of 1-2 orders of magnitude.\n", + "\n", + "Remember:\n", + "1. Scaling is an iterative process.\n", + "2. Submodel scalers may need to be revised to fix scaling issues.\n", + "3. Using the expression walker in an expression tree that involves subtraction or exponential functions is dangerous.\n", + "
\n", + "\n", + "From our knowledge of the physical properties, `mole_frac_phase_comp_true[\"Liq\",\"CO2\"]` and `log_conc_mol_phase_comp_true[\"Liq\",\"CO2\"]` should have the largest effects on this equation. The other variables affect the concentration indirectly through the phase density. But while `mole_frac_phase_comp_true[\"Liq\",\"CO2\"]` does have an appropriately-sized impact, `log_conc_mol_phase_comp_true[\"Liq\",\"CO2\"]` is several orders-of-magnitude too small. A naive approach might be to decrease the scaling factor on `log_conc_mol_phase_comp_true[\"Liq\",\"CO2\"]` until it has an appropriately-sized effect in the equation. Remember, though, that log variables are well-scaled by default. Something else must be wrong.\n", + "\n", + "Let's take a look at the values on both sides of the equation." + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Left hand side value: 1.3698e+00\n", + "CO2 true concentration value: 1.3698e+00\n" + ] + } + ], + "source": [ + "print(\n", + " f\"Left hand side value: {value(exp(m.fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[\"Liq\",\"CO2\"])):.4e}\"\n", + ")\n", + "print(\n", + " f\"CO2 true concentration value: {value(m.fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[\"Liq\",\"CO2\"]):.4e}\"\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Since the left hand side and right hand side both have values of order one, we expect the equation to have a similar scaling factor." + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.0004103666666666667\n" + ] + } + ], + "source": [ + "print(\n", + " get_scaling_factor(\n", + " (\n", + " m.fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[\n", + " \"Liq\", \"CO2\"\n", + " ]\n", + " )\n", + " )\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "However, it actually has an extremely small scaling factor. To what can we attribute this?\n", + "\n", + "It is a result of not setting good default values for the true species mole fractions in the liquid phase. Although the apparent $\\text{CO}_2$ mole fraction is about 0.03, almost all of that is in the form of a carbamate salt formed through reaction with $\\text{MEA}$. The true mole fraction is significantly lower." + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True CO2 mole fraction: 3.410357e-05\n", + "True MEACOO- mole fraction: 2.796223e-02\n" + ] + } + ], + "source": [ + "print(\n", + " f\"True CO2 mole fraction: {m.fs.unit.liquid_phase.properties_out[0].mole_frac_phase_comp_true[\"Liq\",\"CO2\"].value:4e}\"\n", + ")\n", + "print(\n", + " f\"True MEACOO- mole fraction: {m.fs.unit.liquid_phase.properties_out[0].mole_frac_phase_comp_true[\"Liq\",\"MEACOO_-\"].value:4e}\"\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Nevertheless, the true value of the $\\text{CO}_2$ mole fraction is important because it is used in the calculation of fugacity. It should therefore be assigned a larger scaling factor. Therefore, let's revisit the default scaling factors for the liquid properties:" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": {}, + "outputs": [], + "source": [ + "default_scaling_factors = (\n", + " m.fs.liquid_properties.default_state_scaler_object.default_scaling_factors\n", + ")\n", + "# Dictionaries are mutable, so changing its value here also changes it on the scaler object\n", + "# First scale the apparent mole fractions\n", + "default_scaling_factors[\"mole_frac_phase_comp[Liq, H2O]\"] = 1\n", + "default_scaling_factors[\"mole_frac_phase_comp[Liq, CO2]\"] = 10\n", + "default_scaling_factors[\"mole_frac_phase_comp[Liq, MEA]\"] = 10\n", + "# Next scale the true mole fractions\n", + "default_scaling_factors[\"mole_frac_phase_comp_true[Liq, H2O]\"] = 1\n", + "default_scaling_factors[\"mole_frac_phase_comp_true[Liq, CO2]\"] = 1e4\n", + "default_scaling_factors[\"mole_frac_phase_comp_true[Liq, MEA]\"] = 10\n", + "default_scaling_factors[\"mole_frac_phase_comp_true[Liq, MEA_+]\"] = 10\n", + "default_scaling_factors[\"mole_frac_phase_comp_true[Liq, MEACOO_-]\"] = 10\n", + "default_scaling_factors[\"mole_frac_phase_comp_true[Liq, HCO3_-]\"] = 100" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "With these new scaling factors, let's rescale and resolve the mode, then check the new condition number." + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Starting initialization routine\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Bubble, dew, and critical point initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Equilibrium temperature initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: State variable initialization completed.\n", + "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Phase equilibrium initialization completed.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Property initialization routine finished.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Starting initialization routine\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Bubble, dew, and critical point initialization completed.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Equilibrium temperature initialization completed.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: State variable initialization completed.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Phase equilibrium initialization completed.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Property initialization routine finished.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: Starting initialization routine\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: Bubble, dew, and critical point initialization completed.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: Equilibrium temperature initialization completed.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: State variable initialization completed.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: Phase equilibrium initialization completed.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: Property initialization routine finished.\n", + "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit: Initialization Complete: optimal - \n", + "====================================================================================\n", + "Model Statistics\n", + "\n", + " Jacobian Condition Number: 2.945E+05\n", + "\n", + "------------------------------------------------------------------------------------\n", + "0 WARNINGS\n", + "\n", + " No warnings found!\n", + "\n", + "------------------------------------------------------------------------------------\n", + "6 Cautions\n", + "\n", + " Caution: 9 Variables with value close to their bounds (abs=1.0E-04, rel=1.0E-04)\n", + " Caution: 14 Variables with value close to zero (tol=1.0E-08)\n", + " Caution: 27 Variables with extreme value (<1.0E-04 or >1.0E+04)\n", + " Caution: 2 Constraints with mismatched terms\n", + " Caution: 1 Constraint with potential cancellation of terms\n", + " Caution: 16 extreme Jacobian Entries (<1.0E-04 or >1.0E+04)\n", + "\n", + "------------------------------------------------------------------------------------\n", + "Suggested next steps:\n", + "\n", + " If you still have issues converging your model consider:\n", + "\n", + " prepare_degeneracy_hunter()\n", + " prepare_svd_toolbox()\n", + "\n", + "====================================================================================\n" + ] + } + ], + "source": [ + "scaler_obj = SolventReboilerScaler(overwrite=True)\n", + "scaler_obj.scale_model(m.fs.unit)\n", + "reboiler_init.initialize(m.fs.unit)\n", + "dt = DiagnosticsToolbox(m)\n", + "dt.report_numerical_issues()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The condition number decreased by a factor of 18, which is less than what we might have hoped for. Let's check out the SVD toolbox again." + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "====================================================================================\n", + "Constraints and Variables associated with smallest singular values\n", + "\n", + " 1st Smallest Singular Value: 6.965e-04\n", + "\n", + " Variables:\n", + "\n", + " fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[bicarbonate]\n", + " fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[carbamate]\n", + " fs.unit.liquid_phase.properties_out[0.0].apparent_inherent_reaction_extent[carbamate]\n", + "\n", + " Constraints:\n", + "\n", + " fs.unit.unit_material_balance[0.0,CO2]\n", + " fs.unit.unit_material_balance[0.0,H2O]\n", + " fs.unit.liquid_phase.material_balances[0.0,H2O]\n", + " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].total_flow_balance\n", + " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", + "\n", + " 2nd Smallest Singular Value: 1.047e-03\n", + "\n", + " Variables:\n", + "\n", + " fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[carbamate]\n", + " fs.unit.liquid_phase.properties_out[0.0].apparent_inherent_reaction_extent[carbamate]\n", + "\n", + " Constraints:\n", + "\n", + " fs.unit.unit_material_balance[0.0,CO2]\n", + " fs.unit.unit_material_balance[0.0,H2O]\n", + " fs.unit.liquid_phase.material_balances[0.0,H2O]\n", + " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEA_+]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA_+]\n", + "\n", + " 3rd Smallest Singular Value: 4.024e-03\n", + "\n", + " Variables:\n", + "\n", + " fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[bicarbonate]\n", + " fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[carbamate]\n", + "\n", + " Constraints:\n", + "\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,H2O]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,H2O]\n", + " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,H2O]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", + "\n", + " 4th Smallest Singular Value: 5.218e-03\n", + "\n", + " Variables:\n", + "\n", + " fs.unit.liquid_phase.properties_out[0.0].apparent_inherent_reaction_extent[bicarbonate]\n", + "\n", + " Constraints:\n", + "\n", + " fs.unit.unit_material_balance[0.0,CO2]\n", + " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,HCO3_-]\n", + "\n", + " 5th Smallest Singular Value: 5.115e-02\n", + "\n", + " Variables:\n", + "\n", + " fs.unit.vapor_phase[0.0].flow_mol_phase[Vap]\n", + " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]\n", + " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_comp[CO2]\n", + " fs.unit.vapor_phase[0.0].mole_frac_comp[H2O]\n", + " fs.unit.vapor_phase[0.0].flow_mol\n", + "\n", + " Constraints:\n", + "\n", + " fs.unit.unit_material_balance[0.0,CO2]\n", + " fs.unit.unit_material_balance[0.0,H2O]\n", + " fs.unit.liquid_phase.material_balances[0.0,H2O]\n", + " fs.unit.liquid_phase.material_balances[0.0,MEA]\n", + " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", + " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEA_+]\n", + " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEA]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA_+]\n", + " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA]\n", + " fs.unit.unit_material_balance[0.0,MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_in[0.0].total_flow_balance\n", + " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[MEA]\n", + " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEACOO_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,HCO3_-]\n", + " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA_+]\n", + " fs.unit.liquid_phase.properties_out[0.0].sum_mole_frac_out\n", + " fs.unit.vapor_phase[0.0].sum_mole_frac_out\n", + "\n", + "====================================================================================\n" + ] + } + ], + "source": [ + "st = dt.prepare_svd_toolbox()\n", + "st.display_underdetermined_variables_and_constraints([1, 2, 3, 4, 5])" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": {}, + "outputs": [], + "source": [ + "assert st.s[0] == pytest.approx(6.965e-04, rel=1e-2)\n", + "assert st.s[3] == pytest.approx(5.218e-03, rel=1e-2)\n", + "assert st.s[4] == pytest.approx(5.115e-02, rel=1e-2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can see an order-of-magnitude difference between the first four smallest singular values and the fifth-smallest singular value. Inspecting the variables and constraints involved, they all involve the inherent reaction calculations for ionic speciation. Improving the scaling of those variables and constraints might improve the condition number by another one to two orders of magnitude. However, we are reaching the point of diminishing returns for scaling. We can leave the scaler here unless a solver failure forces us to revisit it again.\n", + "\n", + "## Step 7: Reviewing Model Scaling\n", + "\n", + "Before we conclude entirely, let's take a look at all the variable and constraint scaling factors used." + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Scaling Factors for block fs.unit\n", + "\n", + "Variable Scaling Factor Value Scaled Value\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol 1.250E-02 8.389E+01 1.049E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[H2O] 1.000E+00 8.589E-01 8.589E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[MEA] 1.000E+01 1.085E-01 1.085E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[CO2] 1.000E+01 3.260E-02 3.260E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].temperature 3.333E-03 3.925E+02 1.308E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol 1.250E-02 7.410E+01 9.263E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O] 1.000E+00 8.487E-01 8.487E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] 1.000E+01 1.228E-01 1.228E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[CO2] 1.000E+01 2.851E-02 2.851E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].temperature 3.333E-03 3.938E+02 1.313E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", + "fs.unit.vapor_phase[0.0].flow_mol 1.000E-01 9.785E+00 9.785E-01\n", + "fs.unit.vapor_phase[0.0].mole_frac_comp[CO2] 1.000E+01 6.361E-02 6.361E-01\n", + "fs.unit.vapor_phase[0.0].mole_frac_comp[H2O] 1.000E+01 9.364E-01 9.364E+00\n", + "fs.unit.vapor_phase[0.0].mole_frac_comp[N2] 1.000E+01 1.022E-09 1.022E-08\n", + "fs.unit.vapor_phase[0.0].mole_frac_comp[O2] 1.000E+01 1.022E-09 1.022E-08\n", + "fs.unit.vapor_phase[0.0].temperature 3.333E-03 3.938E+02 1.313E+00\n", + "fs.unit.vapor_phase[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", + "fs.unit.liquid_phase.heat[0.0] 8.763E-07 4.306E+05 3.773E-01\n", + "fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,H2O] 1.250E-02 -9.163E+00 -1.145E-01\n", + "fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,MEA] 1.250E-01 0.000E+00 0.000E+00\n", + "fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,CO2] 1.250E-01 -6.224E-01 -7.780E-02\n", + "fs.unit.liquid_phase.enthalpy_transfer[0.0] 8.763E-07 -3.209E+04 -2.812E-02\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase[Liq] 1.250E-02 8.389E+01 1.049E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp[Liq,H2O] 1.000E+00 8.589E-01 8.589E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp[Liq,MEA] 1.000E+01 1.085E-01 1.085E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp[Liq,CO2] 1.000E+01 3.260E-02 3.260E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].phase_frac[Liq] 1.000E+00 1.000E+00 1.000E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,MEACOO_-] 1.250E-01 2.550E+00 3.187E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,HCO3_-] 1.250E+00 1.785E-01 2.231E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,MEA_+] 1.250E-01 2.728E+00 3.410E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,H2O] 1.250E-02 7.187E+01 8.984E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,MEA] 1.250E-01 3.825E+00 4.781E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,CO2] 1.250E+02 6.803E-03 8.504E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,MEACOO_-] 1.000E+01 3.141E-02 3.141E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,HCO3_-] 1.000E+02 2.199E-03 2.199E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,MEA_+] 1.000E+01 3.361E-02 3.361E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,H2O] 1.000E+00 8.856E-01 8.856E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,MEA] 1.000E+01 4.712E-02 4.712E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,CO2] 1.000E+04 8.383E-05 8.383E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[bicarbonate] 1.250E+02 1.785E-01 2.231E+01\n", + "fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[carbamate] 1.250E+02 2.550E+00 3.187E+02\n", + "fs.unit.liquid_phase.properties_in[0.0].log_k_eq[bicarbonate] None -7.578E+00 -7.578E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].log_k_eq[carbamate] None -1.985E+00 -1.985E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-] 1.000E+00 7.168E+00 7.168E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-] 1.000E+00 4.509E+00 4.509E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+] 1.000E+00 7.236E+00 7.236E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,H2O] 1.000E+00 1.051E+01 1.051E+01\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEA] 1.000E+00 7.573E+00 7.573E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,CO2] 1.000E+00 1.242E+00 1.242E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase[Liq] 1.250E-02 7.410E+01 9.263E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,H2O] 1.000E+00 8.487E-01 8.487E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,MEA] 1.000E+01 1.228E-01 1.228E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,CO2] 1.000E+01 2.851E-02 2.851E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].phase_frac[Liq] 1.000E+00 1.000E+00 1.000E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,MEACOO_-] 1.250E-01 2.013E+00 2.516E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,HCO3_-] 1.250E+00 9.684E-02 1.210E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,MEA_+] 1.250E-01 2.110E+00 2.637E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,H2O] 1.250E-02 6.279E+01 7.849E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,MEA] 1.250E-01 4.979E+00 6.224E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,CO2] 1.250E+02 2.455E-03 3.069E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,MEACOO_-] 1.000E+01 2.796E-02 2.796E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,HCO3_-] 1.000E+02 1.345E-03 1.345E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,MEA_+] 1.000E+01 2.931E-02 2.931E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,H2O] 1.000E+00 8.722E-01 8.722E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,MEA] 1.000E+01 6.916E-02 6.916E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,CO2] 1.000E+04 3.410E-05 3.410E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].apparent_inherent_reaction_extent[bicarbonate] 1.250E+02 9.684E-02 1.210E+01\n", + "fs.unit.liquid_phase.properties_out[0.0].apparent_inherent_reaction_extent[carbamate] 1.250E+02 2.013E+00 2.516E+02\n", + "fs.unit.liquid_phase.properties_out[0.0].log_k_eq[bicarbonate] None -7.648E+00 -7.648E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].log_k_eq[carbamate] None -2.079E+00 -2.079E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-] 1.000E+00 7.024E+00 7.024E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-] 1.000E+00 3.989E+00 3.989E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+] 1.000E+00 7.071E+00 7.071E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,H2O] 1.000E+00 1.046E+01 1.046E+01\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA] 1.000E+00 7.929E+00 7.929E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2] 1.000E+00 3.147E-01 3.147E-01\n", + "fs.unit.vapor_phase[0.0].flow_mol_phase[Vap] 1.000E-01 9.785E+00 9.785E-01\n", + "fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2] 1.000E+01 6.361E-02 6.361E-01\n", + "fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O] 1.000E+01 9.364E-01 9.364E+00\n", + "fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,N2] 1.000E+01 1.022E-09 1.022E-08\n", + "fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,O2] 1.000E+01 1.022E-09 1.022E-08\n", + "fs.unit.vapor_phase[0.0].phase_frac[Vap] 1.000E+00 1.000E+00 1.000E+00\n", + "\n", + "Constraint Scaling Factor\n", + "fs.unit.unit_material_balance[0.0,CO2] 1.250E-01\n", + "fs.unit.unit_material_balance[0.0,H2O] 1.250E-02\n", + "fs.unit.unit_material_balance[0.0,N2] 1.000E+00\n", + "fs.unit.unit_material_balance[0.0,O2] 1.000E+00\n", + "fs.unit.unit_material_balance[0.0,MEA] 1.250E-01\n", + "fs.unit.unit_phase_equilibrium[0.0,CO2] 1.000E-04\n", + "fs.unit.unit_phase_equilibrium[0.0,H2O] 1.000E-04\n", + "fs.unit.unit_temperature_equality[0.0] 3.333E-03\n", + "fs.unit.unit_enthalpy_balance[0.0] 5.463E-06\n", + "fs.unit.unit_pressure_balance[0.0] 1.000E-05\n", + "fs.unit.liquid_phase.material_balances[0.0,H2O] 1.250E-02\n", + "fs.unit.liquid_phase.material_balances[0.0,MEA] 1.250E-01\n", + "fs.unit.liquid_phase.material_balances[0.0,CO2] 1.250E-01\n", + "fs.unit.liquid_phase.enthalpy_balances[0.0] 8.763E-07\n", + "fs.unit.liquid_phase.pressure_balance[0.0] 1.000E-05\n", + "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEACOO_-] 1.250E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,HCO3_-] 1.250E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEA_+] 1.250E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,H2O] 1.250E-02\n", + "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEA] 1.250E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2] 1.250E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEACOO_-] 1.250E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,HCO3_-] 1.250E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEA_+] 1.250E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,H2O] 1.250E-02\n", + "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEA] 1.250E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,CO2] 1.250E+02\n", + "fs.unit.liquid_phase.properties_in[0.0].total_flow_balance 1.250E-02\n", + "fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[H2O] 1.000E+01\n", + "fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[MEA] 1.000E+01\n", + "fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2] 1.000E+01\n", + "fs.unit.liquid_phase.properties_in[0.0].phase_fraction_constraint[Liq] 1.000E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].log_k_eq_constraint[bicarbonate] None\n", + "fs.unit.liquid_phase.properties_in[0.0].log_k_eq_constraint[carbamate] None\n", + "fs.unit.liquid_phase.properties_in[0.0].inherent_equilibrium_constraint[bicarbonate] 1.000E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].inherent_equilibrium_constraint[carbamate] 1.000E+00\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-] 2.377E-04\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-] 2.377E-03\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA_+] 2.377E-04\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,H2O] 2.377E-05\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA] 2.377E-04\n", + "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2] 2.377E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEACOO_-] 1.250E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,HCO3_-] 1.250E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA_+] 1.250E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,H2O] 1.250E-02\n", + "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA] 1.250E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2] 1.250E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEACOO_-] 1.250E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,HCO3_-] 1.250E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEA_+] 1.250E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,H2O] 1.250E-02\n", + "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEA] 1.250E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,CO2] 1.250E+02\n", + "fs.unit.liquid_phase.properties_out[0.0].sum_mole_frac_out 1.000E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].total_flow_balance 1.250E-02\n", + "fs.unit.liquid_phase.properties_out[0.0].component_flow_balances[H2O] 1.000E+01\n", + "fs.unit.liquid_phase.properties_out[0.0].component_flow_balances[MEA] 1.000E+01\n", + "fs.unit.liquid_phase.properties_out[0.0].component_flow_balances[CO2] 1.000E+01\n", + "fs.unit.liquid_phase.properties_out[0.0].phase_fraction_constraint[Liq] 1.000E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].log_k_eq_constraint[bicarbonate] None\n", + "fs.unit.liquid_phase.properties_out[0.0].log_k_eq_constraint[carbamate] None\n", + "fs.unit.liquid_phase.properties_out[0.0].inherent_equilibrium_constraint[bicarbonate] 1.000E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].inherent_equilibrium_constraint[carbamate] 1.000E+00\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-] 2.377E-04\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-] 2.377E-03\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA_+] 2.377E-04\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,H2O] 2.377E-05\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA] 2.377E-04\n", + "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2] 2.377E-01\n", + "fs.unit.vapor_phase[0.0].sum_mole_frac_out 1.000E+00\n", + "fs.unit.vapor_phase[0.0].total_flow_balance 1.000E-01\n", + "fs.unit.vapor_phase[0.0].component_flow_balances[CO2] 1.000E+01\n", + "fs.unit.vapor_phase[0.0].component_flow_balances[H2O] 1.000E+01\n", + "fs.unit.vapor_phase[0.0].component_flow_balances[N2] 1.000E+01\n", + "fs.unit.vapor_phase[0.0].component_flow_balances[O2] 1.000E+01\n", + "fs.unit.vapor_phase[0.0].phase_fraction_constraint[Vap] 1.000E+00\n", + "\n", + "Expression Scaling Hint\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp[Liq,H2O] 1.250E-02\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp[Liq,MEA] 1.250E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp[Liq,CO2] 1.250E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].k_eq[bicarbonate] None\n", + "fs.unit.liquid_phase.properties_in[0.0].k_eq[carbamate] None\n", + "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,MEACOO_-] None\n", + "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,HCO3_-] None\n", + "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,MEA_+] None\n", + "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,H2O] None\n", + "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,MEA] None\n", + "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,CO2] None\n", + "fs.unit.liquid_phase.properties_in[0.0].dens_mol_phase[Liq] 2.377E-05\n", + "fs.unit.liquid_phase.properties_in[0.0].vol_mol_phase[Liq] 4.206E+04\n", + "fs.unit.liquid_phase.properties_in[0.0]._enthalpy_flow_term[Liq] None\n", + "fs.unit.liquid_phase.properties_in[0.0].enth_mol_phase[Liq] 7.010E-05\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_comp[H2O] 1.250E-02\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_comp[MEA] 1.250E-01\n", + "fs.unit.liquid_phase.properties_in[0.0].flow_mol_comp[CO2] 1.250E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp[Liq,H2O] 1.250E-02\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp[Liq,MEA] 1.250E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp[Liq,CO2] 1.250E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].k_eq[bicarbonate] None\n", + "fs.unit.liquid_phase.properties_out[0.0].k_eq[carbamate] None\n", + "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,MEACOO_-] None\n", + "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,HCO3_-] None\n", + "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,MEA_+] None\n", + "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,H2O] None\n", + "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,MEA] None\n", + "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,CO2] None\n", + "fs.unit.liquid_phase.properties_out[0.0].dens_mol_phase[Liq] 2.377E-05\n", + "fs.unit.liquid_phase.properties_out[0.0].vol_mol_phase[Liq] 4.206E+04\n", + "fs.unit.liquid_phase.properties_out[0.0]._enthalpy_flow_term[Liq] None\n", + "fs.unit.liquid_phase.properties_out[0.0].enth_mol_phase[Liq] 7.010E-05\n", + "fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[Liq,H2O] None\n", + "fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[Liq,MEA] None\n", + "fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[Liq,CO2] None\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_comp[H2O] 1.250E-02\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_comp[MEA] 1.250E-01\n", + "fs.unit.liquid_phase.properties_out[0.0].flow_mol_comp[CO2] 1.250E-01\n", + "fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,CO2] 1.000E+00\n", + "fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,H2O] 1.000E+00\n", + "fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,N2] 1.000E+00\n", + "fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,O2] 1.000E+00\n", + "fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,CO2] None\n", + "fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,H2O] None\n", + "fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,N2] None\n", + "fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,O2] None\n", + "fs.unit.vapor_phase[0.0]._enthalpy_flow_term[Vap] None\n", + "fs.unit.vapor_phase[0.0].enth_mol_phase[Vap] 5.463E-05\n", + "fs.unit.vapor_phase[0.0].enth_mol_phase_comp[Vap,CO2] 3.787E-05\n", + "fs.unit.vapor_phase[0.0].enth_mol_phase_comp[Vap,H2O] 9.249E-05\n", + "fs.unit.vapor_phase[0.0].enth_mol_phase_comp[Vap,N2] 5.950E-05\n", + "fs.unit.vapor_phase[0.0].enth_mol_phase_comp[Vap,O2] 5.208E-05\n", + "fs.unit.vapor_phase[0.0].flow_mol_comp[CO2] 1.000E+00\n", + "fs.unit.vapor_phase[0.0].flow_mol_comp[H2O] 1.000E+00\n", + "fs.unit.vapor_phase[0.0].flow_mol_comp[N2] 1.000E+00\n", + "fs.unit.vapor_phase[0.0].flow_mol_comp[O2] 1.000E+00\n" + ] + } + ], + "source": [ + "from idaes.core.scaling.util import report_scaling_factors\n", + "\n", + "report_scaling_factors(m.fs.unit, descend_into=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Most variable values have scaled values within a couple orders of magnitude of one, which is what we like. The outliers are inherent reaction extents, which we already know are a bit problematic, and variables corresponding to the components $\\text{N}_2$ and $\\text{O}_2$, which are present in the vapor property package but not the vapor stream.\n", + "\n", + "We have reduced the condition number to $3 \\cdot 10^5$, which is not quite as low as we would have liked, but is a vast improvement over the value $3 \\cdot 10^{13}$, which we started out with. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# References\n", + "\n", + "[[1](https://doi.org/10.1016/j.compchemeng.2025.109312)] Allan, D. A., Ostace, A. G., & Polley, T. (2025). Jacobian-based model diagnostics and application to equation oriented modeling of a carbon capture system. Computers & Chemical Engineering, 109312.\n", + "\n", + "[[2](https://link.springer.com/article/10.1007/S10107-004-0559-Y)] W\u00e4chter, A., & Biegler, L. T. (2006). On the implementation of an interior-point filter line-search algorithm for large-scale nonlinear programming. Mathematical programming, 106(1), 25-57." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.12" + } + }, + "nbformat": 4, + "nbformat_minor": 3 +} \ No newline at end of file From 4832140a07d5518cd6e2e44a76a6729f8614f955 Mon Sep 17 00:00:00 2001 From: Doug A Date: Wed, 29 Apr 2026 17:36:08 -0400 Subject: [PATCH 5/7] spelling errors --- .../notebooks/docs/scaling/advanced_scaling_techniques.ipynb | 2 +- .../docs/scaling/advanced_scaling_techniques_doc.ipynb | 2 +- .../docs/scaling/advanced_scaling_techniques_test.ipynb | 2 +- .../docs/scaling/advanced_scaling_techniques_usr.ipynb | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques.ipynb b/idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques.ipynb index e5d61ff0..2a7d87d4 100644 --- a/idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques.ipynb +++ b/idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques.ipynb @@ -2039,7 +2039,7 @@ "id": "b1fc2994-0a80-4530-816a-76e025c49706", "metadata": {}, "source": [ - "The first constraint equates the vapor flow rate to the mass transfer from the liquid phase. Either inverse maximum or inverse minimum would work. The next two are a bit trickier. For $\\text{MEA}$, which is considered nonvolatile in this property package, there is no mass transfer to the vapor phase. A common misconception is that variables should always be scaled to be order one. That is incorrect. We only need to calculate `mass_transfer_term[0.0,\"Liq\",\"MEA\"]` to the same precision as the other (nonzero) terms of the mass balance (and the `ControlVolume0D` submodel scaler does just that). Similarly, `flow_mol_phase_comp[\"Vap\",\"N2\"]` is set to a tiny nonzero value (because flows that are exactly zero often cause problems for property calculations). We do not need more significant figures for either of those variables than the rest of the terms in their correspoding material balances. Therefore we want to use the `inverseMaximum` becuase `inverseMinimum` would demand unnecessary precision.\n", + "The first constraint equates the vapor flow rate to the mass transfer from the liquid phase. Either inverse maximum or inverse minimum would work. The next two are a bit trickier. For $\\text{MEA}$, which is considered nonvolatile in this property package, there is no mass transfer to the vapor phase. A common misconception is that variables should always be scaled to be order one. That is incorrect. We only need to calculate `mass_transfer_term[0.0,\"Liq\",\"MEA\"]` to the same precision as the other (nonzero) terms of the mass balance (and the `ControlVolume0D` submodel scaler does just that). Similarly, `flow_mol_phase_comp[\"Vap\",\"N2\"]` is set to a tiny nonzero value (because flows that are exactly zero often cause problems for property calculations). We do not need more significant figures for either of those variables than the rest of the terms in their corresponding material balances. Therefore we want to use the `inverseMaximum` because `inverseMinimum` would demand unnecessary precision.\n", "\n", "
\n", "NOTE\n", diff --git a/idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques_doc.ipynb b/idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques_doc.ipynb index 693c14b1..f7000025 100644 --- a/idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques_doc.ipynb +++ b/idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques_doc.ipynb @@ -1921,7 +1921,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "The first constraint equates the vapor flow rate to the mass transfer from the liquid phase. Either inverse maximum or inverse minimum would work. The next two are a bit trickier. For $\\text{MEA}$, which is considered nonvolatile in this property package, there is no mass transfer to the vapor phase. A common misconception is that variables should always be scaled to be order one. That is incorrect. We only need to calculate `mass_transfer_term[0.0,\"Liq\",\"MEA\"]` to the same precision as the other (nonzero) terms of the mass balance (and the `ControlVolume0D` submodel scaler does just that). Similarly, `flow_mol_phase_comp[\"Vap\",\"N2\"]` is set to a tiny nonzero value (because flows that are exactly zero often cause problems for property calculations). We do not need more significant figures for either of those variables than the rest of the terms in their correspoding material balances. Therefore we want to use the `inverseMaximum` becuase `inverseMinimum` would demand unnecessary precision.\n", + "The first constraint equates the vapor flow rate to the mass transfer from the liquid phase. Either inverse maximum or inverse minimum would work. The next two are a bit trickier. For $\\text{MEA}$, which is considered nonvolatile in this property package, there is no mass transfer to the vapor phase. A common misconception is that variables should always be scaled to be order one. That is incorrect. We only need to calculate `mass_transfer_term[0.0,\"Liq\",\"MEA\"]` to the same precision as the other (nonzero) terms of the mass balance (and the `ControlVolume0D` submodel scaler does just that). Similarly, `flow_mol_phase_comp[\"Vap\",\"N2\"]` is set to a tiny nonzero value (because flows that are exactly zero often cause problems for property calculations). We do not need more significant figures for either of those variables than the rest of the terms in their corresponding material balances. Therefore we want to use the `inverseMaximum` because `inverseMinimum` would demand unnecessary precision.\n", "\n", "
\n", "NOTE\n", diff --git a/idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques_test.ipynb b/idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques_test.ipynb index bc14bdac..615d4087 100644 --- a/idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques_test.ipynb +++ b/idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques_test.ipynb @@ -1976,7 +1976,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "The first constraint equates the vapor flow rate to the mass transfer from the liquid phase. Either inverse maximum or inverse minimum would work. The next two are a bit trickier. For $\\text{MEA}$, which is considered nonvolatile in this property package, there is no mass transfer to the vapor phase. A common misconception is that variables should always be scaled to be order one. That is incorrect. We only need to calculate `mass_transfer_term[0.0,\"Liq\",\"MEA\"]` to the same precision as the other (nonzero) terms of the mass balance (and the `ControlVolume0D` submodel scaler does just that). Similarly, `flow_mol_phase_comp[\"Vap\",\"N2\"]` is set to a tiny nonzero value (because flows that are exactly zero often cause problems for property calculations). We do not need more significant figures for either of those variables than the rest of the terms in their correspoding material balances. Therefore we want to use the `inverseMaximum` becuase `inverseMinimum` would demand unnecessary precision.\n", + "The first constraint equates the vapor flow rate to the mass transfer from the liquid phase. Either inverse maximum or inverse minimum would work. The next two are a bit trickier. For $\\text{MEA}$, which is considered nonvolatile in this property package, there is no mass transfer to the vapor phase. A common misconception is that variables should always be scaled to be order one. That is incorrect. We only need to calculate `mass_transfer_term[0.0,\"Liq\",\"MEA\"]` to the same precision as the other (nonzero) terms of the mass balance (and the `ControlVolume0D` submodel scaler does just that). Similarly, `flow_mol_phase_comp[\"Vap\",\"N2\"]` is set to a tiny nonzero value (because flows that are exactly zero often cause problems for property calculations). We do not need more significant figures for either of those variables than the rest of the terms in their corresponding material balances. Therefore we want to use the `inverseMaximum` because `inverseMinimum` would demand unnecessary precision.\n", "\n", "
\n", "NOTE\n", diff --git a/idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques_usr.ipynb b/idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques_usr.ipynb index 693c14b1..f7000025 100644 --- a/idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques_usr.ipynb +++ b/idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques_usr.ipynb @@ -1921,7 +1921,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "The first constraint equates the vapor flow rate to the mass transfer from the liquid phase. Either inverse maximum or inverse minimum would work. The next two are a bit trickier. For $\\text{MEA}$, which is considered nonvolatile in this property package, there is no mass transfer to the vapor phase. A common misconception is that variables should always be scaled to be order one. That is incorrect. We only need to calculate `mass_transfer_term[0.0,\"Liq\",\"MEA\"]` to the same precision as the other (nonzero) terms of the mass balance (and the `ControlVolume0D` submodel scaler does just that). Similarly, `flow_mol_phase_comp[\"Vap\",\"N2\"]` is set to a tiny nonzero value (because flows that are exactly zero often cause problems for property calculations). We do not need more significant figures for either of those variables than the rest of the terms in their correspoding material balances. Therefore we want to use the `inverseMaximum` becuase `inverseMinimum` would demand unnecessary precision.\n", + "The first constraint equates the vapor flow rate to the mass transfer from the liquid phase. Either inverse maximum or inverse minimum would work. The next two are a bit trickier. For $\\text{MEA}$, which is considered nonvolatile in this property package, there is no mass transfer to the vapor phase. A common misconception is that variables should always be scaled to be order one. That is incorrect. We only need to calculate `mass_transfer_term[0.0,\"Liq\",\"MEA\"]` to the same precision as the other (nonzero) terms of the mass balance (and the `ControlVolume0D` submodel scaler does just that). Similarly, `flow_mol_phase_comp[\"Vap\",\"N2\"]` is set to a tiny nonzero value (because flows that are exactly zero often cause problems for property calculations). We do not need more significant figures for either of those variables than the rest of the terms in their corresponding material balances. Therefore we want to use the `inverseMaximum` because `inverseMinimum` would demand unnecessary precision.\n", "\n", "
\n", "NOTE\n", From 13a8f5b81eba28dc77b27b9751ed77e2922fd1d8 Mon Sep 17 00:00:00 2001 From: Doug A Date: Thu, 30 Apr 2026 13:51:42 -0400 Subject: [PATCH 6/7] hyperlinks and cached values --- .../scaling/advanced_scaling_techniques.ipynb | 1940 ++-------------- .../advanced_scaling_techniques_doc.ipynb | 1965 ++-------------- .../advanced_scaling_techniques_test.ipynb | 1995 ++--------------- .../advanced_scaling_techniques_usr.ipynb | 1965 ++-------------- 4 files changed, 851 insertions(+), 7014 deletions(-) diff --git a/idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques.ipynb b/idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques.ipynb index 2a7d87d4..78c111fb 100644 --- a/idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques.ipynb +++ b/idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "id": "4a1d7eaf-e297-436e-bb48-e65d1fdcd7f6", "metadata": {}, "outputs": [], @@ -34,533 +34,29 @@ "\n", "## Introduction\n", "\n", - "This notebook is intended to give the user further insight into how the scaling toolbox can be used to improve robustness. A large portion of the material is an adaptation of [Allan, Ostace, and Polly (2025)](#references). By the end of this study, the user should understand:\n", + "This notebook is intended to give the user further insight into how the scaling toolbox can be used to improve robustness. It is a followup to a [previous notebook](./scaler_workshop.ipynb) about how to create scaler objects in IDAES, and it assumes some familiarity with the material contained therein. A large portion of the material is an adaptation of [Allan, Ostace, and Polly (2025)](#references). By the end of this study, the user should understand:\n", "* How a default scaler object can be specified for a property package\n", "* How to set default scaling factors for property package variables\n", + "* How to use the `DiagnosticsToolbox` to troubleshoot saling issues\n", "* The strengths and weaknesses of the ``NominalValueExpressionWalker`` used in ``CustomScalerBase.get_sum_terms_nominal_values`` and ``CustomScalerBase.get_expression_nominal_value`` for use in constraint scaling\n", "* How to use the ``SVDToolbox`` to troubleshoot scaling issues\n", "\n", "## Step 1: Set Up Test Case\n", - "We will use the `SolventReboiler` unit model as a case study. It is a component in a stripping column used for solvent regeneration. It is modeled as a single equilibrium stage with an external heat duty. The inlet stream is entirely liquid, while it has both boilup and bottoms outlet streams. The liquid and vapor phases use different configurations of the modular property framework.\n", + "We will use the `SolventReboiler` unit model as a case study. It is a component in a stripping column used for solvent regeneration. It is modeled as a single equilibrium stage with an external heat duty. The inlet stream is entirely liquid, while it has both boilup and bottoms outlet streams. The liquid and vapor phases use different configurations of the [modular property framework](https://idaes-pse.readthedocs.io/en/latest/explanations/components/property_package/general/index.html).\n", "\n", "First, we set up and attempt to initialize the unit model." ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "id": "e9e198c2-800e-48ac-b67c-8223a19abf96", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2026-04-29 17:11:54 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Starting initialization routine\n", - "2026-04-29 17:11:54 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Bubble, dew, and critical point initialization completed.\n", - "2026-04-29 17:11:54 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Equilibrium temperature initialization completed.\n", - "2026-04-29 17:11:54 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: State variable initialization completed.\n", - "2026-04-29 17:11:54 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Phase equilibrium initialization completed.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Ipopt 3.13.2: linear_solver=\"ma57\"\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: max_iter=200\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: nlp_scaling_method=\"gradient-based\"\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: tol=1e-06\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: ******************************************************************************\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: For more information visit http://projects.coin-or.org/Ipopt\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: This version of Ipopt was compiled from source code available at\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: for large-scale scientific computation. All technical papers, sales and\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: publicity material resulting from use of the HSL codes within IPOPT must\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: contain the following acknowledgement:\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: HSL, a collection of Fortran codes for large-scale scientific\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: computation. See http://www.hsl.rl.ac.uk.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: ******************************************************************************\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of nonzeros in equality constraint Jacobian...: 74\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of nonzeros in inequality constraint Jacobian.: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of nonzeros in Lagrangian Hessian.............: 42\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Total number of variables............................: 18\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: variables with only lower bounds: 6\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: variables with lower and upper bounds: 12\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: variables with only upper bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Total number of equality constraints.................: 18\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Total number of inequality constraints...............: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: inequality constraints with only lower bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: inequality constraints with lower and upper bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: inequality constraints with only upper bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 0 0.0000000e+00 4.13e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Reallocating memory for MA57: lfact (1377)\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 1 0.0000000e+00 4.05e+02 1.89e+12 -1.0 6.07e+01 - 1.92e-01 1.98e-02H 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 2 0.0000000e+00 1.62e+04 1.56e+17 -1.0 8.76e+01 - 1.69e-01 5.07e-01H 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 3 0.0000000e+00 1.62e+04 1.55e+17 -1.0 4.59e+01 - 1.21e-07 3.23e-03H 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 4 0.0000000e+00 2.15e+04 1.93e+17 -1.0 4.88e+01 - 1.06e-02 9.12e-01h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Reallocating memory for MA57: lfact (1542)\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 5 0.0000000e+00 2.15e+04 1.93e+17 -1.0 3.05e+02 - 4.08e-04 6.58e-04h 2\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Reallocating memory for MA57: lfact (1662)\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 6 0.0000000e+00 2.09e+04 1.87e+17 -1.0 1.11e+01 - 4.04e-03 3.08e-02h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 7 0.0000000e+00 1.50e+04 1.37e+17 -1.0 1.37e+01 - 1.44e-04 3.14e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 8 0.0000000e+00 1.49e+04 1.36e+17 -1.0 4.21e+00 - 5.37e-01 9.11e-03h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 9 0.0000000e+00 1.49e+04 1.36e+17 -1.0 4.10e+00 - 9.86e-01 9.35e-05h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 10r 0.0000000e+00 1.49e+04 1.00e+03 1.6 0.00e+00 - 0.00e+00 4.68e-07R 2\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 11r 0.0000000e+00 5.25e+03 2.22e+03 1.6 3.13e+04 - 3.88e-03 1.14e-03f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 12r 0.0000000e+00 5.08e+03 4.24e+04 1.6 1.22e+03 - 1.88e-01 5.18e-03f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 13r 0.0000000e+00 4.77e+03 3.36e+04 1.6 6.27e+01 - 3.06e-02 6.76e-02f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 14r 0.0000000e+00 4.33e+03 1.32e+05 1.6 8.06e+00 - 5.05e-01 9.81e-02f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 15r 0.0000000e+00 4.19e+03 1.12e+05 1.6 9.20e+00 - 3.38e-01 3.25e-02f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 16r 0.0000000e+00 1.89e+03 5.50e+04 1.6 2.54e+00 - 8.42e-02 7.08e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 17r 0.0000000e+00 1.72e+03 4.73e+04 1.6 7.82e+00 - 2.36e-01 1.01e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 18r 0.0000000e+00 1.14e+03 2.84e+04 1.6 1.92e+00 - 7.10e-01 4.02e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 19r 0.0000000e+00 1.06e+03 2.92e+04 1.6 5.12e+00 - 7.85e-01 7.79e-02f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 20r 0.0000000e+00 2.69e+02 3.66e+03 1.6 5.52e-01 - 1.00e+00 9.33e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 21r 0.0000000e+00 1.64e+01 3.96e+02 0.9 1.63e-01 - 9.76e-01 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 22r 0.0000000e+00 6.87e-01 1.09e+02 0.2 3.52e-02 - 1.00e+00 9.59e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 23r 0.0000000e+00 2.05e-01 8.47e+03 -0.5 2.72e-03 - 1.00e+00 6.98e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 24r 0.0000000e+00 1.34e-03 2.18e-01 -0.5 1.87e-03 - 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 25r 0.0000000e+00 1.29e-02 1.88e+02 -2.9 3.36e-04 - 1.00e+00 9.47e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 26r 0.0000000e+00 2.90e-06 4.04e-05 -2.9 7.48e-05 - 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of Iterations....: 26\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: (scaled) (unscaled)\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Constraint violation....: 2.1131334015933589e-08 2.8957967970200116e-06\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Overall NLP error.......: 2.1131334015933589e-08 2.8957967970200116e-06\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of objective function evaluations = 34\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of objective gradient evaluations = 12\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of equality constraint evaluations = 36\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of inequality constraint evaluations = 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of equality constraint Jacobian evaluations = 28\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of inequality constraint Jacobian evaluations = 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of Lagrangian Hessian evaluations = 26\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Total CPU secs in IPOPT (w/o function evaluations) = 0.006\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Total CPU secs in NLP function evaluations = 0.000\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: EXIT: Optimal Solution Found.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Property initialization routine finished.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Starting initialization routine\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Bubble, dew, and critical point initialization completed.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Equilibrium temperature initialization completed.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: State variable initialization completed.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Phase equilibrium initialization completed.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Ipopt 3.13.2: linear_solver=\"ma57\"\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: max_iter=200\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: nlp_scaling_method=\"gradient-based\"\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: tol=1e-06\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: ******************************************************************************\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: For more information visit http://projects.coin-or.org/Ipopt\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: This version of Ipopt was compiled from source code available at\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: for large-scale scientific computation. All technical papers, sales and\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: publicity material resulting from use of the HSL codes within IPOPT must\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: contain the following acknowledgement:\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: HSL, a collection of Fortran codes for large-scale scientific\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: computation. See http://www.hsl.rl.ac.uk.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: ******************************************************************************\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of nonzeros in equality constraint Jacobian...: 74\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of nonzeros in inequality constraint Jacobian.: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of nonzeros in Lagrangian Hessian.............: 42\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Total number of variables............................: 18\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: variables with only lower bounds: 6\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: variables with lower and upper bounds: 12\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: variables with only upper bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Total number of equality constraints.................: 18\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Total number of inequality constraints...............: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: inequality constraints with only lower bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: inequality constraints with lower and upper bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: inequality constraints with only upper bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 0 0.0000000e+00 4.13e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Reallocating memory for MA57: lfact (1377)\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 1 0.0000000e+00 4.05e+02 1.89e+12 -1.0 6.07e+01 - 1.92e-01 1.98e-02H 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 2 0.0000000e+00 1.62e+04 1.56e+17 -1.0 8.76e+01 - 1.69e-01 5.07e-01H 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 3 0.0000000e+00 1.62e+04 1.55e+17 -1.0 4.59e+01 - 1.21e-07 3.23e-03H 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 4 0.0000000e+00 2.15e+04 1.93e+17 -1.0 4.88e+01 - 1.06e-02 9.12e-01h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Reallocating memory for MA57: lfact (1542)\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 5 0.0000000e+00 2.15e+04 1.93e+17 -1.0 3.05e+02 - 4.08e-04 6.58e-04h 2\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Reallocating memory for MA57: lfact (1662)\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 6 0.0000000e+00 2.09e+04 1.87e+17 -1.0 1.11e+01 - 4.04e-03 3.08e-02h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 7 0.0000000e+00 1.50e+04 1.37e+17 -1.0 1.37e+01 - 1.44e-04 3.14e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 8 0.0000000e+00 1.49e+04 1.36e+17 -1.0 4.21e+00 - 5.37e-01 9.11e-03h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 9 0.0000000e+00 1.49e+04 1.36e+17 -1.0 4.10e+00 - 9.86e-01 9.35e-05h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 10r 0.0000000e+00 1.49e+04 1.00e+03 1.6 0.00e+00 - 0.00e+00 4.68e-07R 2\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 11r 0.0000000e+00 5.25e+03 2.22e+03 1.6 3.13e+04 - 3.88e-03 1.14e-03f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 12r 0.0000000e+00 5.08e+03 4.24e+04 1.6 1.22e+03 - 1.88e-01 5.18e-03f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 13r 0.0000000e+00 4.77e+03 3.36e+04 1.6 6.27e+01 - 3.06e-02 6.76e-02f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 14r 0.0000000e+00 4.33e+03 1.32e+05 1.6 8.06e+00 - 5.05e-01 9.81e-02f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 15r 0.0000000e+00 4.19e+03 1.12e+05 1.6 9.20e+00 - 3.38e-01 3.25e-02f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 16r 0.0000000e+00 1.89e+03 5.50e+04 1.6 2.54e+00 - 8.42e-02 7.08e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 17r 0.0000000e+00 1.72e+03 4.73e+04 1.6 7.82e+00 - 2.36e-01 1.01e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 18r 0.0000000e+00 1.14e+03 2.84e+04 1.6 1.92e+00 - 7.10e-01 4.02e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 19r 0.0000000e+00 1.06e+03 2.92e+04 1.6 5.12e+00 - 7.85e-01 7.79e-02f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 20r 0.0000000e+00 2.69e+02 3.66e+03 1.6 5.52e-01 - 1.00e+00 9.33e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 21r 0.0000000e+00 1.64e+01 3.96e+02 0.9 1.63e-01 - 9.76e-01 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 22r 0.0000000e+00 6.87e-01 1.09e+02 0.2 3.52e-02 - 1.00e+00 9.59e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 23r 0.0000000e+00 2.05e-01 8.47e+03 -0.5 2.72e-03 - 1.00e+00 6.98e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 24r 0.0000000e+00 1.34e-03 2.18e-01 -0.5 1.87e-03 - 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 25r 0.0000000e+00 1.29e-02 1.88e+02 -2.9 3.36e-04 - 1.00e+00 9.47e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 26r 0.0000000e+00 2.90e-06 4.04e-05 -2.9 7.48e-05 - 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of Iterations....: 26\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: (scaled) (unscaled)\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Constraint violation....: 2.1131334015933589e-08 2.8957967970200116e-06\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Overall NLP error.......: 2.1131334015933589e-08 2.8957967970200116e-06\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of objective function evaluations = 34\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of objective gradient evaluations = 12\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of equality constraint evaluations = 36\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of inequality constraint evaluations = 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of equality constraint Jacobian evaluations = 28\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of inequality constraint Jacobian evaluations = 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of Lagrangian Hessian evaluations = 26\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Total CPU secs in IPOPT (w/o function evaluations) = 0.008\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Total CPU secs in NLP function evaluations = 0.000\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: EXIT: Optimal Solution Found.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Property initialization routine finished.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase: Control volume properties initialization complete\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase: Control volume reactions initialization complete\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit: Initialization Step 1 Complete.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: Starting initialization routine\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: Bubble, dew, and critical point initialization completed.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: Equilibrium temperature initialization completed.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: State variable initialization completed.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: Phase equilibrium initialization completed.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: Property initialization routine finished.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit: Initialization Step 2 Complete.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Ipopt 3.13.2: linear_solver=\"ma57\"\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: max_iter=200\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: nlp_scaling_method=\"gradient-based\"\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: tol=1e-06\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: ******************************************************************************\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: For more information visit http://projects.coin-or.org/Ipopt\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: This version of Ipopt was compiled from source code available at\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: for large-scale scientific computation. All technical papers, sales and\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: publicity material resulting from use of the HSL codes within IPOPT must\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: contain the following acknowledgement:\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: HSL, a collection of Fortran codes for large-scale scientific\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: computation. See http://www.hsl.rl.ac.uk.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: ******************************************************************************\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of nonzeros in equality constraint Jacobian...: 231\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of nonzeros in inequality constraint Jacobian.: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of nonzeros in Lagrangian Hessian.............: 149\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Total number of variables............................: 51\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: variables with only lower bounds: 12\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: variables with lower and upper bounds: 34\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: variables with only upper bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Total number of equality constraints.................: 51\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Total number of inequality constraints...............: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: inequality constraints with only lower bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: inequality constraints with lower and upper bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: inequality constraints with only upper bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 0 0.0000000e+00 3.62e+06 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Reallocating memory for MA57: lfact (3323)\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 1 0.0000000e+00 3.00e+06 1.18e+02 -1.0 3.71e+04 - 5.00e-01 1.73e-01h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 2 0.0000000e+00 2.99e+06 3.06e+03 -1.0 2.81e+04 - 8.76e-01 3.30e-03h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 3 0.0000000e+00 2.99e+06 8.95e+07 -1.0 2.80e+04 - 9.79e-01 3.34e-05h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 4r 0.0000000e+00 2.99e+06 1.00e+03 1.9 0.00e+00 - 0.00e+00 1.74e-07R 2\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 5r 0.0000000e+00 2.93e+06 9.98e+02 1.9 3.19e+04 - 2.43e-03 2.43e-03f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 6r 0.0000000e+00 2.86e+06 1.02e+03 1.2 3.69e+02 - 3.26e-01 2.09e-03f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 7r 0.0000000e+00 2.23e+06 1.04e+03 1.2 2.85e+02 - 1.93e-01 8.65e-02f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 8r 0.0000000e+00 1.90e+06 1.12e+05 1.2 2.94e+02 - 7.31e-02 2.42e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 9r 0.0000000e+00 1.44e+06 7.08e+04 1.2 1.51e+02 - 7.79e-01 2.13e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 10r 0.0000000e+00 1.21e+06 3.79e+04 1.2 1.60e+00 2.0 4.46e-01 1.46e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 11r 0.0000000e+00 7.63e+04 1.14e+04 1.2 9.97e+01 - 3.46e-01 9.00e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 12r 0.0000000e+00 4.57e+04 2.79e+04 1.2 8.49e+01 - 1.00e+00 2.61e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 13r 0.0000000e+00 5.79e+04 9.55e+03 1.2 3.35e+01 - 1.00e+00 7.44e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 14r 0.0000000e+00 1.21e+05 1.45e+04 1.2 2.11e+01 - 1.00e+00 1.00e+00h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 15r 0.0000000e+00 2.24e+05 6.34e+02 1.2 7.86e+00 - 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 16r 0.0000000e+00 2.19e+05 4.22e+03 0.5 1.77e+00 - 1.00e+00 9.43e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 17r 0.0000000e+00 3.93e+05 6.53e+02 0.5 1.02e+02 - 5.02e-01 4.46e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 18r 0.0000000e+00 4.24e+05 4.17e+03 0.5 1.55e+01 - 1.00e+00 2.17e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 19r 0.0000000e+00 4.87e+05 1.47e+01 0.5 7.37e+00 - 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 20r 0.0000000e+00 5.23e+05 2.31e+03 -0.9 1.53e+00 - 9.40e-01 7.50e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 21r 0.0000000e+00 5.39e+05 7.30e+03 -0.9 2.08e+02 - 8.07e-01 3.86e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 22r 0.0000000e+00 5.39e+05 5.05e+03 -0.9 1.37e+02 - 1.00e+00 4.43e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 23r 0.0000000e+00 5.38e+05 7.93e+00 -0.9 7.27e+01 - 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 24r 0.0000000e+00 5.39e+05 1.75e-03 -0.9 2.41e-01 - 1.00e+00 1.00e+00h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 25r 0.0000000e+00 5.44e+05 2.59e+01 -3.6 3.79e+00 - 9.90e-01 9.73e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 26r 0.0000000e+00 4.44e+05 3.73e+02 -3.6 6.08e+03 - 7.62e-02 6.44e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 27r 0.0000000e+00 3.34e+05 7.09e+02 -3.6 2.85e+03 - 5.42e-02 9.37e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 28r 0.0000000e+00 2.87e+03 9.51e+02 -3.6 1.42e+03 - 1.73e-01 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 29r 0.0000000e+00 8.65e+04 2.35e+02 -3.6 1.10e+03 - 1.00e+00 1.00e+00H 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 30r 0.0000000e+00 8.28e+04 4.88e-01 -3.6 1.19e+02 - 1.00e+00 1.00e+00h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 31r 0.0000000e+00 8.28e+04 9.25e-05 -3.6 2.69e-01 - 1.00e+00 1.00e+00h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 32r 0.0000000e+00 8.28e+04 2.10e+00 -5.4 5.64e-02 - 1.00e+00 9.70e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 33r 0.0000000e+00 8.28e+04 2.49e+02 -5.4 1.00e-03 1.5 8.85e-01 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 34r 0.0000000e+00 8.27e+04 3.33e-02 -5.4 3.00e-03 1.0 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 35r 0.0000000e+00 8.27e+04 3.31e-02 -5.4 8.93e-03 0.6 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 36r 0.0000000e+00 8.26e+04 3.24e-02 -5.4 2.63e-02 0.1 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 37r 0.0000000e+00 8.23e+04 3.06e-02 -5.4 7.43e-02 -0.4 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 38r 0.0000000e+00 8.16e+04 2.59e-02 -5.4 1.89e-01 -0.9 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 39r 0.0000000e+00 8.02e+04 4.92e-02 -5.4 3.67e-01 -1.3 1.00e+00 1.00e+00h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 40r 0.0000000e+00 7.85e+04 6.76e-02 -5.4 1.01e+00 -1.8 1.00e+00 1.00e+00h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 41r 0.0000000e+00 7.76e+04 2.21e-02 -5.4 3.03e+00 -2.3 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 42r 0.0000000e+00 7.73e+04 1.54e-02 -5.4 9.07e+00 -2.8 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 43r 0.0000000e+00 7.69e+04 1.54e-02 -5.4 2.72e+01 -3.2 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 44r 0.0000000e+00 7.57e+04 9.45e-02 -5.4 8.16e+01 -3.7 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 45r 0.0000000e+00 7.21e+04 7.98e-01 -5.4 2.45e+02 -4.2 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 46r 0.0000000e+00 6.17e+04 5.91e+00 -5.4 7.40e+02 -4.7 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 47r 0.0000000e+00 3.69e+04 5.13e+01 -5.4 2.31e+03 -5.2 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 48r 0.0000000e+00 7.15e+04 1.47e+02 -5.4 1.10e+04 -5.6 1.00e+00 2.17e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 49r 0.0000000e+00 7.15e+04 4.98e+02 -5.4 4.07e+03 -5.2 1.00e+00 5.56e-06h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 50r 0.0000000e+00 2.07e+05 4.58e+03 -5.4 2.01e+04 -5.7 4.61e-01 1.75e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 51r 0.0000000e+00 1.19e+06 4.31e+04 -5.4 9.31e+03 -5.3 2.11e-06 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 52r 0.0000000e+00 1.16e+06 3.63e+04 -5.4 1.14e+02 -0.3 4.01e-01 1.23e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 53r 0.0000000e+00 1.16e+06 3.63e+04 -5.4 2.83e+01 0.1 7.36e-01 7.74e-07h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 54r 0.0000000e+00 1.16e+06 3.63e+04 -5.4 3.94e+03 - 1.59e-01 7.41e-06h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 55r 0.0000000e+00 7.95e+05 2.50e+04 -5.4 4.00e+03 - 7.84e-01 3.17e-01h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 56r 0.0000000e+00 3.83e+05 1.19e+04 -5.4 1.69e+03 - 1.35e-05 5.23e-01h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 57r 0.0000000e+00 2.95e+05 9.19e+03 -5.4 9.94e+00 -0.4 5.56e-01 2.31e-01h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 58r 0.0000000e+00 1.29e+04 7.45e+02 -5.4 1.55e+03 - 2.88e-06 1.00e+00h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 59r 0.0000000e+00 1.05e+04 3.57e+00 -5.4 8.95e-02 -0.8 1.00e+00 1.00e+00h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 60r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 7.60e-02 -1.3 1.00e+00 1.00e+00h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 61r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 2.28e-01 -1.8 1.00e+00 2.50e-01h 3\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 62r 0.0000000e+00 1.05e+04 1.03e-02 -5.4 6.84e-01 -2.3 1.00e+00 1.56e-02h 7\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 63r 0.0000000e+00 1.05e+04 3.12e-02 -5.4 2.05e+00 -2.8 1.00e+00 9.77e-04h 11\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 64r 0.0000000e+00 1.05e+04 9.35e-02 -5.4 6.16e+00 -3.2 1.00e+00 1.22e-04h 14\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 65r 0.0000000e+00 1.05e+04 2.81e-01 -5.4 1.85e+01 -3.7 1.00e+00 7.45e-09h 28\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 66r 0.0000000e+00 1.05e+04 8.49e-01 -5.4 5.60e+01 -4.2 1.00e+00 1.86e-09h 30\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 67r 0.0000000e+00 1.05e+04 2.61e+00 -5.4 1.72e+02 -4.7 1.00e+00 1.16e-10h 34\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 68r 0.0000000e+00 1.05e+04 8.40e+00 -5.4 5.54e+02 -5.1 1.00e+00 3.64e-12h 39\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 69r 0.0000000e+00 1.05e+04 8.40e+00 -5.4 2.14e+03 -5.6 0.00e+00 3.59e-18R 58\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 70r 0.0000000e+00 1.05e+04 1.94e+01 -5.4 4.50e+04 -6.1 1.63e-02 1.43e-12f 35\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 71r 0.0000000e+00 1.05e+04 3.85e+01 -5.4 2.54e+03 -5.7 1.00e+00 1.27e-11f 36\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 72r 0.0000000e+00 1.05e+04 1.11e+01 -5.4 7.22e+02 -5.2 9.93e-01 2.91e-11f 36\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 73r 0.0000000e+00 1.05e+04 3.70e+01 -5.4 3.05e+03 -5.7 7.35e-01 1.32e-12f 39\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 74r 0.0000000e+00 1.05e+04 1.25e+01 -5.4 8.27e+02 -5.3 1.00e+00 3.64e-12f 39\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 75r 0.0000000e+00 1.05e+04 3.60e+01 -5.4 3.72e+03 -5.8 5.36e-01 1.35e-13f 42\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 76r 0.0000000e+00 1.05e+04 1.44e+01 -5.4 9.51e+02 -5.3 1.00e+00 1.14e-13f 44\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 77r 0.0000000e+00 1.05e+04 2.35e+01 -5.4 4.61e+03 -5.8 1.64e-01 1.36e-14f 45\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 78r 0.0000000e+00 1.05e+04 1.66e+01 -5.4 1.10e+03 -5.4 1.00e+00 3.55e-15f 49\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 79r 0.0000000e+00 1.05e+04 2.55e+01 -5.4 5.86e+03 -5.9 1.22e-01 3.35e-16f 50\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 80r 0.0000000e+00 2.67e+04 5.84e+01 -5.4 1.27e+03 -5.4 1.00e+00 8.72e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 81r 0.0000000e+00 2.67e+04 2.19e+03 -5.4 1.28e+03 - 4.11e-03 2.62e-05w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 82r 0.0000000e+00 4.42e+04 8.23e+02 -5.4 3.84e+03 -5.9 5.02e-01 4.78e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 83r 0.0000000e+00 1.05e+04 1.92e+01 -5.4 1.21e+04 - 1.00e+00 7.74e-16f 50\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 84r 0.0000000e+00 1.05e+04 2.07e+01 -5.4 1.47e+03 -5.5 4.87e-01 3.33e-16h 52\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 85r 0.0000000e+00 1.05e+04 5.09e+01 -5.4 1.08e+04 -6.0 2.11e-01 1.14e-17f 54\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 86r 0.0000000e+00 1.05e+04 6.78e+01 -5.4 1.72e+03 -5.5 1.00e+00 1.78e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 87r 0.0000000e+00 1.05e+04 1.11e+02 -5.4 1.65e+04 -6.0 4.54e-02 1.86e-18f 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 88r 0.0000000e+00 1.05e+04 2.03e+02 -5.4 2.02e+03 -5.6 1.00e+00 1.52e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 89r 0.0000000e+00 1.05e+04 3.30e+02 -5.4 3.06e+04 -6.1 2.34e-02 1.00e-18f 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 90r 0.0000000e+00 1.05e+04 7.12e+02 -5.4 2.38e+03 -5.7 1.00e+00 1.29e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 91r 0.0000000e+00 1.05e+04 7.29e+02 -5.4 9.01e+04 -6.1 3.00e-04 3.41e-19f 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 92r 0.0000000e+00 1.05e+04 3.99e+01 -5.4 2.95e+03 -5.7 3.70e-01 2.84e-18h 59\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 93r 0.0000000e+00 2.20e+04 3.07e+01 -5.4 7.91e+02 -5.3 1.00e+00 1.00e+00w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 94r 0.0000000e+00 3.01e+04 4.20e+01 -5.4 2.61e+03 -5.8 7.22e-01 2.55e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 95r 0.0000000e+00 3.01e+04 1.37e+03 -5.4 1.07e+03 - 1.99e-03 3.17e-05w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 96r 0.0000000e+00 1.05e+04 1.20e+01 -5.4 7.00e+03 -6.2 1.00e+00 1.78e-15h 49\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 97r 0.0000000e+00 1.05e+04 2.31e+01 -5.4 4.29e+03 -5.8 2.10e-01 6.00e-11f 33\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 98r 0.0000000e+00 1.05e+04 1.59e+01 -5.4 1.05e+03 -5.4 1.00e+00 7.28e-12f 38\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 99r 0.0000000e+00 1.05e+04 2.46e+01 -5.4 5.40e+03 -5.9 1.33e-01 4.76e-11f 33\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 100r 0.0000000e+00 1.05e+04 1.83e+01 -5.4 1.21e+03 -5.4 1.00e+00 1.07e-10f 34\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 101r 0.0000000e+00 1.05e+04 2.73e+01 -5.4 7.03e+03 -5.9 1.02e-01 3.66e-11f 33\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 102r 0.0000000e+00 1.05e+04 2.77e+01 -5.4 1.40e+03 -5.5 1.00e+00 1.43e-12f 40\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 103r 0.0000000e+00 1.05e+04 4.37e+01 -5.4 9.60e+03 -6.0 7.47e-02 5.24e-14f 42\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 104r 0.0000000e+00 1.05e+04 6.49e+01 -5.4 1.63e+03 -5.5 1.00e+00 7.69e-14f 44\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 105r 0.0000000e+00 1.05e+04 1.04e+02 -5.4 1.42e+04 -6.0 5.06e-02 1.11e-15f 47\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 106r 0.0000000e+00 2.67e+04 1.58e+01 -5.4 1.91e+03 -5.6 1.00e+00 5.77e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 107r 0.0000000e+00 2.67e+04 1.40e+03 -5.4 9.67e+02 - 2.90e-03 3.66e-04w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 108r 0.0000000e+00 4.39e+04 4.78e+02 -5.4 5.57e+03 -6.1 3.84e-01 3.25e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 109r 0.0000000e+00 1.05e+04 1.80e+02 -5.4 6.38e+03 - 1.00e+00 4.10e-15f 47\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 110r 0.0000000e+00 1.05e+04 2.40e+02 -5.4 2.26e+03 -5.6 3.17e-01 3.47e-15f 48\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 111r 0.0000000e+00 1.05e+04 5.44e+02 -5.4 6.90e+04 -6.1 2.06e-02 1.14e-16f 48\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 112r 0.0000000e+00 1.05e+04 4.95e+01 -5.4 2.79e+03 -5.7 2.55e-01 7.69e-16f 51\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 113r 0.0000000e+00 1.05e+04 1.15e+01 -5.4 7.57e+02 -5.3 1.00e+00 7.11e-15f 48\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 114r 0.0000000e+00 1.05e+04 2.06e+01 -5.4 3.26e+03 -5.7 2.41e-01 6.02e-16f 50\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 115r 0.0000000e+00 1.05e+04 1.32e+01 -5.4 8.68e+02 -5.3 1.00e+00 2.22e-16h 53\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 116r 0.0000000e+00 1.05e+04 2.17e+01 -5.4 3.99e+03 -5.8 1.79e-01 3.07e-17h 54\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 117r 0.0000000e+00 1.05e+04 1.51e+01 -5.4 9.98e+02 -5.4 1.00e+00 2.78e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 118r 0.0000000e+00 1.05e+04 2.38e+01 -5.4 4.99e+03 -5.8 1.44e-01 6.14e-18h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 119r 0.0000000e+00 2.67e+04 5.98e+01 -5.4 1.15e+03 -5.4 1.00e+00 9.60e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 120r 0.0000000e+00 2.67e+04 2.31e+03 -5.4 1.66e+03 - 4.25e-03 1.30e-05w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 121r 0.0000000e+00 4.43e+04 8.41e+02 -5.4 3.52e+03 -5.9 5.33e-01 5.24e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 122r 0.0000000e+00 1.05e+04 1.75e+01 -5.4 1.31e+04 - 1.00e+00 2.66e-17h 55\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 123r 0.0000000e+00 1.05e+04 1.89e+01 -5.4 1.33e+03 -5.5 5.38e-01 2.30e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 124r 0.0000000e+00 1.05e+04 4.92e+01 -5.4 8.61e+03 -5.9 2.71e-01 3.56e-18h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 125r 0.0000000e+00 1.05e+04 2.98e+01 -5.4 1.55e+03 -5.5 1.00e+00 1.98e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 126r 0.0000000e+00 1.05e+04 4.92e+01 -5.4 1.23e+04 -6.0 6.33e-02 2.48e-18h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 127r 0.0000000e+00 1.05e+04 8.12e+01 -5.4 1.82e+03 -5.6 1.00e+00 1.69e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 128r 0.0000000e+00 1.05e+04 1.31e+02 -5.4 2.00e+04 -6.0 3.59e-02 1.53e-18f 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 129r 0.0000000e+00 1.05e+04 2.54e+02 -5.4 2.14e+03 -5.6 1.00e+00 1.43e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 130r 0.0000000e+00 1.05e+04 4.15e+02 -5.4 4.32e+04 -6.1 1.66e-02 7.10e-19f 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 131r 0.0000000e+00 1.05e+04 9.52e+02 -5.4 2.53e+03 -5.7 1.00e+00 1.21e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 132r 0.0000000e+00 2.67e+04 2.24e+01 -5.4 4.51e+05 -6.1 1.18e-04 2.45e-03w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 133r 0.0000000e+00 4.32e+04 1.53e+02 -5.4 4.75e+04 -6.6 3.50e-02 3.68e-02w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 134r 0.0000000e+00 4.32e+04 3.80e+02 -5.4 3.44e+03 - 1.99e-02 3.86e-06w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 135r 0.0000000e+00 1.05e+04 9.98e+02 -5.4 8.04e+02 - 1.18e-04 6.81e-20f 55\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 136r 0.0000000e+00 1.05e+04 2.21e+01 -5.4 8.37e+02 -5.3 6.52e-01 5.55e-17h 55\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 137r 0.0000000e+00 1.05e+04 2.91e+01 -5.4 3.73e+03 -5.8 2.04e-01 8.22e-18h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 138r 0.0000000e+00 1.05e+04 1.45e+01 -5.4 9.53e+02 -5.3 1.00e+00 5.55e-17h 55\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 139r 0.0000000e+00 1.05e+04 2.31e+01 -5.4 4.63e+03 -5.8 1.55e-01 6.62e-18h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 140r 0.0000000e+00 1.05e+04 1.67e+01 -5.4 1.10e+03 -5.4 1.00e+00 2.78e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 141r 0.0000000e+00 1.05e+04 2.55e+01 -5.4 5.89e+03 -5.9 1.22e-01 5.20e-18h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 142r 0.0000000e+00 1.05e+04 1.93e+01 -5.4 1.27e+03 -5.4 1.00e+00 2.41e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 143r 0.0000000e+00 1.05e+04 2.84e+01 -5.4 7.78e+03 -5.9 9.22e-02 3.94e-18h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 144r 0.0000000e+00 1.05e+04 3.40e+01 -5.4 1.48e+03 -5.5 1.00e+00 2.08e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 145r 0.0000000e+00 2.67e+04 4.04e+01 -5.4 1.09e+04 -6.0 6.60e-02 1.02e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 146r 0.0000000e+00 2.67e+04 1.47e+03 -5.4 1.02e+03 - 2.88e-03 1.10e-04w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 147r 0.0000000e+00 4.33e+04 7.00e+02 -5.4 1.97e+04 -6.5 1.24e-01 8.93e-02w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 148r 0.0000000e+00 1.05e+04 5.40e+01 -5.4 6.24e+03 - 6.60e-02 2.82e-18h 55\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 149r 0.0000000e+00 1.05e+04 1.51e+02 -5.4 1.68e+04 -6.0 1.26e-01 1.83e-18h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 150r 0.0000000e+00 1.05e+04 5.58e+01 -5.4 2.10e+03 -5.6 1.51e-01 9.25e-19h 60\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 151r 0.0000000e+00 1.05e+04 6.31e+01 -5.4 3.28e+04 -6.1 1.66e-02 9.36e-19f 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 152r 0.0000000e+00 1.05e+04 6.32e+01 -5.4 3.63e+03 -5.7 8.61e-03 1.56e-18h 54\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 153r 0.0000000e+00 1.05e+04 6.33e+01 -5.4 2.10e+05 -6.1 1.98e-05 1.48e-19f 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 154r 0.0000000e+00 1.05e+04 8.87e-01 -5.4 1.46e-02 -0.3 1.00e+00 1.43e-06h 4\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 155r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 2.09e-02 -0.8 1.00e+00 5.00e-01f 2\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 156r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 6.26e-02 -1.2 1.00e+00 2.44e-04h 13\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 157r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 1.88e-01 -1.7 1.00e+00 1.53e-05h 17\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 158r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 5.64e-01 -2.2 1.00e+00 1.00e+00w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 159r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 1.69e+00 -2.7 1.00e+00 1.00e+00w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 160r 0.0000000e+00 1.06e+04 3.62e-03 -5.4 5.08e+00 -3.1 1.00e+00 1.00e+00w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 161r 0.0000000e+00 1.05e+04 8.60e-03 -5.4 1.53e+01 -3.6 1.00e+00 7.45e-09h 27\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 162r 0.0000000e+00 1.05e+04 6.99e-01 -5.4 4.61e+01 -4.1 1.00e+00 1.14e-13h 44\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 163r 0.0000000e+00 1.05e+04 2.14e+00 -5.4 1.41e+02 -4.6 1.00e+00 2.84e-14h 46\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 164r 0.0000000e+00 1.05e+04 6.79e+00 -5.4 4.48e+02 -5.1 1.00e+00 4.66e-10f 32\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 165r 0.0000000e+00 1.05e+04 2.13e+01 -5.4 1.64e+03 -5.5 8.03e-01 1.96e-11f 36\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 166r 0.0000000e+00 1.05e+04 5.45e+01 -5.4 1.44e+04 -6.0 1.69e-01 5.60e-13f 38\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 167r 0.0000000e+00 1.05e+04 2.91e+01 -5.4 1.92e+03 -5.6 1.00e+00 1.31e-13f 43\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 168r 0.0000000e+00 1.05e+04 3.94e+01 -5.4 2.52e+04 -6.1 2.91e-02 3.11e-16f 48\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 169r 0.0000000e+00 1.05e+04 3.44e+01 -5.4 2.27e+03 -5.6 1.00e+00 3.46e-15h 48\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 170r 0.0000000e+00 1.05e+04 4.50e+01 -5.4 7.69e+04 -6.1 9.32e-03 1.28e-17f 51\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 171r 0.0000000e+00 2.67e+04 3.33e+01 -5.4 2.71e+03 -5.7 1.00e+00 4.08e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 172r 0.0000000e+00 2.67e+04 9.73e+02 -5.4 1.12e+03 - 1.93e-03 9.14e-05w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 173r 0.0000000e+00 4.37e+04 5.94e+02 -5.4 7.46e+03 -6.2 2.29e-01 2.40e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 174r 0.0000000e+00 1.05e+04 4.51e+01 -5.4 3.87e+03 - 1.00e+00 2.97e-12f 37\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 175r 0.0000000e+00 1.05e+04 6.47e+01 -5.4 3.27e+03 -5.7 2.19e-01 7.69e-14f 43\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 176r 0.0000000e+00 1.05e+04 5.10e+01 -5.4 8.69e+02 -5.3 1.00e+00 1.14e-13h 44\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 177r 0.0000000e+00 1.05e+04 7.51e+01 -5.4 4.00e+03 -5.8 1.79e-01 6.43e-11f 33\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 178r 0.0000000e+00 1.05e+04 6.82e+01 -5.4 1.00e+03 -5.4 1.00e+00 4.66e-10f 32\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 179r 0.0000000e+00 1.05e+04 1.03e+02 -5.4 5.00e+03 -5.8 1.43e-01 1.29e-11f 35\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 180r 0.0000000e+00 1.05e+04 1.08e+02 -5.4 1.15e+03 -5.4 1.00e+00 1.39e-11f 37\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 181r 0.0000000e+00 1.05e+04 1.65e+02 -5.4 6.42e+03 -5.9 1.12e-01 5.01e-12f 36\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 182r 0.0000000e+00 1.05e+04 2.00e+02 -5.4 1.34e+03 -5.5 1.00e+00 1.20e-11f 37\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 183r 0.0000000e+00 1.05e+04 3.13e+02 -5.4 8.54e+03 -5.9 8.39e-02 9.41e-13f 38\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 184r 0.0000000e+00 2.67e+04 6.63e+01 -5.4 1.55e+03 -5.5 1.00e+00 7.13e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 185r 0.0000000e+00 2.67e+04 8.09e+02 -5.4 1.01e+03 - 2.25e-03 8.90e-04w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 186r 0.0000000e+00 4.40e+04 1.17e+02 -5.4 4.65e+03 -6.0 4.39e-01 3.92e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 187r 0.0000000e+00 1.05e+04 4.40e+02 -5.4 8.89e+03 - 1.00e+00 2.07e-11f 35\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 188r 0.0000000e+00 1.05e+04 5.51e+02 -5.4 1.81e+03 -5.6 3.96e-01 8.88e-12f 37\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 189r 0.0000000e+00 1.05e+04 8.25e+02 -5.4 1.87e+04 -6.0 3.12e-02 1.08e-13f 40\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 190r 0.0000000e+00 1.05e+04 3.35e+01 -5.4 2.20e+03 -5.6 4.67e-01 2.27e-13f 43\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 191r 0.0000000e+00 1.05e+04 4.40e+01 -5.4 4.69e+04 -6.1 1.56e-02 5.36e-15f 43\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 192r 0.0000000e+00 1.05e+04 3.87e+01 -5.4 2.56e+03 -5.7 1.00e+00 2.46e-14f 45\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 193r 0.0000000e+00 1.05e+04 1.92e+01 -5.4 7.26e+02 -5.2 9.88e-01 1.14e-13h 44\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 194r 0.0000000e+00 1.05e+04 4.68e+01 -5.4 3.07e+03 -5.7 7.96e-01 1.68e-10f 32\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 195r 0.0000000e+00 1.05e+04 3.54e+01 -5.4 8.31e+02 -5.3 1.00e+00 5.82e-11f 35\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 196r 0.0000000e+00 1.05e+04 8.07e+01 -5.4 3.74e+03 -5.8 5.32e-01 6.87e-11f 33\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 197r 0.0000000e+00 2.44e+04 4.51e+01 -5.4 9.55e+02 -5.3 1.00e+00 1.00e+00w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 198r 0.0000000e+00 2.90e+04 1.83e+02 -5.4 3.03e+03 -5.8 6.02e-01 1.26e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 199r 0.0000000e+00 2.90e+04 3.65e+02 -5.4 1.03e+03 - 1.58e-03 1.30e-03w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 200r 0.0000000e+00 1.05e+04 6.99e+01 -5.4 9.09e+03 -6.3 1.00e+00 2.91e-11f 35\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of Iterations....: 200\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: (scaled) (unscaled)\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Dual infeasibility......: 6.9908071367141474e+01 6.9908071367141474e+01\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Constraint violation....: 2.8645094423111342e-03 1.0458847092153306e+04\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Complementarity.........: 1.3579265591895737e-03 1.3579265591895737e-03\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Overall NLP error.......: 2.8645094423111342e-03 1.0458847092153306e+04\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of objective function evaluations = 5209\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of objective gradient evaluations = 6\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of equality constraint evaluations = 5210\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of inequality constraint evaluations = 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of equality constraint Jacobian evaluations = 203\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of inequality constraint Jacobian evaluations = 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of Lagrangian Hessian evaluations = 200\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Total CPU secs in IPOPT (w/o function evaluations) = 0.176\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Total CPU secs in NLP function evaluations = 0.014\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: EXIT: Maximum Number of Iterations Exceeded.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit: Initialization Step 3 maxIterations - .\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit: Initialization Complete: maxIterations - \n", - "Initialization failed.\n" - ] - } - ], + "outputs": [], "source": [ "import logging\n", + "import traceback\n", + "\n", "from pyomo.environ import (\n", " ComponentMap,\n", " ConcreteModel,\n", @@ -618,14 +114,20 @@ " return m\n", "\n", "\n", - "if __name__ == \"__main__\":\n", - " m = create_model()\n", - "\n", - " reboiler_init = m.fs.unit.default_initializer(always_estimate_states=True)\n", - " try:\n", - " reboiler_init.initialize(m.fs.unit, output_level=idaeslog.DEBUG)\n", - " except InitializationError:\n", - " print(\"Initialization failed.\")" + "m = create_model()\n", + "reboiler_init = m.fs.unit.default_initializer(always_estimate_states=True)\n", + "try:\n", + " reboiler_init.initialize(m.fs.unit, output_level=idaeslog.DEBUG)\n", + "except InitializationError:\n", + " traceback.print_exc()" + ] + }, + { + "cell_type": "markdown", + "id": "066c51f2-fd67-45c9-8b59-5ef2b2a0b9fa", + "metadata": {}, + "source": [ + "Here we see that initialization failed due to the unit model solve terminating after reaching the maximum number of iterations. However, when solution of a square problem reaches 200-300 iterations without converging, increasing the number of iterations usually does not help. In this case, it terminates with a `Restoration Failed` status after about 500 iterations. When confronted with a failing solve, we should first head to the `DiagnosticsToolbox`." ] }, { @@ -634,55 +136,82 @@ "metadata": {}, "source": [ "## Step 2: Run Model Diagnostics\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "3f6b82e5-9d12-4c0a-a9b0-8a6414d894b1", + "metadata": {}, + "source": [ + "While initialization fails in every version of Python supported presently (3.10, 3.11, 3.12 3.13), the model termination point(s) that Python 3.10 and 3.11 come to are different than the model termination point that 3.12 and 3.13 come to. In order to ensure that the diagnostic output is the same in every supported version, we load the model state from a `json` file." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ab663d6a-4703-46d3-814c-86a659b87619", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [ + "testing" + ] + }, + "outputs": [], + "source": [ + "# Uncomment this cell in order to regenerate the cached solution\n", + "# from idaes.core.util import to_json\n", + "# to_json(m, fname=\"advanced_scaling_failed_solution.json\", human_read=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a0c5b278-6e3e-444a-a86c-ccfb87608c5d", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "from idaes.core.util import from_json, StoreSpec\n", "\n", - "We see that the unit model failed to initialize. When confronted with a bad solution state, we should first use the `DiagnosticsToolbox` to check to see if there are structural issues with the model." + "from_json(m, fname=\"advanced_scaling_failed_solution.json\", wts=StoreSpec.value())" + ] + }, + { + "cell_type": "markdown", + "id": "2816b80d-9c90-45c3-a59d-df4da4c35def", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "First, we will use the `DiagnosticsToolbox` to check to see if there are structural issues with the model. (More information about the `DiagnosticsToolbox` can be found in its [documentation](https://idaes-pse.readthedocs.io/en/stable/explanations/model_diagnostics/index.html) and [tutorial notebook](https://idaes-examples.readthedocs.io/en/latest/docs/diagnostics/diagnostics_toolbox_doc.html)" ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "id": "69b249a7-99ad-408d-b6aa-470bb1ea9057", "metadata": { - "scrolled": true + "editable": true, + "scrolled": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "====================================================================================\n", - "Model Statistics\n", - "\n", - " Activated Blocks: 23 (Deactivated: 0)\n", - " Free Variables in Activated Constraints: 77 (External: 0)\n", - " Free Variables with only lower bounds: 15\n", - " Free Variables with only upper bounds: 0\n", - " Free Variables with upper and lower bounds: 50\n", - " Fixed Variables in Activated Constraints: 66 (External: 0)\n", - " Activated Equality Constraints: 77 (Deactivated: 0)\n", - " Activated Inequality Constraints: 0 (Deactivated: 0)\n", - " Activated Objectives: 0 (Deactivated: 0)\n", - "\n", - "------------------------------------------------------------------------------------\n", - "1 WARNINGS\n", - "\n", - " WARNING: Found 9 potential evaluation errors.\n", - "\n", - "------------------------------------------------------------------------------------\n", - "2 Cautions\n", - "\n", - " Caution: 11 variables fixed to 0\n", - " Caution: 82 unused variables (82 fixed)\n", - "\n", - "------------------------------------------------------------------------------------\n", - "Suggested next steps:\n", - "\n", - " display_potential_evaluation_errors()\n", - "\n", - "====================================================================================\n" - ] - } - ], + "outputs": [], "source": [ "from idaes.core.util import DiagnosticsToolbox\n", "\n", @@ -695,64 +224,24 @@ "id": "c08b1da8-20da-4291-b555-7d78cf565f67", "metadata": {}, "source": [ - "The density relationship is being flagged for potential evaluation errors. The interval arithmetic used to identify potential evaluation errors can produce relatively loose bounds, especially for the sort of large polynomial expressions favored in the literature. Independent testing of the density relationship over a wide range of values has demonstrated that no evaluation errors occur, so we can ignore these warnings.\n", + "The density relationship is being flagged for potential evaluation errors. The interval arithmetic used to identify potential evaluation errors can produce relatively loose bounds, especially for the sort of large polynomial expressions favored in engineering literature. Independent testing of the density relationship over a wide range of values has demonstrated that no evaluation errors occur, so we can ignore these warnings.\n", "\n", "The next step is determining which numerical issues exist." ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "id": "41e8b916-6314-42b3-b643-b492486af32b", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "====================================================================================\n", - "Model Statistics\n", - "\n", - " Jacobian Condition Number: 2.718E+13\n", - "\n", - "------------------------------------------------------------------------------------\n", - "3 WARNINGS\n", - "\n", - " WARNING: 3 Constraints with large residuals (>1.0E-05)\n", - " WARNING: 1 Variable with extreme Jacobian column norms (<1.0E-08 or >1.0E+08)\n", - " WARNING: 1 Constraint with extreme Jacobian row norms (<1.0E-08 or >1.0E+08)\n", - "\n", - "------------------------------------------------------------------------------------\n", - "8 Cautions\n", - "\n", - " Caution: 9 Variables with value close to their bounds (abs=1.0E-04, rel=1.0E-04)\n", - " Caution: 18 Variables with value close to zero (tol=1.0E-08)\n", - " Caution: 30 Variables with extreme value (<1.0E-04 or >1.0E+04)\n", - " Caution: 2 Constraints with mismatched terms\n", - " Caution: 1 Constraint with potential cancellation of terms\n", - " Caution: 27 Variables with extreme Jacobian column norms (<1.0E-04 or >1.0E+04)\n", - " Caution: 16 Constraints with extreme Jacobian row norms (<1.0E-04 or >1.0E+04)\n", - " Caution: 50 extreme Jacobian Entries (<1.0E-04 or >1.0E+04)\n", - "\n", - "------------------------------------------------------------------------------------\n", - "Suggested next steps:\n", - "\n", - " display_constraints_with_large_residuals()\n", - " compute_infeasibility_explanation()\n", - " display_variables_with_extreme_jacobians()\n", - " display_constraints_with_extreme_jacobians()\n", - "\n", - "====================================================================================\n" - ] - } - ], + "outputs": [], "source": [ "dt.report_numerical_issues()" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "id": "51b9a50d", "metadata": { "tags": [ @@ -814,44 +303,15 @@ "$$\n", "With a condition number on the order of $10^{13}$ and the default tolerance $\\varepsilon = 10^{-6}$, then the difference between the computed solution $x_f$ and the true solution $x$ could be on the order of $10^7$.\n", "\n", - "In practice, however, we frequently end up with much better results than those predicted by this worst-case bound. Frequently, we find that most constraints have residuals on the order of $10^{-10}$ or less, with a few problematic constraints having larger residuals. That is the case here." + "In practice, however, we frequently end up with much better results than those predicted by this worst-case bound. The condition number of the unscaled Jacobian does not taken into account that some variables are much bigger than others. For example, the liquid phase mole fraction of $\\text{CO}_2$ is on the order of $10^{-5}$, whereas the heat duty is on the order of $10^6$. Unless we scale the model, we have no way of determining which changes to the solution are significant and which are not. Additionally, we frequently find that most constraints have residuals on the order of $10^{-10}$ or less, with only a few problematic constraints having larger residuals. That is the case here." ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "id": "3a75813b-2b5e-44d9-9676-1f26871ecf37", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Number of constraints: 77\n", - "====================================================================================\n", - "The following constraint(s) have large residuals (>1.0E-10):\n", - "\n", - " fs.unit.unit_material_balance[0.0,CO2]: 1.84866E-10\n", - " fs.unit.unit_material_balance[0.0,N2]: 1.89950E-10\n", - " fs.unit.unit_material_balance[0.0,O2]: 1.87656E-10\n", - " fs.unit.unit_phase_equilibrium[0.0,CO2]: 1.04588E+04\n", - " fs.unit.unit_phase_equilibrium[0.0,H2O]: 8.88278E-07\n", - " fs.unit.unit_enthalpy_balance[0.0]: 5.05679E-10\n", - " fs.unit.liquid_phase.material_balances[0.0,CO2]: 1.70459E-10\n", - " fs.unit.liquid_phase.enthalpy_balances[0.0]: 1.17285E-05\n", - " fs.unit.liquid_phase.properties_out[0.0].sum_mole_frac_out: 2.08134E-10\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-]: 8.83857E-06\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]: 1.54414E-07\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA_+]: 7.69821E-06\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,H2O]: 2.50511E-08\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA]: 4.55346E-06\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2]: 4.42749E-05\n", - " fs.unit.vapor_phase[0.0].sum_mole_frac_out: 1.71144E-10\n", - "\n", - "====================================================================================\n" - ] - } - ], + "outputs": [], "source": [ "import idaes.core.util.model_statistics as mstat\n", "\n", @@ -874,7 +334,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "id": "1da2f90e-e562-4f2a-b066-c635c88b0d78", "metadata": {}, "outputs": [], @@ -1111,14 +571,12 @@ "\n", "## Step 3: Creating a New Scaler Class\n", "\n", - "To create a new scaling routine for the equilibrium reactor, we start by creating a new ``Scaler`` class which inherits from the ``CustomScalerBase`` class in ``idaes.core.scaling``. The ``CustomScalerBase`` class contains a number of useful methods to help us in developing our scaling routine, including some placeholder methods for implementing a standard scaling workflow and helper methods for doing common tasks.\n", - "\n", - "The cell below shows how to create our new class which we will name ``SolventReboilerScaler`` as well as two key methods we will fill out as part of this workshop." + "To create a new scaling routine for the solvent reboiler, we start by creating a new ``Scaler`` class which inherits from the ``CustomScalerBase`` class in ``idaes.core.scaling``." ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "id": "6910d881-8875-4529-bd30-5807aa15f400", "metadata": {}, "outputs": [], @@ -1145,7 +603,7 @@ "id": "ba19563f-d285-4eba-8156-1d4ef0ad36b2", "metadata": {}, "source": [ - "As you know from the first scaling tutorial, the ``variable_scaling_routine`` and ``constraint_scaling_routine`` methods are used to implement subroutines for scaling the variables and constraints in the model respectively. Separately, there is a ``scale_model`` method that will call each of these in sequence in order to scale an entire model by applying the following steps:\n", + "As you know from the [first scaling tutorial](./scaler_workshop.ipynb), the ``variable_scaling_routine`` and ``constraint_scaling_routine`` methods are used to implement subroutines for scaling the variables and constraints in the model respectively. Separately, there is a ``scale_model`` method that will call each of these in sequence in order to scale an entire model by applying the following steps:\n", "\n", "1. apply variable scaling routine,\n", "2. apply first stage scaling fill-in,\n", @@ -1161,7 +619,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "id": "6a2d1c70-1608-4df6-9865-68c00193dcbe", "metadata": {}, "outputs": [], @@ -1216,7 +674,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "id": "7ae92ba0-17d3-4aa5-ba21-d5cead039f47", "metadata": {}, "outputs": [], @@ -1235,31 +693,10 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": null, "id": "8de34555-cf86-43a1-bf56-e12ef9e7b55b", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'flow_mol_phase': ,\n", - " 'mole_frac_phase_comp': 10,\n", - " 'temperature': 0.0033333333333333335,\n", - " 'pressure': 1e-05,\n", - " 'enth_mol_phase': ,\n", - " 'visc_d_phase': ,\n", - " 'therm_cond_phase': ,\n", - " 'mole_frac_phase_comp_true': 10,\n", - " 'mole_frac_phase_comp_apparent': 10,\n", - " 'dens_mol_phase': ,\n", - " 'vol_mol_phase': }" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "liquid_properties_scaler.default_scaling_factors" ] @@ -1273,14 +710,14 @@ "\n", "With an inlet flow of about 80 mol/s, a scaling factor of 1/80 is appropriate. We can ignore ``visc_d_phase`` and ``therm_cond_phase``, because this unit model does not require dynamic viscosity or thermal conductivity. Molar enthalpy is a tougher quantity to scale.\n", "\n", - "By convention, the molar enthalpy of each element in its pure form at $25^\\circ\\text{C}$ and $1\\:\\text{atm}$ is set equal to zero. In some property packages, enthalpy of formation is taken into account for compounds, while in some property packages it is not. However, the scaling factor for enthalpy should not depend on this convention---only enthalpy *differences* are meaningful. So we need to determine how to determine what constitutes a \"significant\" enthalpy difference for this property package. The way the modular property scaler object estimates this is through the temperature scaling factor, which determines what a \"significant\" temperature difference is, and the observation that a wide range of substances have a specific heat capacity around $2\\:\\frac{\\text{J}}{\\text{g K}}$.\n", + "By convention, the molar enthalpy of each element in its pure form at $25^\\circ\\text{C}$ and $1\\:\\text{atm}$ is set equal to zero. In some property packages, enthalpy of formation is taken into account for compounds, while in some property packages it is not. However, the scaling factor for enthalpy should not depend on this convention—only enthalpy *differences* are meaningful. So we need to determine how to determine what constitutes a \"significant\" enthalpy difference for this property package. The way the modular property scaler object estimates this is through the temperature scaling factor, which determines what a \"significant\" temperature difference is, and the observation that a wide range of substances have a specific heat capacity around $2\\:\\frac{\\text{J}}{\\text{g K}}$.\n", "\n", "This default method is good enough for our purposes now. We can revisit it later, if necessary." ] }, { "cell_type": "code", - "execution_count": 12, + "execution_count": null, "id": "322ea374-6077-49b5-aa2f-d866ad9a3204", "metadata": {}, "outputs": [], @@ -1302,46 +739,10 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": null, "id": "f82e7b2c-8c98-4685-bf25-9f2dea6db0f1", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "====================================================================================\n", - "Model Statistics\n", - "\n", - " Jacobian Condition Number: 7.165E+10\n", - "\n", - "------------------------------------------------------------------------------------\n", - "1 WARNINGS\n", - "\n", - " WARNING: 1 Constraint with large residuals (>1.0E-05)\n", - "\n", - "------------------------------------------------------------------------------------\n", - "8 Cautions\n", - "\n", - " Caution: 9 Variables with value close to their bounds (abs=1.0E-04, rel=1.0E-04)\n", - " Caution: 14 Variables with value close to zero (tol=1.0E-08)\n", - " Caution: 27 Variables with extreme value (<1.0E-04 or >1.0E+04)\n", - " Caution: 2 Constraints with mismatched terms\n", - " Caution: 1 Constraint with potential cancellation of terms\n", - " Caution: 10 Variables with extreme Jacobian column norms (<1.0E-04 or >1.0E+04)\n", - " Caution: 4 Constraints with extreme Jacobian row norms (<1.0E-04 or >1.0E+04)\n", - " Caution: 33 extreme Jacobian Entries (<1.0E-04 or >1.0E+04)\n", - "\n", - "------------------------------------------------------------------------------------\n", - "Suggested next steps:\n", - "\n", - " display_constraints_with_large_residuals()\n", - " compute_infeasibility_explanation()\n", - "\n", - "====================================================================================\n" - ] - } - ], + "outputs": [], "source": [ "reboiler_scaler = SolventReboilerScaler()\n", "reboiler_scaler.scale_model(m.fs.unit)\n", @@ -1351,7 +752,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": null, "id": "a8ba1d58", "metadata": { "tags": [ @@ -1374,7 +775,7 @@ "$$\n", "\\max\\left(\\frac{||\\mathbf{r}_\\text{max}||_2}{||\\mathbf{r}_\\text{min}||_2}, \\frac{||\\mathbf{c}_\\text{max}||_2}{||\\mathbf{c}_\\text{min}||_2}\\right) \\leq \\kappa(\\mathbf{J}(\\mathbf{x}))\n", "$$\n", - "Consequently, Jacobian rows or columns with extremely large or extremely small norms indicate that the Jacobian is ill-conditioned. Each row is associated with a constraint and each column is associated with a variable. So the extreme Jacobian rows and columns give us a list of variables and constraints to investigate for scaling.\n", + "Consequently, Jacobian rows or columns with extremely large or extremely small norms indicate that the Jacobian is ill-conditioned. Each row is associated with a constraint and each column is associated with a variable. Thus, the extreme Jacobian rows and columns give us a list of variables and constraints to investigate for scaling.\n", "\n", "
\n", "Just because a variable or constraint has a Jacobian column or row with an extreme norm does not mean it is badly-scaled. Frequently, either a constraint containing the variable or a variable present in a constraint is the actual problem. \n", @@ -1393,41 +794,10 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": null, "id": "0737f98e-73c5-4fac-9215-aee2efd1942d", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "====================================================================================\n", - "The following variable(s) correspond to Jacobian columns with extreme norms(<1.0E-04 or>1.0E+04):\n", - "\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,CO2]: 3.450E+07\n", - " fs.unit.liquid_phase.enthalpy_transfer[0.0]: 1.970E+06\n", - " fs.unit.liquid_phase.properties_out[0.0].temperature: 1.586E+06\n", - " fs.unit.vapor_phase[0.0].pressure: 1.353E+05\n", - " fs.unit.vapor_phase[0.0].temperature: 1.014E+05\n", - " fs.unit.liquid_phase.properties_out[0.0].pressure: 1.000E+05\n", - " fs.unit.vapor_phase[0.0].flow_mol_phase[Vap]: 3.256E+04\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,H2O]: 1.954E+04\n", - " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]: 1.873E+04\n", - " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]: 1.863E+04\n", - "\n", - "====================================================================================\n", - "====================================================================================\n", - "The following constraint(s) correspond to Jacobian rows with extreme norms (<1.0E-04 or>1.0E+04):\n", - "\n", - " fs.unit.unit_phase_equilibrium[0.0,CO2]: 3.450E+07\n", - " fs.unit.unit_enthalpy_balance[0.0]: 1.973E+06\n", - " fs.unit.unit_phase_equilibrium[0.0,H2O]: 1.589E+06\n", - " fs.unit.unit_pressure_balance[0.0]: 1.414E+05\n", - "\n", - "====================================================================================\n" - ] - } - ], + "outputs": [], "source": [ "dt.display_variables_with_extreme_jacobians()\n", "dt.display_constraints_with_extreme_jacobians()" @@ -1442,23 +812,15 @@ "\n", "## Step 5: Unit Model Level Scaling\n", "\n", - "We should take a look at the constraints before determining their scaling factors. However, Pyomo's `pprint` method often prints out multiple terminal pages' worth of thermodynamic expressions, which are extremely difficult to parse. The output is so verbose because it descends into named `Expressions` and recursively subsititutes them into the constraint expression. Since IDAES makes heavy use of named `Expressions` to decrease the number of `Constraints` in a model, the output becomes unmanangable for all but the most simple constraints. The `print_compact_form` utility function usually results in much more readable output." + "We should take a look at the constraints before determining their scaling factors. However, Pyomo's `pprint` method often prints out multiple terminal pages' worth of thermodynamic expressions, which are extremely difficult to parse. The output is so verbose because it descends into named `Expressions` and recursively subsititutes them into the constraint expression. Since IDAES makes heavy use of named `Expressions` to reduce the number of `Constraints` in a model, the output becomes unmanangable for all but the most simple constraints. The `print_compact_form` utility function usually results in much more readable output." ] }, { "cell_type": "code", - "execution_count": 16, + "execution_count": null, "id": "6e025e22-4b18-41cf-b761-942ec50964e1", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "- fs.unit.liquid_phase.enthalpy_transfer[0.0] == (kg*m**2/J/s**2)*fs.unit.vapor_phase[0.0]._enthalpy_flow_term[Vap]\n" - ] - } - ], + "outputs": [], "source": [ "from idaes.core.util.misc import print_compact_form\n", "\n", @@ -1478,21 +840,10 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": null, "id": "54986702-39c2-40ac-b144-8a757ac324fb", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "5.076760620583219e-07" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "get_scaling_factor(m.fs.unit.liquid_phase.enthalpy_transfer[0.0])" ] @@ -1509,18 +860,10 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": null, "id": "ed2cad19-6b46-4a97-9fc5-4332c0dea65c", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "None\n" - ] - } - ], + "outputs": [], "source": [ "print(get_scaling_factor(m.fs.unit.vapor_phase[0.0]._enthalpy_flow_term[\"Vap\"]))" ] @@ -1535,18 +878,10 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": null, "id": "cebca2c2-a949-4120-b31a-453d28eee1ae", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "fs.unit.vapor_phase[0.0].flow_mol_phase[Vap]*fs.unit.vapor_phase[0.0].enth_mol_phase[Vap]\n" - ] - } - ], + "outputs": [], "source": [ "print_compact_form(m.fs.unit.vapor_phase[0.0]._enthalpy_flow_term[\"Vap\"])" ] @@ -1561,21 +896,10 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": null, "id": "c997f5f5-9b09-48cf-a15e-3cd0cc43c52b", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0.1" - ] - }, - "execution_count": 20, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "get_scaling_factor(m.fs.unit.vapor_phase[0.0].flow_mol_phase[\"Vap\"])" ] @@ -1590,21 +914,10 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": null, "id": "759e6aab-ddc5-435f-9699-d9dcdf82dc52", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "5.46268982847154e-05" - ] - }, - "execution_count": 21, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "get_scaling_factor(m.fs.unit.vapor_phase[0.0].enth_mol_phase[\"Vap\"])" ] @@ -1619,21 +932,10 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": null, "id": "c12629aa-ea76-43fd-8a87-dff2b7d2ac75", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0.0125" - ] - }, - "execution_count": 22, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "get_scaling_factor(m.fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase[\"Liq\"])" ] @@ -1649,7 +951,7 @@ "$$\n", "Let $\\sigma(v)$ denote the scaling factor of the variable $v$. Then `get_sum_terms_nominal_values` substitutes the inverse of the variable scaling factor into each term in the sum and returns it as a list:\n", "$$\n", - "\\left[\\frac{1}{\\sigma(a)},\\; \\frac{1}{\\sigma(b) \\cdot \\sigma(c)}, \\frac{\\left(\\frac{1}{\\sigma(e)} - \\frac{1}{\\sigma(f)}\\right)}{\\sigma(d)} \\right]\n", + "\\left[\\frac{1}{\\sigma(a)},\\; \\frac{1}{\\sigma(b) \\cdot \\sigma(c)}, \\frac{-\\left(\\frac{1}{\\sigma(e)} - \\frac{1}{\\sigma(f)}\\right)}{\\sigma(d)} \\right]\n", "$$\n", "\n", "This process can produce reliable estimates of expression magnitude for certain operations:\n", @@ -1677,21 +979,10 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": null, "id": "899cf853-c7a5-40b9-add6-21de075f15f2", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[1969759.9999999995, 183060.0]" - ] - }, - "execution_count": 23, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "reboiler_scaler.get_sum_terms_nominal_values(m.fs.unit.unit_enthalpy_balance[0.0])" ] @@ -1701,7 +992,7 @@ "id": "ef79b2c7-3187-41c1-aa33-bce79bceb11a", "metadata": {}, "source": [ - "The inverse of either of these numbers would be reasonable scaling factors. The `scale_constraint_by_nominal value` function automatically scales a constraint by using one of these numbers. Which number we use is selected using the `ConstraintScalingScheme` `Enum` If we take the inverse of the larger number, we are saying that the constraint needs to be satisfied with the same precision as the largest term in the sum. This corresponds to `ConstraintScalingScheme.inverseMaximum`. If we take the inverse of the smaller number, we are saying that the constraint needs to be satisfied with the same precision as the smallest term in the sum. This corresponds to `ConstraintScalingScheme.inverseMinimum`.\n", + "The inverse of either of these numbers would be reasonable scaling factors. The `scale_constraint_by_nominal value` function automatically scales a constraint by using one of these numbers. Which number we use is selected using the `ConstraintScalingScheme` `Enum`. If we take the inverse of the larger number, we are saying that the constraint needs to be satisfied with the same precision as the largest term in the sum. This corresponds to `ConstraintScalingScheme.inverseMaximum`. If we take the inverse of the smaller number, we are saying that the constraint needs to be satisfied with the same precision as the smallest term in the sum. This corresponds to `ConstraintScalingScheme.inverseMinimum`.\n", "\n", "In general, the `inverseMinimum` scheme is the safest to use, because it demands the most precision. Let's use the `inverseMinimum` method for this constraint in order to more precisely determine the vapor phase's temperature.\n", "\n", @@ -1710,24 +1001,12 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": null, "id": "5165dd5a-f440-466a-b1e2-5e5f43846746", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[Liq,CO2] == fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,CO2]\n", - "\n", - "\n", - "fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[Liq,H2O] == fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,H2O]\n" - ] - } - ], + "outputs": [], "source": [ "print_compact_form(m.fs.unit.unit_phase_equilibrium[0.0, \"CO2\"])\n", - "print(\"\\n\")\n", "print_compact_form(m.fs.unit.unit_phase_equilibrium[0.0, \"H2O\"])" ] }, @@ -1741,7 +1020,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": null, "id": "222d92b4", "metadata": { "tags": [ @@ -1767,19 +1046,10 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": null, "id": "790b9691-0734-4974-9f32-0d5d4070e5c5", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[7623092.433711249, 10000.0]\n", - "[355.3596511053128, 10000.0]\n" - ] - } - ], + "outputs": [], "source": [ "print(\n", " reboiler_scaler.get_sum_terms_nominal_values(\n", @@ -1798,23 +1068,15 @@ "id": "e601fb2f-6208-4c53-bd74-13bbe97b682b", "metadata": {}, "source": [ - "Here, we see that, while the vapor phase fugacities are associated with a nominal value of 10000, the liquid phase fugacities have wildly different nominal values. We do expect the vapor phase to be enriched in $\\text{CO}_2$, but not by a factor of $2\\cdot 10^4$. Let's unpack these values. We are using the ideal gas law for the vapor phase, so the fugacity is simply the product of the mole fraction and vapor pressure:" + "Here, we see that, while the vapor phase fugacities are associated with a nominal value of `10000`, the liquid phase fugacities have wildly different nominal values. We do expect the vapor phase to be enriched in $\\text{CO}_2$, but not by a factor of $2\\cdot 10^4$. Let's unpack these values. We are using the ideal gas law for the vapor phase, so the fugacity is simply the product of the mole fraction and vapor pressure:" ] }, { "cell_type": "code", - "execution_count": 27, + "execution_count": null, "id": "5bdb2701-c04a-4e1b-b9d2-86a673a944a9", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]*fs.unit.vapor_phase[0.0].pressure\n" - ] - } - ], + "outputs": [], "source": [ "print_compact_form(m.fs.unit.vapor_phase[0.0].fug_phase_comp[\"Vap\", \"CO2\"])" ] @@ -1829,18 +1091,10 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": null, "id": "7a316b13-1891-47fa-bb1a-fa52365f8e57", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,CO2]*(exp(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O])*log(244800.0*exp(-1348*K/fs.unit.liquid_phase.properties_out[0.0].temperature)*(3520000.0*exp(-2113*K/fs.unit.liquid_phase.properties_out[0.0].temperature)/(8449000.0*exp(-2283*K/fs.unit.liquid_phase.properties_out[0.0].temperature)))) + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O])*log(3520000.0*exp(-2113*K/fs.unit.liquid_phase.properties_out[0.0].temperature)) + fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O])*(fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]))*(fs.liquid_properties.CO2.lwm_coeff_1 + K**(-1)*fs.liquid_properties.CO2.lwm_coeff_2*(fs.unit.liquid_phase.properties_out[0.0].temperature - 273.15*K) + K**(-2)*fs.liquid_properties.CO2.lwm_coeff_3*(fs.unit.liquid_phase.properties_out[0.0].temperature - 273.15*K)**2 + fs.liquid_properties.CO2.lwm_coeff_4*(fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]))))*Pa*m**3*mol**(-1))\n" - ] - } - ], + "outputs": [], "source": [ "print_compact_form(\n", " m.fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[\"Liq\", \"CO2\"]\n", @@ -1852,26 +1106,15 @@ "id": "df43607d-fd78-4ab2-9e40-223c595cc115", "metadata": {}, "source": [ - "Parsing the entire pile of thermodynamic gibberish is unnecessary to plan our next move. We can plainly see that the liquid phase fugacity expression is rife with subtraction and exponentiation, both of which are dangerous for the nominal value expression walker. Even worse, we are scaling based on a failed solution, so the values may be off anyway. It is far better to base the scaling factor on the vapor phase fugacity. The `get_expression_nominal_value` function allows the user to get the nominal value of a single expression." + "Parsing the entire pile of thermodynamic gibberish is unnecessary to plan our next move. We can see that the liquid phase fugacity expression is rife with subtraction and exponentiation, both of which are dangerous for the nominal value expression walker. Even worse, we are scaling based on a failed solution, so the values may be off anyway. It is far better to base the scaling factor on the vapor phase fugacity. The `get_expression_nominal_value` function allows the user to get the nominal value of a single expression." ] }, { "cell_type": "code", - "execution_count": 29, + "execution_count": null, "id": "7ebe7e0c-1dc5-49cc-a712-d507f2510f28", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "10000.0" - ] - }, - "execution_count": 29, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "reboiler_scaler.get_expression_nominal_value(\n", " m.fs.unit.vapor_phase[0.0].fug_phase_comp[\"Vap\", \"CO2\"]\n", @@ -1890,18 +1133,10 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": null, "id": "1ad76dde-b6f4-4c26-9d78-5cc76170c399", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "fs.unit.liquid_phase.properties_out[0.0].pressure == fs.unit.vapor_phase[0.0].pressure\n" - ] - } - ], + "outputs": [], "source": [ "print_compact_form(m.fs.unit.unit_pressure_balance[0.0])" ] @@ -1918,52 +1153,10 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": null, "id": "715c1ead-2d0e-4b4f-97ef-bdd8fb0bb2d0", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Scaling Factors for block fs.unit\n", - "\n", - "Variable Scaling Factor Value Scaled Value\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol 1.250E-02 8.389E+01 1.049E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[H2O] 1.000E+01 8.589E-01 8.589E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[MEA] 1.000E+01 1.085E-01 1.085E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[CO2] 1.000E+01 3.260E-02 3.260E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].temperature 3.333E-03 3.925E+02 1.308E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol 1.250E-02 7.424E+01 9.279E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O] 1.000E+01 8.527E-01 8.527E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] 1.000E+01 1.226E-01 1.226E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[CO2] 1.000E+01 2.471E-02 2.471E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].temperature 3.333E-03 3.926E+02 1.309E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", - "fs.unit.vapor_phase[0.0].flow_mol 1.000E-01 9.654E+00 9.654E-01\n", - "fs.unit.vapor_phase[0.0].mole_frac_comp[CO2] 1.000E+01 9.329E-02 9.329E-01\n", - "fs.unit.vapor_phase[0.0].mole_frac_comp[H2O] 1.000E+01 9.067E-01 9.067E+00\n", - "fs.unit.vapor_phase[0.0].mole_frac_comp[N2] 1.000E+01 1.055E-09 1.055E-08\n", - "fs.unit.vapor_phase[0.0].mole_frac_comp[O2] 1.000E+01 1.055E-09 1.055E-08\n", - "fs.unit.vapor_phase[0.0].temperature 3.333E-03 3.926E+02 1.309E+00\n", - "fs.unit.vapor_phase[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", - "fs.unit.liquid_phase.heat[0.0] 5.077E-07 4.306E+05 2.186E-01\n", - "\n", - "Constraint Scaling Factor\n", - "fs.unit.unit_material_balance[0.0,CO2] None\n", - "fs.unit.unit_material_balance[0.0,H2O] None\n", - "fs.unit.unit_material_balance[0.0,N2] None\n", - "fs.unit.unit_material_balance[0.0,O2] None\n", - "fs.unit.unit_material_balance[0.0,MEA] None\n", - "fs.unit.unit_phase_equilibrium[0.0,CO2] None\n", - "fs.unit.unit_phase_equilibrium[0.0,H2O] None\n", - "fs.unit.unit_temperature_equality[0.0] None\n", - "fs.unit.unit_enthalpy_balance[0.0] None\n", - "fs.unit.unit_pressure_balance[0.0] None\n" - ] - } - ], + "outputs": [], "source": [ "from idaes.core.scaling.util import report_scaling_factors\n", "\n", @@ -1980,18 +1173,10 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": null, "id": "7f5f85f4-33ec-42a4-a700-c9744b25d6f4", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "fs.unit.liquid_phase.properties_out[0.0].temperature == fs.unit.vapor_phase[0.0].temperature\n" - ] - } - ], + "outputs": [], "source": [ "print_compact_form(m.fs.unit.unit_temperature_equality[0.0])" ] @@ -2008,29 +1193,13 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": null, "id": "0f62396b-94de-4f92-b7c9-4d6cae1e83b5", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "- fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,CO2] == fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,CO2]\n", - "\n", - "\n", - "fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,MEA] == 0*(mol*s**(-1))\n", - "\n", - "\n", - "fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,N2] == fs.unit.zero_flow_param\n" - ] - } - ], + "outputs": [], "source": [ "print_compact_form(m.fs.unit.unit_material_balance[0.0, \"CO2\"])\n", - "print(\"\\n\")\n", "print_compact_form(m.fs.unit.unit_material_balance[0.0, \"MEA\"])\n", - "print(\"\\n\")\n", "print_compact_form(m.fs.unit.unit_material_balance[0.0, \"N2\"])" ] }, @@ -2055,7 +1224,7 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": null, "id": "164ad598-7e44-43ad-b6e6-726721a66f21", "metadata": {}, "outputs": [], @@ -2139,54 +1308,27 @@ "id": "9d5e8f3f-94fa-49be-a213-30cb976798e2", "metadata": {}, "source": [ - "Now we can see how this works on the model. We'll pass `overwrite=True` config option when creating the scaler object to ensure we have up-to-date scaling factors." + "Now we can see how this works on the model. We will create a new instance of the model to demonstrate that the improved scaling is sufficient to allow the model to initialize without a custom-tailored initial guess." ] }, { "cell_type": "code", - "execution_count": 35, + "execution_count": null, "id": "a319f9b5-4c27-4416-9c8e-41be2d9badd3", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Starting initialization routine\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Bubble, dew, and critical point initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Equilibrium temperature initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: State variable initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Phase equilibrium initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Property initialization routine finished.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Starting initialization routine\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Bubble, dew, and critical point initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Equilibrium temperature initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: State variable initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Phase equilibrium initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Property initialization routine finished.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: Starting initialization routine\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: Bubble, dew, and critical point initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: Equilibrium temperature initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: State variable initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: Phase equilibrium initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: Property initialization routine finished.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit: Initialization Complete: optimal - \n" - ] - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 35, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "scaler_obj = SolventReboilerScaler(overwrite=True)\n", + "m = create_model()\n", + "\n", + "# Since this is a new instance of the model, we need to set the default\n", + "# scaler objects again.\n", + "m.fs.liquid_properties.default_state_scaler_object = liquid_properties_scaler\n", + "m.fs.vapor_properties.default_state_scaler_object = vapor_properties_scaler\n", + "\n", + "scaler_obj = SolventReboilerScaler()\n", "scaler_obj.scale_model(m.fs.unit)\n", + "\n", + "reboiler_init = m.fs.unit.default_initializer(always_estimate_states=True)\n", "reboiler_init.initialize(m.fs.unit)" ] }, @@ -2195,51 +1337,15 @@ "id": "c7e05d0d-7dc8-4de9-b87d-059b3779b71c", "metadata": {}, "source": [ - "We see that scaling improved the model enough so that initialization could succeed. Now let's look at the numerical issues." + "We see that scaling improved the robustness of the model enough so that initialization could succeed. Now let's look at the numerical issues." ] }, { "cell_type": "code", - "execution_count": 36, + "execution_count": null, "id": "a2e3a35e-165e-4687-a0ef-5330557fdb16", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "====================================================================================\n", - "Model Statistics\n", - "\n", - " Jacobian Condition Number: 5.400E+06\n", - "\n", - "------------------------------------------------------------------------------------\n", - "0 WARNINGS\n", - "\n", - " No warnings found!\n", - "\n", - "------------------------------------------------------------------------------------\n", - "6 Cautions\n", - "\n", - " Caution: 9 Variables with value close to their bounds (abs=1.0E-04, rel=1.0E-04)\n", - " Caution: 14 Variables with value close to zero (tol=1.0E-08)\n", - " Caution: 27 Variables with extreme value (<1.0E-04 or >1.0E+04)\n", - " Caution: 2 Constraints with mismatched terms\n", - " Caution: 1 Constraint with potential cancellation of terms\n", - " Caution: 20 extreme Jacobian Entries (<1.0E-04 or >1.0E+04)\n", - "\n", - "------------------------------------------------------------------------------------\n", - "Suggested next steps:\n", - "\n", - " If you still have issues converging your model consider:\n", - "\n", - " prepare_degeneracy_hunter()\n", - " prepare_svd_toolbox()\n", - "\n", - "====================================================================================\n" - ] - } - ], + "outputs": [], "source": [ "dt = DiagnosticsToolbox(m)\n", "dt.report_numerical_issues()" @@ -2247,7 +1353,7 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": null, "id": "f62989cb", "metadata": { "tags": [ @@ -2297,7 +1403,7 @@ "\n", "Because $\\mathbf{U}$ and $\\mathbf{V}$ are orthogonal and $\\mathbf{\\Sigma}$ is diagonal, computing a Newton step is easy once the SVD is calculated.\n", "$$\n", - "\\mathbf{\\delta x}_k = -\\mathbf{V \\Sigma^{-1} U}^T \\cdot \\mathbf{f}(\\mathbf{x}_k)\n", + "\\mathbf{\\delta x}_k = -\\mathbf{V \\Sigma}^{-1} \\mathbf{U}^T \\cdot \\mathbf{f}(\\mathbf{x}_k)\n", "$$\n", "Since we have to refactorize $\\mathbf{J}$ at each iteration, the SVD is not an efficient method to calculate a Newton step. However, this process has a geometric interpretation that is useful for model diagnostics and scaling. First, the constraint residual is decomposed into orthogonal components by $\\mathbf{U}$:\n", "$$\n", @@ -2305,7 +1411,7 @@ "$$\n", "Next, these orthogonal components are scaled by the inverse of the associated singular value:\n", "$$\n", - "\\mathbf{\\tilde{s}} = \\Sigma^{-1} \\cdot \\mathbf{s}\n", + "\\mathbf{\\tilde{s}} = \\mathbf{\\Sigma}^{-1} \\cdot \\mathbf{s}\n", "$$\n", "Finally, these independent components are translated into the variable space by $\\mathbf{V}$:\n", "$$\n", @@ -2316,164 +1422,21 @@ "
\n", "NOTE\n", "\n", - "The singular vectors $\\mathbf{u}_j$ and $\\mathbf{v}_j$ are typically dense. In order to link them with specific variables and constraints, a thresholding scheme is applied. The `size_cutoff_in_singular_vector` config option for the `SVDToolbox` controls the magnitude of an entry in $\\mathbf{u}_j$ and $\\mathbf{v}_j$ that is sufficient to link a variable or constraint to the $\\sigma_j$. It is `0.1` by default, but can take on values between about `0.05` and `0.3`. Decrease it to show fewer variables and constraints, increase it to show more variables and constraints.\n", + "The singular vectors $\\mathbf{u}_j$ and $\\mathbf{v}_j$ are typically dense. In order to link them with specific variables and constraints, a thresholding scheme is applied. The `size_cutoff_in_singular_vector` config option for the `SVDToolbox` controls the magnitude of an entry in $\\mathbf{u}_j$ and $\\mathbf{v}_j$ that is sufficient to link a variable or constraint to the $\\sigma_j$. It is `0.1` by default, but typically has a value between `0.05` and `0.3`. Decrease it to show fewer variables and constraints, increase it to show more variables and constraints.\n", "\n", "
\n", "\n", - "So let's create an instance of the `SVDToolbox` and display the variables and constraints associated with the 5 smallest singular values.\n" + "So let's create an instance of the `SVDToolbox` and display the variables and constraints associated with the 5 smallest singular values. (For a full description of all the methods available, look at the [SVD toolbox documentation](https://idaes-pse.readthedocs.io/en/latest/reference_guides/core/util/diagnostics/svd_toolbox.html#svd-toolbox).)\n" ] }, { "cell_type": "code", - "execution_count": 38, + "execution_count": null, "id": "8b62a78b-d7f3-455e-b2c2-4d3ff609f101", "metadata": { "scrolled": true }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "====================================================================================\n", - "Constraints and Variables associated with smallest singular values\n", - "\n", - " 1st Smallest Singular Value: 6.356e-04\n", - "\n", - " Variables:\n", - "\n", - " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_comp[CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_comp[H2O]\n", - "\n", - " Constraints:\n", - "\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2]\n", - "\n", - " 2nd Smallest Singular Value: 2.781e-02\n", - "\n", - " Variables:\n", - "\n", - " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_comp[CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_comp[H2O]\n", - "\n", - " Constraints:\n", - "\n", - " fs.unit.unit_material_balance[0.0,CO2]\n", - " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", - "\n", - " 3rd Smallest Singular Value: 3.679e-02\n", - "\n", - " Variables:\n", - "\n", - " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_comp[CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_comp[H2O]\n", - "\n", - " Constraints:\n", - "\n", - " fs.unit.unit_material_balance[0.0,CO2]\n", - " fs.unit.liquid_phase.material_balances[0.0,MEA]\n", - " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", - " fs.unit.liquid_phase.enthalpy_balances[0.0]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", - " fs.unit.unit_material_balance[0.0,MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,HCO3_-]\n", - " fs.unit.vapor_phase[0.0].sum_mole_frac_out\n", - "\n", - " 4th Smallest Singular Value: 6.842e-02\n", - "\n", - " Variables:\n", - "\n", - " fs.unit.vapor_phase[0.0].flow_mol_phase[Vap]\n", - " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,H2O]\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]\n", - " fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,H2O]\n", - " fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,H2O]\n", - " fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,H2O]\n", - " fs.unit.vapor_phase[0.0].mole_frac_comp[H2O]\n", - " fs.unit.vapor_phase[0.0].flow_mol\n", - "\n", - " Constraints:\n", - "\n", - " fs.unit.unit_material_balance[0.0,CO2]\n", - " fs.unit.liquid_phase.material_balances[0.0,MEA]\n", - " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", - " fs.unit.liquid_phase.enthalpy_balances[0.0]\n", - " fs.unit.unit_material_balance[0.0,MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].total_flow_balance\n", - " fs.unit.vapor_phase[0.0].sum_mole_frac_out\n", - "\n", - " 5th Smallest Singular Value: 7.703e-02\n", - "\n", - " Variables:\n", - "\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,H2O]\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]\n", - " fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,H2O]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_k_eq[bicarbonate]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_k_eq[carbamate]\n", - "\n", - " Constraints:\n", - "\n", - " fs.unit.liquid_phase.material_balances[0.0,MEA]\n", - " fs.unit.unit_material_balance[0.0,MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].total_flow_balance\n", - " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[MEA]\n", - " fs.unit.liquid_phase.properties_out[0.0].sum_mole_frac_out\n", - "\n", - "====================================================================================\n" - ] - } - ], + "outputs": [], "source": [ "st = dt.prepare_svd_toolbox()\n", "# The SVD toolbox displays 10 singular values by default, but we are going to\n", @@ -2483,7 +1446,7 @@ }, { "cell_type": "code", - "execution_count": 39, + "execution_count": null, "id": "4abb105d", "metadata": { "tags": [ @@ -2506,18 +1469,10 @@ }, { "cell_type": "code", - "execution_count": 40, + "execution_count": null, "id": "43b2dd6a-e71b-48ea-a3a8-36d6f73f9f80", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "exp(fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]) == fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,CO2]/(mol/m**3)\n" - ] - } - ], + "outputs": [], "source": [ "print_compact_form(\n", " m.fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[\n", @@ -2538,30 +1493,10 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": null, "id": "5900b815-9725-4334-a108-ae70088b3962", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "====================================================================================\n", - "The following variables are involved in fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2]:\n", - "\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,H2O]: 4.333e-05\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,MEA]: 1.441e-04\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,CO2]: 6.126e-05\n", - " fs.unit.liquid_phase.properties_out[0.0].temperature: 1.576e-04\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]: -5.255e-07\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA]: 5.123e-06\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,CO2]: -1.648e+00\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]: 5.621e-04\n", - "\n", - "====================================================================================\n" - ] - } - ], + "outputs": [], "source": [ "st.display_variables_in_constraint(\n", " m.fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[\n", @@ -2578,7 +1513,7 @@ "
\n", "NOTE\n", "\n", - "At this point of the process, the original author found a shortcoming in the `ModularPropertiesScaler`. No scaling hint was set for the molar density expression, so the expression walker descended into it and came back with an inappropriate nominal value. Revising the scaler to estimate the phase density resulted in a condition number improvement of 1-2 orders of magnitude.\n", + "At this point of the process, the author of this notebook found a shortcoming in the `ModularPropertiesScaler`. No scaling hint was set for the molar density expression, so the expression walker descended into it and came back with an inappropriate nominal value. Revising the scaler to estimate the phase density resulted in a condition number improvement of 1-2 orders of magnitude.\n", "\n", "Remember:\n", "1. Scaling is an iterative process.\n", @@ -2593,25 +1528,16 @@ }, { "cell_type": "code", - "execution_count": 42, + "execution_count": null, "id": "7f9156a6-dbd0-4902-9fa2-ebb4e487f365", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Left hand side value: 1.3698e+00\n", - "CO2 true concentration value: 1.3698e+00\n" - ] - } - ], + "outputs": [], "source": [ "print(\n", - " f\"Left hand side value: {value(exp(m.fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[\"Liq\",\"CO2\"])):.4e}\"\n", + " f\"Left hand side value: {value(exp(m.fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true['Liq','CO2'])):.4e}\"\n", ")\n", "print(\n", - " f\"CO2 true concentration value: {value(m.fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[\"Liq\",\"CO2\"]):.4e}\"\n", + " f\"CO2 true concentration value: {value(m.fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true['Liq','CO2']):.4e}\"\n", ")" ] }, @@ -2625,7 +1551,7 @@ }, { "cell_type": "code", - "execution_count": 43, + "execution_count": null, "id": "33d7953e", "metadata": { "tags": [ @@ -2645,18 +1571,10 @@ }, { "cell_type": "code", - "execution_count": 44, + "execution_count": null, "id": "5166b5b9-99cb-4a21-95d3-ead5992a40ed", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0.0004103666666666667\n" - ] - } - ], + "outputs": [], "source": [ "print(\n", " get_scaling_factor(\n", @@ -2681,25 +1599,16 @@ }, { "cell_type": "code", - "execution_count": 45, + "execution_count": null, "id": "ef7e9960-da1f-43a5-a1f6-6fd84be6896a", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True CO2 mole fraction: 3.410357e-05\n", - "True MEACOO- mole fraction: 2.796223e-02\n" - ] - } - ], + "outputs": [], "source": [ "print(\n", - " f\"True CO2 mole fraction: {m.fs.unit.liquid_phase.properties_out[0].mole_frac_phase_comp_true[\"Liq\",\"CO2\"].value:4e}\"\n", + " f\"True CO2 mole fraction: {m.fs.unit.liquid_phase.properties_out[0].mole_frac_phase_comp_true['Liq','CO2'].value:4e}\"\n", ")\n", "print(\n", - " f\"True MEACOO- mole fraction: {m.fs.unit.liquid_phase.properties_out[0].mole_frac_phase_comp_true[\"Liq\",\"MEACOO_-\"].value:4e}\"\n", + " f\"True MEACOO- mole fraction: {m.fs.unit.liquid_phase.properties_out[0].mole_frac_phase_comp_true['Liq','MEACOO_-'].value:4e}\"\n", ")" ] }, @@ -2713,7 +1622,7 @@ }, { "cell_type": "code", - "execution_count": 46, + "execution_count": null, "id": "f519aee0-4a23-4d3c-a705-e7135ea6fd27", "metadata": {}, "outputs": [], @@ -2745,67 +1654,12 @@ }, { "cell_type": "code", - "execution_count": 47, + "execution_count": null, "id": "ae81a354-ba6e-452a-bb7d-37edbf850d05", "metadata": { "scrolled": true }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Starting initialization routine\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Bubble, dew, and critical point initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Equilibrium temperature initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: State variable initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Phase equilibrium initialization completed.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Property initialization routine finished.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Starting initialization routine\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Bubble, dew, and critical point initialization completed.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Equilibrium temperature initialization completed.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: State variable initialization completed.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Phase equilibrium initialization completed.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Property initialization routine finished.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: Starting initialization routine\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: Bubble, dew, and critical point initialization completed.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: Equilibrium temperature initialization completed.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: State variable initialization completed.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: Phase equilibrium initialization completed.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: Property initialization routine finished.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit: Initialization Complete: optimal - \n", - "====================================================================================\n", - "Model Statistics\n", - "\n", - " Jacobian Condition Number: 2.945E+05\n", - "\n", - "------------------------------------------------------------------------------------\n", - "0 WARNINGS\n", - "\n", - " No warnings found!\n", - "\n", - "------------------------------------------------------------------------------------\n", - "6 Cautions\n", - "\n", - " Caution: 9 Variables with value close to their bounds (abs=1.0E-04, rel=1.0E-04)\n", - " Caution: 14 Variables with value close to zero (tol=1.0E-08)\n", - " Caution: 27 Variables with extreme value (<1.0E-04 or >1.0E+04)\n", - " Caution: 2 Constraints with mismatched terms\n", - " Caution: 1 Constraint with potential cancellation of terms\n", - " Caution: 16 extreme Jacobian Entries (<1.0E-04 or >1.0E+04)\n", - "\n", - "------------------------------------------------------------------------------------\n", - "Suggested next steps:\n", - "\n", - " If you still have issues converging your model consider:\n", - "\n", - " prepare_degeneracy_hunter()\n", - " prepare_svd_toolbox()\n", - "\n", - "====================================================================================\n" - ] - } - ], + "outputs": [], "source": [ "scaler_obj = SolventReboilerScaler(overwrite=True)\n", "scaler_obj.scale_model(m.fs.unit)\n", @@ -2816,7 +1670,7 @@ }, { "cell_type": "code", - "execution_count": 48, + "execution_count": null, "id": "21820a85", "metadata": { "tags": [ @@ -2838,158 +1692,12 @@ }, { "cell_type": "code", - "execution_count": 49, + "execution_count": null, "id": "baeb6028-71fb-46c9-ac73-ddaf75f1f7d4", "metadata": { "scrolled": true }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "====================================================================================\n", - "Constraints and Variables associated with smallest singular values\n", - "\n", - " 1st Smallest Singular Value: 6.965e-04\n", - "\n", - " Variables:\n", - "\n", - " fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[bicarbonate]\n", - " fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[carbamate]\n", - " fs.unit.liquid_phase.properties_out[0.0].apparent_inherent_reaction_extent[carbamate]\n", - "\n", - " Constraints:\n", - "\n", - " fs.unit.unit_material_balance[0.0,CO2]\n", - " fs.unit.unit_material_balance[0.0,H2O]\n", - " fs.unit.liquid_phase.material_balances[0.0,H2O]\n", - " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].total_flow_balance\n", - " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", - "\n", - " 2nd Smallest Singular Value: 1.047e-03\n", - "\n", - " Variables:\n", - "\n", - " fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[carbamate]\n", - " fs.unit.liquid_phase.properties_out[0.0].apparent_inherent_reaction_extent[carbamate]\n", - "\n", - " Constraints:\n", - "\n", - " fs.unit.unit_material_balance[0.0,CO2]\n", - " fs.unit.unit_material_balance[0.0,H2O]\n", - " fs.unit.liquid_phase.material_balances[0.0,H2O]\n", - " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEA_+]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA_+]\n", - "\n", - " 3rd Smallest Singular Value: 4.024e-03\n", - "\n", - " Variables:\n", - "\n", - " fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[bicarbonate]\n", - " fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[carbamate]\n", - "\n", - " Constraints:\n", - "\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,H2O]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,H2O]\n", - " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,H2O]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", - "\n", - " 4th Smallest Singular Value: 5.218e-03\n", - "\n", - " Variables:\n", - "\n", - " fs.unit.liquid_phase.properties_out[0.0].apparent_inherent_reaction_extent[bicarbonate]\n", - "\n", - " Constraints:\n", - "\n", - " fs.unit.unit_material_balance[0.0,CO2]\n", - " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,HCO3_-]\n", - "\n", - " 5th Smallest Singular Value: 5.115e-02\n", - "\n", - " Variables:\n", - "\n", - " fs.unit.vapor_phase[0.0].flow_mol_phase[Vap]\n", - " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_comp[CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_comp[H2O]\n", - " fs.unit.vapor_phase[0.0].flow_mol\n", - "\n", - " Constraints:\n", - "\n", - " fs.unit.unit_material_balance[0.0,CO2]\n", - " fs.unit.unit_material_balance[0.0,H2O]\n", - " fs.unit.liquid_phase.material_balances[0.0,H2O]\n", - " fs.unit.liquid_phase.material_balances[0.0,MEA]\n", - " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEA_+]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEA]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA_+]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA]\n", - " fs.unit.unit_material_balance[0.0,MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].total_flow_balance\n", - " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA_+]\n", - " fs.unit.liquid_phase.properties_out[0.0].sum_mole_frac_out\n", - " fs.unit.vapor_phase[0.0].sum_mole_frac_out\n", - "\n", - "====================================================================================\n" - ] - } - ], + "outputs": [], "source": [ "st = dt.prepare_svd_toolbox()\n", "st.display_underdetermined_variables_and_constraints([1, 2, 3, 4, 5])" @@ -2997,9 +1705,13 @@ }, { "cell_type": "code", - "execution_count": 50, + "execution_count": null, "id": "9f9c565b", - "metadata": {}, + "metadata": { + "tags": [ + "testing" + ] + }, "outputs": [], "source": [ "assert st.s[0] == pytest.approx(6.965e-04, rel=1e-2)\n", @@ -3021,244 +1733,12 @@ }, { "cell_type": "code", - "execution_count": 51, + "execution_count": null, "id": "28633b75-9a64-4fe6-b27c-c93498413f47", "metadata": { "scrolled": true }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Scaling Factors for block fs.unit\n", - "\n", - "Variable Scaling Factor Value Scaled Value\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol 1.250E-02 8.389E+01 1.049E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[H2O] 1.000E+00 8.589E-01 8.589E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[MEA] 1.000E+01 1.085E-01 1.085E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[CO2] 1.000E+01 3.260E-02 3.260E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].temperature 3.333E-03 3.925E+02 1.308E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol 1.250E-02 7.410E+01 9.263E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O] 1.000E+00 8.487E-01 8.487E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] 1.000E+01 1.228E-01 1.228E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[CO2] 1.000E+01 2.851E-02 2.851E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].temperature 3.333E-03 3.938E+02 1.313E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", - "fs.unit.vapor_phase[0.0].flow_mol 1.000E-01 9.785E+00 9.785E-01\n", - "fs.unit.vapor_phase[0.0].mole_frac_comp[CO2] 1.000E+01 6.361E-02 6.361E-01\n", - "fs.unit.vapor_phase[0.0].mole_frac_comp[H2O] 1.000E+01 9.364E-01 9.364E+00\n", - "fs.unit.vapor_phase[0.0].mole_frac_comp[N2] 1.000E+01 1.022E-09 1.022E-08\n", - "fs.unit.vapor_phase[0.0].mole_frac_comp[O2] 1.000E+01 1.022E-09 1.022E-08\n", - "fs.unit.vapor_phase[0.0].temperature 3.333E-03 3.938E+02 1.313E+00\n", - "fs.unit.vapor_phase[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", - "fs.unit.liquid_phase.heat[0.0] 8.763E-07 4.306E+05 3.773E-01\n", - "fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,H2O] 1.250E-02 -9.163E+00 -1.145E-01\n", - "fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,MEA] 1.250E-01 0.000E+00 0.000E+00\n", - "fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,CO2] 1.250E-01 -6.224E-01 -7.780E-02\n", - "fs.unit.liquid_phase.enthalpy_transfer[0.0] 8.763E-07 -3.209E+04 -2.812E-02\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase[Liq] 1.250E-02 8.389E+01 1.049E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp[Liq,H2O] 1.000E+00 8.589E-01 8.589E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp[Liq,MEA] 1.000E+01 1.085E-01 1.085E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp[Liq,CO2] 1.000E+01 3.260E-02 3.260E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].phase_frac[Liq] 1.000E+00 1.000E+00 1.000E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,MEACOO_-] 1.250E-01 2.550E+00 3.187E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,HCO3_-] 1.250E+00 1.785E-01 2.231E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,MEA_+] 1.250E-01 2.728E+00 3.410E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,H2O] 1.250E-02 7.187E+01 8.984E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,MEA] 1.250E-01 3.825E+00 4.781E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,CO2] 1.250E+02 6.803E-03 8.504E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,MEACOO_-] 1.000E+01 3.141E-02 3.141E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,HCO3_-] 1.000E+02 2.199E-03 2.199E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,MEA_+] 1.000E+01 3.361E-02 3.361E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,H2O] 1.000E+00 8.856E-01 8.856E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,MEA] 1.000E+01 4.712E-02 4.712E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,CO2] 1.000E+04 8.383E-05 8.383E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[bicarbonate] 1.250E+02 1.785E-01 2.231E+01\n", - "fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[carbamate] 1.250E+02 2.550E+00 3.187E+02\n", - "fs.unit.liquid_phase.properties_in[0.0].log_k_eq[bicarbonate] None -7.578E+00 -7.578E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].log_k_eq[carbamate] None -1.985E+00 -1.985E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-] 1.000E+00 7.168E+00 7.168E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-] 1.000E+00 4.509E+00 4.509E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+] 1.000E+00 7.236E+00 7.236E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,H2O] 1.000E+00 1.051E+01 1.051E+01\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEA] 1.000E+00 7.573E+00 7.573E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,CO2] 1.000E+00 1.242E+00 1.242E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase[Liq] 1.250E-02 7.410E+01 9.263E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,H2O] 1.000E+00 8.487E-01 8.487E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,MEA] 1.000E+01 1.228E-01 1.228E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,CO2] 1.000E+01 2.851E-02 2.851E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].phase_frac[Liq] 1.000E+00 1.000E+00 1.000E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,MEACOO_-] 1.250E-01 2.013E+00 2.516E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,HCO3_-] 1.250E+00 9.684E-02 1.210E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,MEA_+] 1.250E-01 2.110E+00 2.637E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,H2O] 1.250E-02 6.279E+01 7.849E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,MEA] 1.250E-01 4.979E+00 6.224E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,CO2] 1.250E+02 2.455E-03 3.069E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,MEACOO_-] 1.000E+01 2.796E-02 2.796E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,HCO3_-] 1.000E+02 1.345E-03 1.345E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,MEA_+] 1.000E+01 2.931E-02 2.931E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,H2O] 1.000E+00 8.722E-01 8.722E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,MEA] 1.000E+01 6.916E-02 6.916E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,CO2] 1.000E+04 3.410E-05 3.410E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].apparent_inherent_reaction_extent[bicarbonate] 1.250E+02 9.684E-02 1.210E+01\n", - "fs.unit.liquid_phase.properties_out[0.0].apparent_inherent_reaction_extent[carbamate] 1.250E+02 2.013E+00 2.516E+02\n", - "fs.unit.liquid_phase.properties_out[0.0].log_k_eq[bicarbonate] None -7.648E+00 -7.648E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].log_k_eq[carbamate] None -2.079E+00 -2.079E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-] 1.000E+00 7.024E+00 7.024E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-] 1.000E+00 3.989E+00 3.989E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+] 1.000E+00 7.071E+00 7.071E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,H2O] 1.000E+00 1.046E+01 1.046E+01\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA] 1.000E+00 7.929E+00 7.929E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2] 1.000E+00 3.147E-01 3.147E-01\n", - "fs.unit.vapor_phase[0.0].flow_mol_phase[Vap] 1.000E-01 9.785E+00 9.785E-01\n", - "fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2] 1.000E+01 6.361E-02 6.361E-01\n", - "fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O] 1.000E+01 9.364E-01 9.364E+00\n", - "fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,N2] 1.000E+01 1.022E-09 1.022E-08\n", - "fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,O2] 1.000E+01 1.022E-09 1.022E-08\n", - "fs.unit.vapor_phase[0.0].phase_frac[Vap] 1.000E+00 1.000E+00 1.000E+00\n", - "\n", - "Constraint Scaling Factor\n", - "fs.unit.unit_material_balance[0.0,CO2] 1.250E-01\n", - "fs.unit.unit_material_balance[0.0,H2O] 1.250E-02\n", - "fs.unit.unit_material_balance[0.0,N2] 1.000E+00\n", - "fs.unit.unit_material_balance[0.0,O2] 1.000E+00\n", - "fs.unit.unit_material_balance[0.0,MEA] 1.250E-01\n", - "fs.unit.unit_phase_equilibrium[0.0,CO2] 1.000E-04\n", - "fs.unit.unit_phase_equilibrium[0.0,H2O] 1.000E-04\n", - "fs.unit.unit_temperature_equality[0.0] 3.333E-03\n", - "fs.unit.unit_enthalpy_balance[0.0] 5.463E-06\n", - "fs.unit.unit_pressure_balance[0.0] 1.000E-05\n", - "fs.unit.liquid_phase.material_balances[0.0,H2O] 1.250E-02\n", - "fs.unit.liquid_phase.material_balances[0.0,MEA] 1.250E-01\n", - "fs.unit.liquid_phase.material_balances[0.0,CO2] 1.250E-01\n", - "fs.unit.liquid_phase.enthalpy_balances[0.0] 8.763E-07\n", - "fs.unit.liquid_phase.pressure_balance[0.0] 1.000E-05\n", - "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEACOO_-] 1.250E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,HCO3_-] 1.250E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEA_+] 1.250E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,H2O] 1.250E-02\n", - "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEA] 1.250E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2] 1.250E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEACOO_-] 1.250E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,HCO3_-] 1.250E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEA_+] 1.250E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,H2O] 1.250E-02\n", - "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEA] 1.250E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,CO2] 1.250E+02\n", - "fs.unit.liquid_phase.properties_in[0.0].total_flow_balance 1.250E-02\n", - "fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[H2O] 1.000E+01\n", - "fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[MEA] 1.000E+01\n", - "fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2] 1.000E+01\n", - "fs.unit.liquid_phase.properties_in[0.0].phase_fraction_constraint[Liq] 1.000E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].log_k_eq_constraint[bicarbonate] None\n", - "fs.unit.liquid_phase.properties_in[0.0].log_k_eq_constraint[carbamate] None\n", - "fs.unit.liquid_phase.properties_in[0.0].inherent_equilibrium_constraint[bicarbonate] 1.000E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].inherent_equilibrium_constraint[carbamate] 1.000E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-] 2.377E-04\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-] 2.377E-03\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA_+] 2.377E-04\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,H2O] 2.377E-05\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA] 2.377E-04\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2] 2.377E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEACOO_-] 1.250E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,HCO3_-] 1.250E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA_+] 1.250E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,H2O] 1.250E-02\n", - "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA] 1.250E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2] 1.250E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEACOO_-] 1.250E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,HCO3_-] 1.250E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEA_+] 1.250E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,H2O] 1.250E-02\n", - "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEA] 1.250E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,CO2] 1.250E+02\n", - "fs.unit.liquid_phase.properties_out[0.0].sum_mole_frac_out 1.000E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].total_flow_balance 1.250E-02\n", - "fs.unit.liquid_phase.properties_out[0.0].component_flow_balances[H2O] 1.000E+01\n", - "fs.unit.liquid_phase.properties_out[0.0].component_flow_balances[MEA] 1.000E+01\n", - "fs.unit.liquid_phase.properties_out[0.0].component_flow_balances[CO2] 1.000E+01\n", - "fs.unit.liquid_phase.properties_out[0.0].phase_fraction_constraint[Liq] 1.000E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].log_k_eq_constraint[bicarbonate] None\n", - "fs.unit.liquid_phase.properties_out[0.0].log_k_eq_constraint[carbamate] None\n", - "fs.unit.liquid_phase.properties_out[0.0].inherent_equilibrium_constraint[bicarbonate] 1.000E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].inherent_equilibrium_constraint[carbamate] 1.000E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-] 2.377E-04\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-] 2.377E-03\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA_+] 2.377E-04\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,H2O] 2.377E-05\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA] 2.377E-04\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2] 2.377E-01\n", - "fs.unit.vapor_phase[0.0].sum_mole_frac_out 1.000E+00\n", - "fs.unit.vapor_phase[0.0].total_flow_balance 1.000E-01\n", - "fs.unit.vapor_phase[0.0].component_flow_balances[CO2] 1.000E+01\n", - "fs.unit.vapor_phase[0.0].component_flow_balances[H2O] 1.000E+01\n", - "fs.unit.vapor_phase[0.0].component_flow_balances[N2] 1.000E+01\n", - "fs.unit.vapor_phase[0.0].component_flow_balances[O2] 1.000E+01\n", - "fs.unit.vapor_phase[0.0].phase_fraction_constraint[Vap] 1.000E+00\n", - "\n", - "Expression Scaling Hint\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp[Liq,H2O] 1.250E-02\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp[Liq,MEA] 1.250E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp[Liq,CO2] 1.250E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].k_eq[bicarbonate] None\n", - "fs.unit.liquid_phase.properties_in[0.0].k_eq[carbamate] None\n", - "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,MEACOO_-] None\n", - "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,HCO3_-] None\n", - "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,MEA_+] None\n", - "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,H2O] None\n", - "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,MEA] None\n", - "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,CO2] None\n", - "fs.unit.liquid_phase.properties_in[0.0].dens_mol_phase[Liq] 2.377E-05\n", - "fs.unit.liquid_phase.properties_in[0.0].vol_mol_phase[Liq] 4.206E+04\n", - "fs.unit.liquid_phase.properties_in[0.0]._enthalpy_flow_term[Liq] None\n", - "fs.unit.liquid_phase.properties_in[0.0].enth_mol_phase[Liq] 7.010E-05\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_comp[H2O] 1.250E-02\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_comp[MEA] 1.250E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_comp[CO2] 1.250E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp[Liq,H2O] 1.250E-02\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp[Liq,MEA] 1.250E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp[Liq,CO2] 1.250E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].k_eq[bicarbonate] None\n", - "fs.unit.liquid_phase.properties_out[0.0].k_eq[carbamate] None\n", - "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,MEACOO_-] None\n", - "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,HCO3_-] None\n", - "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,MEA_+] None\n", - "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,H2O] None\n", - "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,MEA] None\n", - "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,CO2] None\n", - "fs.unit.liquid_phase.properties_out[0.0].dens_mol_phase[Liq] 2.377E-05\n", - "fs.unit.liquid_phase.properties_out[0.0].vol_mol_phase[Liq] 4.206E+04\n", - "fs.unit.liquid_phase.properties_out[0.0]._enthalpy_flow_term[Liq] None\n", - "fs.unit.liquid_phase.properties_out[0.0].enth_mol_phase[Liq] 7.010E-05\n", - "fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[Liq,H2O] None\n", - "fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[Liq,MEA] None\n", - "fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[Liq,CO2] None\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_comp[H2O] 1.250E-02\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_comp[MEA] 1.250E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_comp[CO2] 1.250E-01\n", - "fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,CO2] 1.000E+00\n", - "fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,H2O] 1.000E+00\n", - "fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,N2] 1.000E+00\n", - "fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,O2] 1.000E+00\n", - "fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,CO2] None\n", - "fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,H2O] None\n", - "fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,N2] None\n", - "fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,O2] None\n", - "fs.unit.vapor_phase[0.0]._enthalpy_flow_term[Vap] None\n", - "fs.unit.vapor_phase[0.0].enth_mol_phase[Vap] 5.463E-05\n", - "fs.unit.vapor_phase[0.0].enth_mol_phase_comp[Vap,CO2] 3.787E-05\n", - "fs.unit.vapor_phase[0.0].enth_mol_phase_comp[Vap,H2O] 9.249E-05\n", - "fs.unit.vapor_phase[0.0].enth_mol_phase_comp[Vap,N2] 5.950E-05\n", - "fs.unit.vapor_phase[0.0].enth_mol_phase_comp[Vap,O2] 5.208E-05\n", - "fs.unit.vapor_phase[0.0].flow_mol_comp[CO2] 1.000E+00\n", - "fs.unit.vapor_phase[0.0].flow_mol_comp[H2O] 1.000E+00\n", - "fs.unit.vapor_phase[0.0].flow_mol_comp[N2] 1.000E+00\n", - "fs.unit.vapor_phase[0.0].flow_mol_comp[O2] 1.000E+00\n" - ] - } - ], + "outputs": [], "source": [ "from idaes.core.scaling.util import report_scaling_factors\n", "\n", @@ -3270,7 +1750,7 @@ "id": "31cf3ac5-612f-46db-96b8-044057bbd808", "metadata": {}, "source": [ - "Most variable values have scaled values within a couple orders of magnitude of one, which is what we like. The outliers are inherent reaction extents, which we already know are a bit problematic, and variables corresponding to the components $\\text{N}_2$ and $\\text{O}_2$, which are present in the vapor property package but not the vapor stream.\n", + "Most variable values have scaled values within a couple orders of magnitude of one, which is what we like. The outliers are inherent reaction extents, which we already know are a bit problematic, and variables corresponding to the components $\\text{N}_2$ and $\\text{O}_2$. Because those components are present in the vapor property package but not the vapor stream, they should not be scaled to order one, and their current scaling factors are fine.\n", "\n", "We have reduced the condition number to $3 \\cdot 10^5$, which is not quite as low as we would have liked, but is a vast improvement over the value $3 \\cdot 10^{13}$, which we started out with. " ] @@ -3312,7 +1792,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.12" + "version": "3.10.20" } }, "nbformat": 4, diff --git a/idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques_doc.ipynb b/idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques_doc.ipynb index f7000025..2d692008 100644 --- a/idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques_doc.ipynb +++ b/idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques_doc.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -32,532 +32,28 @@ "\n", "## Introduction\n", "\n", - "This notebook is intended to give the user further insight into how the scaling toolbox can be used to improve robustness. A large portion of the material is an adaptation of [Allan, Ostace, and Polly (2025)](#references). By the end of this study, the user should understand:\n", + "This notebook is intended to give the user further insight into how the scaling toolbox can be used to improve robustness. It is a followup to a [previous notebook](./scaler_workshop_doc.md) about how to create scaler objects in IDAES, and it assumes some familiarity with the material contained therein. A large portion of the material is an adaptation of [Allan, Ostace, and Polly (2025)](#references). By the end of this study, the user should understand:\n", "* How a default scaler object can be specified for a property package\n", "* How to set default scaling factors for property package variables\n", + "* How to use the `DiagnosticsToolbox` to troubleshoot saling issues\n", "* The strengths and weaknesses of the ``NominalValueExpressionWalker`` used in ``CustomScalerBase.get_sum_terms_nominal_values`` and ``CustomScalerBase.get_expression_nominal_value`` for use in constraint scaling\n", "* How to use the ``SVDToolbox`` to troubleshoot scaling issues\n", "\n", "## Step 1: Set Up Test Case\n", - "We will use the `SolventReboiler` unit model as a case study. It is a component in a stripping column used for solvent regeneration. It is modeled as a single equilibrium stage with an external heat duty. The inlet stream is entirely liquid, while it has both boilup and bottoms outlet streams. The liquid and vapor phases use different configurations of the modular property framework.\n", + "We will use the `SolventReboiler` unit model as a case study. It is a component in a stripping column used for solvent regeneration. It is modeled as a single equilibrium stage with an external heat duty. The inlet stream is entirely liquid, while it has both boilup and bottoms outlet streams. The liquid and vapor phases use different configurations of the [modular property framework](https://idaes-pse.readthedocs.io/en/latest/explanations/components/property_package/general/index.html).\n", "\n", "First, we set up and attempt to initialize the unit model." ] }, { "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2026-04-29 17:11:54 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Starting initialization routine\n", - "2026-04-29 17:11:54 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Bubble, dew, and critical point initialization completed.\n", - "2026-04-29 17:11:54 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Equilibrium temperature initialization completed.\n", - "2026-04-29 17:11:54 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: State variable initialization completed.\n", - "2026-04-29 17:11:54 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Phase equilibrium initialization completed.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Ipopt 3.13.2: linear_solver=\"ma57\"\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: max_iter=200\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: nlp_scaling_method=\"gradient-based\"\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: tol=1e-06\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: ******************************************************************************\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: For more information visit http://projects.coin-or.org/Ipopt\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: This version of Ipopt was compiled from source code available at\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: for large-scale scientific computation. All technical papers, sales and\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: publicity material resulting from use of the HSL codes within IPOPT must\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: contain the following acknowledgement:\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: HSL, a collection of Fortran codes for large-scale scientific\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: computation. See http://www.hsl.rl.ac.uk.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: ******************************************************************************\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of nonzeros in equality constraint Jacobian...: 74\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of nonzeros in inequality constraint Jacobian.: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of nonzeros in Lagrangian Hessian.............: 42\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Total number of variables............................: 18\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: variables with only lower bounds: 6\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: variables with lower and upper bounds: 12\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: variables with only upper bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Total number of equality constraints.................: 18\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Total number of inequality constraints...............: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: inequality constraints with only lower bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: inequality constraints with lower and upper bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: inequality constraints with only upper bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 0 0.0000000e+00 4.13e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Reallocating memory for MA57: lfact (1377)\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 1 0.0000000e+00 4.05e+02 1.89e+12 -1.0 6.07e+01 - 1.92e-01 1.98e-02H 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 2 0.0000000e+00 1.62e+04 1.56e+17 -1.0 8.76e+01 - 1.69e-01 5.07e-01H 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 3 0.0000000e+00 1.62e+04 1.55e+17 -1.0 4.59e+01 - 1.21e-07 3.23e-03H 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 4 0.0000000e+00 2.15e+04 1.93e+17 -1.0 4.88e+01 - 1.06e-02 9.12e-01h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Reallocating memory for MA57: lfact (1542)\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 5 0.0000000e+00 2.15e+04 1.93e+17 -1.0 3.05e+02 - 4.08e-04 6.58e-04h 2\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Reallocating memory for MA57: lfact (1662)\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 6 0.0000000e+00 2.09e+04 1.87e+17 -1.0 1.11e+01 - 4.04e-03 3.08e-02h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 7 0.0000000e+00 1.50e+04 1.37e+17 -1.0 1.37e+01 - 1.44e-04 3.14e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 8 0.0000000e+00 1.49e+04 1.36e+17 -1.0 4.21e+00 - 5.37e-01 9.11e-03h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 9 0.0000000e+00 1.49e+04 1.36e+17 -1.0 4.10e+00 - 9.86e-01 9.35e-05h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 10r 0.0000000e+00 1.49e+04 1.00e+03 1.6 0.00e+00 - 0.00e+00 4.68e-07R 2\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 11r 0.0000000e+00 5.25e+03 2.22e+03 1.6 3.13e+04 - 3.88e-03 1.14e-03f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 12r 0.0000000e+00 5.08e+03 4.24e+04 1.6 1.22e+03 - 1.88e-01 5.18e-03f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 13r 0.0000000e+00 4.77e+03 3.36e+04 1.6 6.27e+01 - 3.06e-02 6.76e-02f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 14r 0.0000000e+00 4.33e+03 1.32e+05 1.6 8.06e+00 - 5.05e-01 9.81e-02f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 15r 0.0000000e+00 4.19e+03 1.12e+05 1.6 9.20e+00 - 3.38e-01 3.25e-02f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 16r 0.0000000e+00 1.89e+03 5.50e+04 1.6 2.54e+00 - 8.42e-02 7.08e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 17r 0.0000000e+00 1.72e+03 4.73e+04 1.6 7.82e+00 - 2.36e-01 1.01e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 18r 0.0000000e+00 1.14e+03 2.84e+04 1.6 1.92e+00 - 7.10e-01 4.02e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 19r 0.0000000e+00 1.06e+03 2.92e+04 1.6 5.12e+00 - 7.85e-01 7.79e-02f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 20r 0.0000000e+00 2.69e+02 3.66e+03 1.6 5.52e-01 - 1.00e+00 9.33e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 21r 0.0000000e+00 1.64e+01 3.96e+02 0.9 1.63e-01 - 9.76e-01 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 22r 0.0000000e+00 6.87e-01 1.09e+02 0.2 3.52e-02 - 1.00e+00 9.59e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 23r 0.0000000e+00 2.05e-01 8.47e+03 -0.5 2.72e-03 - 1.00e+00 6.98e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 24r 0.0000000e+00 1.34e-03 2.18e-01 -0.5 1.87e-03 - 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 25r 0.0000000e+00 1.29e-02 1.88e+02 -2.9 3.36e-04 - 1.00e+00 9.47e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 26r 0.0000000e+00 2.90e-06 4.04e-05 -2.9 7.48e-05 - 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of Iterations....: 26\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: (scaled) (unscaled)\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Constraint violation....: 2.1131334015933589e-08 2.8957967970200116e-06\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Overall NLP error.......: 2.1131334015933589e-08 2.8957967970200116e-06\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of objective function evaluations = 34\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of objective gradient evaluations = 12\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of equality constraint evaluations = 36\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of inequality constraint evaluations = 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of equality constraint Jacobian evaluations = 28\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of inequality constraint Jacobian evaluations = 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of Lagrangian Hessian evaluations = 26\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Total CPU secs in IPOPT (w/o function evaluations) = 0.006\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Total CPU secs in NLP function evaluations = 0.000\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: EXIT: Optimal Solution Found.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Property initialization routine finished.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Starting initialization routine\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Bubble, dew, and critical point initialization completed.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Equilibrium temperature initialization completed.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: State variable initialization completed.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Phase equilibrium initialization completed.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Ipopt 3.13.2: linear_solver=\"ma57\"\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: max_iter=200\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: nlp_scaling_method=\"gradient-based\"\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: tol=1e-06\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: ******************************************************************************\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: For more information visit http://projects.coin-or.org/Ipopt\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: This version of Ipopt was compiled from source code available at\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: for large-scale scientific computation. All technical papers, sales and\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: publicity material resulting from use of the HSL codes within IPOPT must\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: contain the following acknowledgement:\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: HSL, a collection of Fortran codes for large-scale scientific\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: computation. See http://www.hsl.rl.ac.uk.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: ******************************************************************************\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of nonzeros in equality constraint Jacobian...: 74\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of nonzeros in inequality constraint Jacobian.: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of nonzeros in Lagrangian Hessian.............: 42\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Total number of variables............................: 18\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: variables with only lower bounds: 6\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: variables with lower and upper bounds: 12\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: variables with only upper bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Total number of equality constraints.................: 18\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Total number of inequality constraints...............: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: inequality constraints with only lower bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: inequality constraints with lower and upper bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: inequality constraints with only upper bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 0 0.0000000e+00 4.13e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Reallocating memory for MA57: lfact (1377)\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 1 0.0000000e+00 4.05e+02 1.89e+12 -1.0 6.07e+01 - 1.92e-01 1.98e-02H 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 2 0.0000000e+00 1.62e+04 1.56e+17 -1.0 8.76e+01 - 1.69e-01 5.07e-01H 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 3 0.0000000e+00 1.62e+04 1.55e+17 -1.0 4.59e+01 - 1.21e-07 3.23e-03H 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 4 0.0000000e+00 2.15e+04 1.93e+17 -1.0 4.88e+01 - 1.06e-02 9.12e-01h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Reallocating memory for MA57: lfact (1542)\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 5 0.0000000e+00 2.15e+04 1.93e+17 -1.0 3.05e+02 - 4.08e-04 6.58e-04h 2\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Reallocating memory for MA57: lfact (1662)\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 6 0.0000000e+00 2.09e+04 1.87e+17 -1.0 1.11e+01 - 4.04e-03 3.08e-02h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 7 0.0000000e+00 1.50e+04 1.37e+17 -1.0 1.37e+01 - 1.44e-04 3.14e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 8 0.0000000e+00 1.49e+04 1.36e+17 -1.0 4.21e+00 - 5.37e-01 9.11e-03h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 9 0.0000000e+00 1.49e+04 1.36e+17 -1.0 4.10e+00 - 9.86e-01 9.35e-05h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 10r 0.0000000e+00 1.49e+04 1.00e+03 1.6 0.00e+00 - 0.00e+00 4.68e-07R 2\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 11r 0.0000000e+00 5.25e+03 2.22e+03 1.6 3.13e+04 - 3.88e-03 1.14e-03f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 12r 0.0000000e+00 5.08e+03 4.24e+04 1.6 1.22e+03 - 1.88e-01 5.18e-03f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 13r 0.0000000e+00 4.77e+03 3.36e+04 1.6 6.27e+01 - 3.06e-02 6.76e-02f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 14r 0.0000000e+00 4.33e+03 1.32e+05 1.6 8.06e+00 - 5.05e-01 9.81e-02f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 15r 0.0000000e+00 4.19e+03 1.12e+05 1.6 9.20e+00 - 3.38e-01 3.25e-02f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 16r 0.0000000e+00 1.89e+03 5.50e+04 1.6 2.54e+00 - 8.42e-02 7.08e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 17r 0.0000000e+00 1.72e+03 4.73e+04 1.6 7.82e+00 - 2.36e-01 1.01e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 18r 0.0000000e+00 1.14e+03 2.84e+04 1.6 1.92e+00 - 7.10e-01 4.02e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 19r 0.0000000e+00 1.06e+03 2.92e+04 1.6 5.12e+00 - 7.85e-01 7.79e-02f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 20r 0.0000000e+00 2.69e+02 3.66e+03 1.6 5.52e-01 - 1.00e+00 9.33e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 21r 0.0000000e+00 1.64e+01 3.96e+02 0.9 1.63e-01 - 9.76e-01 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 22r 0.0000000e+00 6.87e-01 1.09e+02 0.2 3.52e-02 - 1.00e+00 9.59e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 23r 0.0000000e+00 2.05e-01 8.47e+03 -0.5 2.72e-03 - 1.00e+00 6.98e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 24r 0.0000000e+00 1.34e-03 2.18e-01 -0.5 1.87e-03 - 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 25r 0.0000000e+00 1.29e-02 1.88e+02 -2.9 3.36e-04 - 1.00e+00 9.47e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 26r 0.0000000e+00 2.90e-06 4.04e-05 -2.9 7.48e-05 - 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of Iterations....: 26\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: (scaled) (unscaled)\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Constraint violation....: 2.1131334015933589e-08 2.8957967970200116e-06\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Overall NLP error.......: 2.1131334015933589e-08 2.8957967970200116e-06\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of objective function evaluations = 34\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of objective gradient evaluations = 12\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of equality constraint evaluations = 36\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of inequality constraint evaluations = 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of equality constraint Jacobian evaluations = 28\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of inequality constraint Jacobian evaluations = 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of Lagrangian Hessian evaluations = 26\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Total CPU secs in IPOPT (w/o function evaluations) = 0.008\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Total CPU secs in NLP function evaluations = 0.000\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: EXIT: Optimal Solution Found.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Property initialization routine finished.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase: Control volume properties initialization complete\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase: Control volume reactions initialization complete\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit: Initialization Step 1 Complete.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: Starting initialization routine\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: Bubble, dew, and critical point initialization completed.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: Equilibrium temperature initialization completed.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: State variable initialization completed.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: Phase equilibrium initialization completed.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: Property initialization routine finished.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit: Initialization Step 2 Complete.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Ipopt 3.13.2: linear_solver=\"ma57\"\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: max_iter=200\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: nlp_scaling_method=\"gradient-based\"\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: tol=1e-06\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: ******************************************************************************\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: For more information visit http://projects.coin-or.org/Ipopt\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: This version of Ipopt was compiled from source code available at\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: for large-scale scientific computation. All technical papers, sales and\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: publicity material resulting from use of the HSL codes within IPOPT must\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: contain the following acknowledgement:\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: HSL, a collection of Fortran codes for large-scale scientific\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: computation. See http://www.hsl.rl.ac.uk.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: ******************************************************************************\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of nonzeros in equality constraint Jacobian...: 231\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of nonzeros in inequality constraint Jacobian.: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of nonzeros in Lagrangian Hessian.............: 149\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Total number of variables............................: 51\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: variables with only lower bounds: 12\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: variables with lower and upper bounds: 34\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: variables with only upper bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Total number of equality constraints.................: 51\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Total number of inequality constraints...............: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: inequality constraints with only lower bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: inequality constraints with lower and upper bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: inequality constraints with only upper bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 0 0.0000000e+00 3.62e+06 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Reallocating memory for MA57: lfact (3323)\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 1 0.0000000e+00 3.00e+06 1.18e+02 -1.0 3.71e+04 - 5.00e-01 1.73e-01h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 2 0.0000000e+00 2.99e+06 3.06e+03 -1.0 2.81e+04 - 8.76e-01 3.30e-03h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 3 0.0000000e+00 2.99e+06 8.95e+07 -1.0 2.80e+04 - 9.79e-01 3.34e-05h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 4r 0.0000000e+00 2.99e+06 1.00e+03 1.9 0.00e+00 - 0.00e+00 1.74e-07R 2\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 5r 0.0000000e+00 2.93e+06 9.98e+02 1.9 3.19e+04 - 2.43e-03 2.43e-03f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 6r 0.0000000e+00 2.86e+06 1.02e+03 1.2 3.69e+02 - 3.26e-01 2.09e-03f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 7r 0.0000000e+00 2.23e+06 1.04e+03 1.2 2.85e+02 - 1.93e-01 8.65e-02f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 8r 0.0000000e+00 1.90e+06 1.12e+05 1.2 2.94e+02 - 7.31e-02 2.42e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 9r 0.0000000e+00 1.44e+06 7.08e+04 1.2 1.51e+02 - 7.79e-01 2.13e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 10r 0.0000000e+00 1.21e+06 3.79e+04 1.2 1.60e+00 2.0 4.46e-01 1.46e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 11r 0.0000000e+00 7.63e+04 1.14e+04 1.2 9.97e+01 - 3.46e-01 9.00e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 12r 0.0000000e+00 4.57e+04 2.79e+04 1.2 8.49e+01 - 1.00e+00 2.61e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 13r 0.0000000e+00 5.79e+04 9.55e+03 1.2 3.35e+01 - 1.00e+00 7.44e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 14r 0.0000000e+00 1.21e+05 1.45e+04 1.2 2.11e+01 - 1.00e+00 1.00e+00h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 15r 0.0000000e+00 2.24e+05 6.34e+02 1.2 7.86e+00 - 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 16r 0.0000000e+00 2.19e+05 4.22e+03 0.5 1.77e+00 - 1.00e+00 9.43e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 17r 0.0000000e+00 3.93e+05 6.53e+02 0.5 1.02e+02 - 5.02e-01 4.46e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 18r 0.0000000e+00 4.24e+05 4.17e+03 0.5 1.55e+01 - 1.00e+00 2.17e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 19r 0.0000000e+00 4.87e+05 1.47e+01 0.5 7.37e+00 - 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 20r 0.0000000e+00 5.23e+05 2.31e+03 -0.9 1.53e+00 - 9.40e-01 7.50e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 21r 0.0000000e+00 5.39e+05 7.30e+03 -0.9 2.08e+02 - 8.07e-01 3.86e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 22r 0.0000000e+00 5.39e+05 5.05e+03 -0.9 1.37e+02 - 1.00e+00 4.43e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 23r 0.0000000e+00 5.38e+05 7.93e+00 -0.9 7.27e+01 - 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 24r 0.0000000e+00 5.39e+05 1.75e-03 -0.9 2.41e-01 - 1.00e+00 1.00e+00h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 25r 0.0000000e+00 5.44e+05 2.59e+01 -3.6 3.79e+00 - 9.90e-01 9.73e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 26r 0.0000000e+00 4.44e+05 3.73e+02 -3.6 6.08e+03 - 7.62e-02 6.44e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 27r 0.0000000e+00 3.34e+05 7.09e+02 -3.6 2.85e+03 - 5.42e-02 9.37e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 28r 0.0000000e+00 2.87e+03 9.51e+02 -3.6 1.42e+03 - 1.73e-01 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 29r 0.0000000e+00 8.65e+04 2.35e+02 -3.6 1.10e+03 - 1.00e+00 1.00e+00H 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 30r 0.0000000e+00 8.28e+04 4.88e-01 -3.6 1.19e+02 - 1.00e+00 1.00e+00h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 31r 0.0000000e+00 8.28e+04 9.25e-05 -3.6 2.69e-01 - 1.00e+00 1.00e+00h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 32r 0.0000000e+00 8.28e+04 2.10e+00 -5.4 5.64e-02 - 1.00e+00 9.70e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 33r 0.0000000e+00 8.28e+04 2.49e+02 -5.4 1.00e-03 1.5 8.85e-01 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 34r 0.0000000e+00 8.27e+04 3.33e-02 -5.4 3.00e-03 1.0 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 35r 0.0000000e+00 8.27e+04 3.31e-02 -5.4 8.93e-03 0.6 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 36r 0.0000000e+00 8.26e+04 3.24e-02 -5.4 2.63e-02 0.1 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 37r 0.0000000e+00 8.23e+04 3.06e-02 -5.4 7.43e-02 -0.4 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 38r 0.0000000e+00 8.16e+04 2.59e-02 -5.4 1.89e-01 -0.9 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 39r 0.0000000e+00 8.02e+04 4.92e-02 -5.4 3.67e-01 -1.3 1.00e+00 1.00e+00h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 40r 0.0000000e+00 7.85e+04 6.76e-02 -5.4 1.01e+00 -1.8 1.00e+00 1.00e+00h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 41r 0.0000000e+00 7.76e+04 2.21e-02 -5.4 3.03e+00 -2.3 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 42r 0.0000000e+00 7.73e+04 1.54e-02 -5.4 9.07e+00 -2.8 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 43r 0.0000000e+00 7.69e+04 1.54e-02 -5.4 2.72e+01 -3.2 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 44r 0.0000000e+00 7.57e+04 9.45e-02 -5.4 8.16e+01 -3.7 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 45r 0.0000000e+00 7.21e+04 7.98e-01 -5.4 2.45e+02 -4.2 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 46r 0.0000000e+00 6.17e+04 5.91e+00 -5.4 7.40e+02 -4.7 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 47r 0.0000000e+00 3.69e+04 5.13e+01 -5.4 2.31e+03 -5.2 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 48r 0.0000000e+00 7.15e+04 1.47e+02 -5.4 1.10e+04 -5.6 1.00e+00 2.17e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 49r 0.0000000e+00 7.15e+04 4.98e+02 -5.4 4.07e+03 -5.2 1.00e+00 5.56e-06h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 50r 0.0000000e+00 2.07e+05 4.58e+03 -5.4 2.01e+04 -5.7 4.61e-01 1.75e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 51r 0.0000000e+00 1.19e+06 4.31e+04 -5.4 9.31e+03 -5.3 2.11e-06 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 52r 0.0000000e+00 1.16e+06 3.63e+04 -5.4 1.14e+02 -0.3 4.01e-01 1.23e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 53r 0.0000000e+00 1.16e+06 3.63e+04 -5.4 2.83e+01 0.1 7.36e-01 7.74e-07h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 54r 0.0000000e+00 1.16e+06 3.63e+04 -5.4 3.94e+03 - 1.59e-01 7.41e-06h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 55r 0.0000000e+00 7.95e+05 2.50e+04 -5.4 4.00e+03 - 7.84e-01 3.17e-01h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 56r 0.0000000e+00 3.83e+05 1.19e+04 -5.4 1.69e+03 - 1.35e-05 5.23e-01h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 57r 0.0000000e+00 2.95e+05 9.19e+03 -5.4 9.94e+00 -0.4 5.56e-01 2.31e-01h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 58r 0.0000000e+00 1.29e+04 7.45e+02 -5.4 1.55e+03 - 2.88e-06 1.00e+00h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 59r 0.0000000e+00 1.05e+04 3.57e+00 -5.4 8.95e-02 -0.8 1.00e+00 1.00e+00h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 60r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 7.60e-02 -1.3 1.00e+00 1.00e+00h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 61r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 2.28e-01 -1.8 1.00e+00 2.50e-01h 3\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 62r 0.0000000e+00 1.05e+04 1.03e-02 -5.4 6.84e-01 -2.3 1.00e+00 1.56e-02h 7\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 63r 0.0000000e+00 1.05e+04 3.12e-02 -5.4 2.05e+00 -2.8 1.00e+00 9.77e-04h 11\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 64r 0.0000000e+00 1.05e+04 9.35e-02 -5.4 6.16e+00 -3.2 1.00e+00 1.22e-04h 14\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 65r 0.0000000e+00 1.05e+04 2.81e-01 -5.4 1.85e+01 -3.7 1.00e+00 7.45e-09h 28\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 66r 0.0000000e+00 1.05e+04 8.49e-01 -5.4 5.60e+01 -4.2 1.00e+00 1.86e-09h 30\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 67r 0.0000000e+00 1.05e+04 2.61e+00 -5.4 1.72e+02 -4.7 1.00e+00 1.16e-10h 34\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 68r 0.0000000e+00 1.05e+04 8.40e+00 -5.4 5.54e+02 -5.1 1.00e+00 3.64e-12h 39\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 69r 0.0000000e+00 1.05e+04 8.40e+00 -5.4 2.14e+03 -5.6 0.00e+00 3.59e-18R 58\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 70r 0.0000000e+00 1.05e+04 1.94e+01 -5.4 4.50e+04 -6.1 1.63e-02 1.43e-12f 35\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 71r 0.0000000e+00 1.05e+04 3.85e+01 -5.4 2.54e+03 -5.7 1.00e+00 1.27e-11f 36\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 72r 0.0000000e+00 1.05e+04 1.11e+01 -5.4 7.22e+02 -5.2 9.93e-01 2.91e-11f 36\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 73r 0.0000000e+00 1.05e+04 3.70e+01 -5.4 3.05e+03 -5.7 7.35e-01 1.32e-12f 39\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 74r 0.0000000e+00 1.05e+04 1.25e+01 -5.4 8.27e+02 -5.3 1.00e+00 3.64e-12f 39\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 75r 0.0000000e+00 1.05e+04 3.60e+01 -5.4 3.72e+03 -5.8 5.36e-01 1.35e-13f 42\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 76r 0.0000000e+00 1.05e+04 1.44e+01 -5.4 9.51e+02 -5.3 1.00e+00 1.14e-13f 44\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 77r 0.0000000e+00 1.05e+04 2.35e+01 -5.4 4.61e+03 -5.8 1.64e-01 1.36e-14f 45\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 78r 0.0000000e+00 1.05e+04 1.66e+01 -5.4 1.10e+03 -5.4 1.00e+00 3.55e-15f 49\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 79r 0.0000000e+00 1.05e+04 2.55e+01 -5.4 5.86e+03 -5.9 1.22e-01 3.35e-16f 50\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 80r 0.0000000e+00 2.67e+04 5.84e+01 -5.4 1.27e+03 -5.4 1.00e+00 8.72e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 81r 0.0000000e+00 2.67e+04 2.19e+03 -5.4 1.28e+03 - 4.11e-03 2.62e-05w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 82r 0.0000000e+00 4.42e+04 8.23e+02 -5.4 3.84e+03 -5.9 5.02e-01 4.78e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 83r 0.0000000e+00 1.05e+04 1.92e+01 -5.4 1.21e+04 - 1.00e+00 7.74e-16f 50\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 84r 0.0000000e+00 1.05e+04 2.07e+01 -5.4 1.47e+03 -5.5 4.87e-01 3.33e-16h 52\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 85r 0.0000000e+00 1.05e+04 5.09e+01 -5.4 1.08e+04 -6.0 2.11e-01 1.14e-17f 54\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 86r 0.0000000e+00 1.05e+04 6.78e+01 -5.4 1.72e+03 -5.5 1.00e+00 1.78e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 87r 0.0000000e+00 1.05e+04 1.11e+02 -5.4 1.65e+04 -6.0 4.54e-02 1.86e-18f 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 88r 0.0000000e+00 1.05e+04 2.03e+02 -5.4 2.02e+03 -5.6 1.00e+00 1.52e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 89r 0.0000000e+00 1.05e+04 3.30e+02 -5.4 3.06e+04 -6.1 2.34e-02 1.00e-18f 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 90r 0.0000000e+00 1.05e+04 7.12e+02 -5.4 2.38e+03 -5.7 1.00e+00 1.29e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 91r 0.0000000e+00 1.05e+04 7.29e+02 -5.4 9.01e+04 -6.1 3.00e-04 3.41e-19f 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 92r 0.0000000e+00 1.05e+04 3.99e+01 -5.4 2.95e+03 -5.7 3.70e-01 2.84e-18h 59\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 93r 0.0000000e+00 2.20e+04 3.07e+01 -5.4 7.91e+02 -5.3 1.00e+00 1.00e+00w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 94r 0.0000000e+00 3.01e+04 4.20e+01 -5.4 2.61e+03 -5.8 7.22e-01 2.55e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 95r 0.0000000e+00 3.01e+04 1.37e+03 -5.4 1.07e+03 - 1.99e-03 3.17e-05w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 96r 0.0000000e+00 1.05e+04 1.20e+01 -5.4 7.00e+03 -6.2 1.00e+00 1.78e-15h 49\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 97r 0.0000000e+00 1.05e+04 2.31e+01 -5.4 4.29e+03 -5.8 2.10e-01 6.00e-11f 33\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 98r 0.0000000e+00 1.05e+04 1.59e+01 -5.4 1.05e+03 -5.4 1.00e+00 7.28e-12f 38\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 99r 0.0000000e+00 1.05e+04 2.46e+01 -5.4 5.40e+03 -5.9 1.33e-01 4.76e-11f 33\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 100r 0.0000000e+00 1.05e+04 1.83e+01 -5.4 1.21e+03 -5.4 1.00e+00 1.07e-10f 34\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 101r 0.0000000e+00 1.05e+04 2.73e+01 -5.4 7.03e+03 -5.9 1.02e-01 3.66e-11f 33\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 102r 0.0000000e+00 1.05e+04 2.77e+01 -5.4 1.40e+03 -5.5 1.00e+00 1.43e-12f 40\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 103r 0.0000000e+00 1.05e+04 4.37e+01 -5.4 9.60e+03 -6.0 7.47e-02 5.24e-14f 42\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 104r 0.0000000e+00 1.05e+04 6.49e+01 -5.4 1.63e+03 -5.5 1.00e+00 7.69e-14f 44\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 105r 0.0000000e+00 1.05e+04 1.04e+02 -5.4 1.42e+04 -6.0 5.06e-02 1.11e-15f 47\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 106r 0.0000000e+00 2.67e+04 1.58e+01 -5.4 1.91e+03 -5.6 1.00e+00 5.77e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 107r 0.0000000e+00 2.67e+04 1.40e+03 -5.4 9.67e+02 - 2.90e-03 3.66e-04w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 108r 0.0000000e+00 4.39e+04 4.78e+02 -5.4 5.57e+03 -6.1 3.84e-01 3.25e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 109r 0.0000000e+00 1.05e+04 1.80e+02 -5.4 6.38e+03 - 1.00e+00 4.10e-15f 47\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 110r 0.0000000e+00 1.05e+04 2.40e+02 -5.4 2.26e+03 -5.6 3.17e-01 3.47e-15f 48\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 111r 0.0000000e+00 1.05e+04 5.44e+02 -5.4 6.90e+04 -6.1 2.06e-02 1.14e-16f 48\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 112r 0.0000000e+00 1.05e+04 4.95e+01 -5.4 2.79e+03 -5.7 2.55e-01 7.69e-16f 51\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 113r 0.0000000e+00 1.05e+04 1.15e+01 -5.4 7.57e+02 -5.3 1.00e+00 7.11e-15f 48\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 114r 0.0000000e+00 1.05e+04 2.06e+01 -5.4 3.26e+03 -5.7 2.41e-01 6.02e-16f 50\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 115r 0.0000000e+00 1.05e+04 1.32e+01 -5.4 8.68e+02 -5.3 1.00e+00 2.22e-16h 53\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 116r 0.0000000e+00 1.05e+04 2.17e+01 -5.4 3.99e+03 -5.8 1.79e-01 3.07e-17h 54\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 117r 0.0000000e+00 1.05e+04 1.51e+01 -5.4 9.98e+02 -5.4 1.00e+00 2.78e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 118r 0.0000000e+00 1.05e+04 2.38e+01 -5.4 4.99e+03 -5.8 1.44e-01 6.14e-18h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 119r 0.0000000e+00 2.67e+04 5.98e+01 -5.4 1.15e+03 -5.4 1.00e+00 9.60e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 120r 0.0000000e+00 2.67e+04 2.31e+03 -5.4 1.66e+03 - 4.25e-03 1.30e-05w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 121r 0.0000000e+00 4.43e+04 8.41e+02 -5.4 3.52e+03 -5.9 5.33e-01 5.24e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 122r 0.0000000e+00 1.05e+04 1.75e+01 -5.4 1.31e+04 - 1.00e+00 2.66e-17h 55\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 123r 0.0000000e+00 1.05e+04 1.89e+01 -5.4 1.33e+03 -5.5 5.38e-01 2.30e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 124r 0.0000000e+00 1.05e+04 4.92e+01 -5.4 8.61e+03 -5.9 2.71e-01 3.56e-18h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 125r 0.0000000e+00 1.05e+04 2.98e+01 -5.4 1.55e+03 -5.5 1.00e+00 1.98e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 126r 0.0000000e+00 1.05e+04 4.92e+01 -5.4 1.23e+04 -6.0 6.33e-02 2.48e-18h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 127r 0.0000000e+00 1.05e+04 8.12e+01 -5.4 1.82e+03 -5.6 1.00e+00 1.69e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 128r 0.0000000e+00 1.05e+04 1.31e+02 -5.4 2.00e+04 -6.0 3.59e-02 1.53e-18f 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 129r 0.0000000e+00 1.05e+04 2.54e+02 -5.4 2.14e+03 -5.6 1.00e+00 1.43e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 130r 0.0000000e+00 1.05e+04 4.15e+02 -5.4 4.32e+04 -6.1 1.66e-02 7.10e-19f 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 131r 0.0000000e+00 1.05e+04 9.52e+02 -5.4 2.53e+03 -5.7 1.00e+00 1.21e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 132r 0.0000000e+00 2.67e+04 2.24e+01 -5.4 4.51e+05 -6.1 1.18e-04 2.45e-03w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 133r 0.0000000e+00 4.32e+04 1.53e+02 -5.4 4.75e+04 -6.6 3.50e-02 3.68e-02w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 134r 0.0000000e+00 4.32e+04 3.80e+02 -5.4 3.44e+03 - 1.99e-02 3.86e-06w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 135r 0.0000000e+00 1.05e+04 9.98e+02 -5.4 8.04e+02 - 1.18e-04 6.81e-20f 55\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 136r 0.0000000e+00 1.05e+04 2.21e+01 -5.4 8.37e+02 -5.3 6.52e-01 5.55e-17h 55\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 137r 0.0000000e+00 1.05e+04 2.91e+01 -5.4 3.73e+03 -5.8 2.04e-01 8.22e-18h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 138r 0.0000000e+00 1.05e+04 1.45e+01 -5.4 9.53e+02 -5.3 1.00e+00 5.55e-17h 55\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 139r 0.0000000e+00 1.05e+04 2.31e+01 -5.4 4.63e+03 -5.8 1.55e-01 6.62e-18h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 140r 0.0000000e+00 1.05e+04 1.67e+01 -5.4 1.10e+03 -5.4 1.00e+00 2.78e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 141r 0.0000000e+00 1.05e+04 2.55e+01 -5.4 5.89e+03 -5.9 1.22e-01 5.20e-18h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 142r 0.0000000e+00 1.05e+04 1.93e+01 -5.4 1.27e+03 -5.4 1.00e+00 2.41e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 143r 0.0000000e+00 1.05e+04 2.84e+01 -5.4 7.78e+03 -5.9 9.22e-02 3.94e-18h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 144r 0.0000000e+00 1.05e+04 3.40e+01 -5.4 1.48e+03 -5.5 1.00e+00 2.08e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 145r 0.0000000e+00 2.67e+04 4.04e+01 -5.4 1.09e+04 -6.0 6.60e-02 1.02e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 146r 0.0000000e+00 2.67e+04 1.47e+03 -5.4 1.02e+03 - 2.88e-03 1.10e-04w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 147r 0.0000000e+00 4.33e+04 7.00e+02 -5.4 1.97e+04 -6.5 1.24e-01 8.93e-02w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 148r 0.0000000e+00 1.05e+04 5.40e+01 -5.4 6.24e+03 - 6.60e-02 2.82e-18h 55\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 149r 0.0000000e+00 1.05e+04 1.51e+02 -5.4 1.68e+04 -6.0 1.26e-01 1.83e-18h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 150r 0.0000000e+00 1.05e+04 5.58e+01 -5.4 2.10e+03 -5.6 1.51e-01 9.25e-19h 60\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 151r 0.0000000e+00 1.05e+04 6.31e+01 -5.4 3.28e+04 -6.1 1.66e-02 9.36e-19f 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 152r 0.0000000e+00 1.05e+04 6.32e+01 -5.4 3.63e+03 -5.7 8.61e-03 1.56e-18h 54\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 153r 0.0000000e+00 1.05e+04 6.33e+01 -5.4 2.10e+05 -6.1 1.98e-05 1.48e-19f 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 154r 0.0000000e+00 1.05e+04 8.87e-01 -5.4 1.46e-02 -0.3 1.00e+00 1.43e-06h 4\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 155r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 2.09e-02 -0.8 1.00e+00 5.00e-01f 2\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 156r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 6.26e-02 -1.2 1.00e+00 2.44e-04h 13\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 157r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 1.88e-01 -1.7 1.00e+00 1.53e-05h 17\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 158r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 5.64e-01 -2.2 1.00e+00 1.00e+00w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 159r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 1.69e+00 -2.7 1.00e+00 1.00e+00w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 160r 0.0000000e+00 1.06e+04 3.62e-03 -5.4 5.08e+00 -3.1 1.00e+00 1.00e+00w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 161r 0.0000000e+00 1.05e+04 8.60e-03 -5.4 1.53e+01 -3.6 1.00e+00 7.45e-09h 27\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 162r 0.0000000e+00 1.05e+04 6.99e-01 -5.4 4.61e+01 -4.1 1.00e+00 1.14e-13h 44\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 163r 0.0000000e+00 1.05e+04 2.14e+00 -5.4 1.41e+02 -4.6 1.00e+00 2.84e-14h 46\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 164r 0.0000000e+00 1.05e+04 6.79e+00 -5.4 4.48e+02 -5.1 1.00e+00 4.66e-10f 32\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 165r 0.0000000e+00 1.05e+04 2.13e+01 -5.4 1.64e+03 -5.5 8.03e-01 1.96e-11f 36\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 166r 0.0000000e+00 1.05e+04 5.45e+01 -5.4 1.44e+04 -6.0 1.69e-01 5.60e-13f 38\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 167r 0.0000000e+00 1.05e+04 2.91e+01 -5.4 1.92e+03 -5.6 1.00e+00 1.31e-13f 43\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 168r 0.0000000e+00 1.05e+04 3.94e+01 -5.4 2.52e+04 -6.1 2.91e-02 3.11e-16f 48\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 169r 0.0000000e+00 1.05e+04 3.44e+01 -5.4 2.27e+03 -5.6 1.00e+00 3.46e-15h 48\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 170r 0.0000000e+00 1.05e+04 4.50e+01 -5.4 7.69e+04 -6.1 9.32e-03 1.28e-17f 51\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 171r 0.0000000e+00 2.67e+04 3.33e+01 -5.4 2.71e+03 -5.7 1.00e+00 4.08e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 172r 0.0000000e+00 2.67e+04 9.73e+02 -5.4 1.12e+03 - 1.93e-03 9.14e-05w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 173r 0.0000000e+00 4.37e+04 5.94e+02 -5.4 7.46e+03 -6.2 2.29e-01 2.40e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 174r 0.0000000e+00 1.05e+04 4.51e+01 -5.4 3.87e+03 - 1.00e+00 2.97e-12f 37\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 175r 0.0000000e+00 1.05e+04 6.47e+01 -5.4 3.27e+03 -5.7 2.19e-01 7.69e-14f 43\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 176r 0.0000000e+00 1.05e+04 5.10e+01 -5.4 8.69e+02 -5.3 1.00e+00 1.14e-13h 44\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 177r 0.0000000e+00 1.05e+04 7.51e+01 -5.4 4.00e+03 -5.8 1.79e-01 6.43e-11f 33\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 178r 0.0000000e+00 1.05e+04 6.82e+01 -5.4 1.00e+03 -5.4 1.00e+00 4.66e-10f 32\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 179r 0.0000000e+00 1.05e+04 1.03e+02 -5.4 5.00e+03 -5.8 1.43e-01 1.29e-11f 35\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 180r 0.0000000e+00 1.05e+04 1.08e+02 -5.4 1.15e+03 -5.4 1.00e+00 1.39e-11f 37\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 181r 0.0000000e+00 1.05e+04 1.65e+02 -5.4 6.42e+03 -5.9 1.12e-01 5.01e-12f 36\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 182r 0.0000000e+00 1.05e+04 2.00e+02 -5.4 1.34e+03 -5.5 1.00e+00 1.20e-11f 37\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 183r 0.0000000e+00 1.05e+04 3.13e+02 -5.4 8.54e+03 -5.9 8.39e-02 9.41e-13f 38\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 184r 0.0000000e+00 2.67e+04 6.63e+01 -5.4 1.55e+03 -5.5 1.00e+00 7.13e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 185r 0.0000000e+00 2.67e+04 8.09e+02 -5.4 1.01e+03 - 2.25e-03 8.90e-04w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 186r 0.0000000e+00 4.40e+04 1.17e+02 -5.4 4.65e+03 -6.0 4.39e-01 3.92e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 187r 0.0000000e+00 1.05e+04 4.40e+02 -5.4 8.89e+03 - 1.00e+00 2.07e-11f 35\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 188r 0.0000000e+00 1.05e+04 5.51e+02 -5.4 1.81e+03 -5.6 3.96e-01 8.88e-12f 37\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 189r 0.0000000e+00 1.05e+04 8.25e+02 -5.4 1.87e+04 -6.0 3.12e-02 1.08e-13f 40\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 190r 0.0000000e+00 1.05e+04 3.35e+01 -5.4 2.20e+03 -5.6 4.67e-01 2.27e-13f 43\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 191r 0.0000000e+00 1.05e+04 4.40e+01 -5.4 4.69e+04 -6.1 1.56e-02 5.36e-15f 43\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 192r 0.0000000e+00 1.05e+04 3.87e+01 -5.4 2.56e+03 -5.7 1.00e+00 2.46e-14f 45\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 193r 0.0000000e+00 1.05e+04 1.92e+01 -5.4 7.26e+02 -5.2 9.88e-01 1.14e-13h 44\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 194r 0.0000000e+00 1.05e+04 4.68e+01 -5.4 3.07e+03 -5.7 7.96e-01 1.68e-10f 32\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 195r 0.0000000e+00 1.05e+04 3.54e+01 -5.4 8.31e+02 -5.3 1.00e+00 5.82e-11f 35\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 196r 0.0000000e+00 1.05e+04 8.07e+01 -5.4 3.74e+03 -5.8 5.32e-01 6.87e-11f 33\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 197r 0.0000000e+00 2.44e+04 4.51e+01 -5.4 9.55e+02 -5.3 1.00e+00 1.00e+00w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 198r 0.0000000e+00 2.90e+04 1.83e+02 -5.4 3.03e+03 -5.8 6.02e-01 1.26e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 199r 0.0000000e+00 2.90e+04 3.65e+02 -5.4 1.03e+03 - 1.58e-03 1.30e-03w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 200r 0.0000000e+00 1.05e+04 6.99e+01 -5.4 9.09e+03 -6.3 1.00e+00 2.91e-11f 35\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of Iterations....: 200\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: (scaled) (unscaled)\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Dual infeasibility......: 6.9908071367141474e+01 6.9908071367141474e+01\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Constraint violation....: 2.8645094423111342e-03 1.0458847092153306e+04\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Complementarity.........: 1.3579265591895737e-03 1.3579265591895737e-03\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Overall NLP error.......: 2.8645094423111342e-03 1.0458847092153306e+04\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of objective function evaluations = 5209\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of objective gradient evaluations = 6\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of equality constraint evaluations = 5210\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of inequality constraint evaluations = 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of equality constraint Jacobian evaluations = 203\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of inequality constraint Jacobian evaluations = 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of Lagrangian Hessian evaluations = 200\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Total CPU secs in IPOPT (w/o function evaluations) = 0.176\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Total CPU secs in NLP function evaluations = 0.014\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: EXIT: Maximum Number of Iterations Exceeded.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit: Initialization Step 3 maxIterations - .\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit: Initialization Complete: maxIterations - \n", - "Initialization failed.\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "import logging\n", + "import traceback\n", + "\n", "from pyomo.environ import (\n", " ComponentMap,\n", " ConcreteModel,\n", @@ -615,14 +111,19 @@ " return m\n", "\n", "\n", - "if __name__ == \"__main__\":\n", - " m = create_model()\n", - "\n", - " reboiler_init = m.fs.unit.default_initializer(always_estimate_states=True)\n", - " try:\n", - " reboiler_init.initialize(m.fs.unit, output_level=idaeslog.DEBUG)\n", - " except InitializationError:\n", - " print(\"Initialization failed.\")" + "m = create_model()\n", + "reboiler_init = m.fs.unit.default_initializer(always_estimate_states=True)\n", + "try:\n", + " reboiler_init.initialize(m.fs.unit, output_level=idaeslog.DEBUG)\n", + "except InitializationError:\n", + " traceback.print_exc()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here we see that initialization failed due to the unit model solve terminating after reaching the maximum number of iterations. However, when solution of a square problem reaches 200-300 iterations without converging, increasing the number of iterations usually does not help. In this case, it terminates with a `Restoration Failed` status after about 500 iterations. When confronted with a failing solve, we should first head to the `DiagnosticsToolbox`." ] }, { @@ -630,54 +131,58 @@ "metadata": {}, "source": [ "## Step 2: Run Model Diagnostics\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "While initialization fails in every version of Python supported presently (3.10, 3.11, 3.12 3.13), the model termination point(s) that Python 3.10 and 3.11 come to are different than the model termination point that 3.12 and 3.13 come to. In order to ensure that the diagnostic output is the same in every supported version, we load the model state from a `json` file." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "from idaes.core.util import from_json, StoreSpec\n", "\n", - "We see that the unit model failed to initialize. When confronted with a bad solution state, we should first use the `DiagnosticsToolbox` to check to see if there are structural issues with the model." + "from_json(m, fname=\"advanced_scaling_failed_solution.json\", wts=StoreSpec.value())" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "First, we will use the `DiagnosticsToolbox` to check to see if there are structural issues with the model. (More information about the `DiagnosticsToolbox` can be found in its [documentation](https://idaes-pse.readthedocs.io/en/stable/explanations/model_diagnostics/index.html) and [tutorial notebook](https://idaes-examples.readthedocs.io/en/latest/docs/diagnostics/diagnostics_toolbox_doc.html)" ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": { - "scrolled": true + "editable": true, + "scrolled": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "====================================================================================\n", - "Model Statistics\n", - "\n", - " Activated Blocks: 23 (Deactivated: 0)\n", - " Free Variables in Activated Constraints: 77 (External: 0)\n", - " Free Variables with only lower bounds: 15\n", - " Free Variables with only upper bounds: 0\n", - " Free Variables with upper and lower bounds: 50\n", - " Fixed Variables in Activated Constraints: 66 (External: 0)\n", - " Activated Equality Constraints: 77 (Deactivated: 0)\n", - " Activated Inequality Constraints: 0 (Deactivated: 0)\n", - " Activated Objectives: 0 (Deactivated: 0)\n", - "\n", - "------------------------------------------------------------------------------------\n", - "1 WARNINGS\n", - "\n", - " WARNING: Found 9 potential evaluation errors.\n", - "\n", - "------------------------------------------------------------------------------------\n", - "2 Cautions\n", - "\n", - " Caution: 11 variables fixed to 0\n", - " Caution: 82 unused variables (82 fixed)\n", - "\n", - "------------------------------------------------------------------------------------\n", - "Suggested next steps:\n", - "\n", - " display_potential_evaluation_errors()\n", - "\n", - "====================================================================================\n" - ] - } - ], + "outputs": [], "source": [ "from idaes.core.util import DiagnosticsToolbox\n", "\n", @@ -689,56 +194,16 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "The density relationship is being flagged for potential evaluation errors. The interval arithmetic used to identify potential evaluation errors can produce relatively loose bounds, especially for the sort of large polynomial expressions favored in the literature. Independent testing of the density relationship over a wide range of values has demonstrated that no evaluation errors occur, so we can ignore these warnings.\n", + "The density relationship is being flagged for potential evaluation errors. The interval arithmetic used to identify potential evaluation errors can produce relatively loose bounds, especially for the sort of large polynomial expressions favored in engineering literature. Independent testing of the density relationship over a wide range of values has demonstrated that no evaluation errors occur, so we can ignore these warnings.\n", "\n", "The next step is determining which numerical issues exist." ] }, { "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "====================================================================================\n", - "Model Statistics\n", - "\n", - " Jacobian Condition Number: 2.718E+13\n", - "\n", - "------------------------------------------------------------------------------------\n", - "3 WARNINGS\n", - "\n", - " WARNING: 3 Constraints with large residuals (>1.0E-05)\n", - " WARNING: 1 Variable with extreme Jacobian column norms (<1.0E-08 or >1.0E+08)\n", - " WARNING: 1 Constraint with extreme Jacobian row norms (<1.0E-08 or >1.0E+08)\n", - "\n", - "------------------------------------------------------------------------------------\n", - "8 Cautions\n", - "\n", - " Caution: 9 Variables with value close to their bounds (abs=1.0E-04, rel=1.0E-04)\n", - " Caution: 18 Variables with value close to zero (tol=1.0E-08)\n", - " Caution: 30 Variables with extreme value (<1.0E-04 or >1.0E+04)\n", - " Caution: 2 Constraints with mismatched terms\n", - " Caution: 1 Constraint with potential cancellation of terms\n", - " Caution: 27 Variables with extreme Jacobian column norms (<1.0E-04 or >1.0E+04)\n", - " Caution: 16 Constraints with extreme Jacobian row norms (<1.0E-04 or >1.0E+04)\n", - " Caution: 50 extreme Jacobian Entries (<1.0E-04 or >1.0E+04)\n", - "\n", - "------------------------------------------------------------------------------------\n", - "Suggested next steps:\n", - "\n", - " display_constraints_with_large_residuals()\n", - " compute_infeasibility_explanation()\n", - " display_variables_with_extreme_jacobians()\n", - " display_constraints_with_extreme_jacobians()\n", - "\n", - "====================================================================================\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "dt.report_numerical_issues()" ] @@ -788,43 +253,14 @@ "$$\n", "With a condition number on the order of $10^{13}$ and the default tolerance $\\varepsilon = 10^{-6}$, then the difference between the computed solution $x_f$ and the true solution $x$ could be on the order of $10^7$.\n", "\n", - "In practice, however, we frequently end up with much better results than those predicted by this worst-case bound. Frequently, we find that most constraints have residuals on the order of $10^{-10}$ or less, with a few problematic constraints having larger residuals. That is the case here." + "In practice, however, we frequently end up with much better results than those predicted by this worst-case bound. The condition number of the unscaled Jacobian does not taken into account that some variables are much bigger than others. For example, the liquid phase mole fraction of $\\text{CO}_2$ is on the order of $10^{-5}$, whereas the heat duty is on the order of $10^6$. Unless we scale the model, we have no way of determining which changes to the solution are significant and which are not. Additionally, we frequently find that most constraints have residuals on the order of $10^{-10}$ or less, with only a few problematic constraints having larger residuals. That is the case here." ] }, { "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Number of constraints: 77\n", - "====================================================================================\n", - "The following constraint(s) have large residuals (>1.0E-10):\n", - "\n", - " fs.unit.unit_material_balance[0.0,CO2]: 1.84866E-10\n", - " fs.unit.unit_material_balance[0.0,N2]: 1.89950E-10\n", - " fs.unit.unit_material_balance[0.0,O2]: 1.87656E-10\n", - " fs.unit.unit_phase_equilibrium[0.0,CO2]: 1.04588E+04\n", - " fs.unit.unit_phase_equilibrium[0.0,H2O]: 8.88278E-07\n", - " fs.unit.unit_enthalpy_balance[0.0]: 5.05679E-10\n", - " fs.unit.liquid_phase.material_balances[0.0,CO2]: 1.70459E-10\n", - " fs.unit.liquid_phase.enthalpy_balances[0.0]: 1.17285E-05\n", - " fs.unit.liquid_phase.properties_out[0.0].sum_mole_frac_out: 2.08134E-10\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-]: 8.83857E-06\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]: 1.54414E-07\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA_+]: 7.69821E-06\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,H2O]: 2.50511E-08\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA]: 4.55346E-06\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2]: 4.42749E-05\n", - " fs.unit.vapor_phase[0.0].sum_mole_frac_out: 1.71144E-10\n", - "\n", - "====================================================================================\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "import idaes.core.util.model_statistics as mstat\n", "\n", @@ -846,7 +282,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -1081,14 +517,12 @@ "\n", "## Step 3: Creating a New Scaler Class\n", "\n", - "To create a new scaling routine for the equilibrium reactor, we start by creating a new ``Scaler`` class which inherits from the ``CustomScalerBase`` class in ``idaes.core.scaling``. The ``CustomScalerBase`` class contains a number of useful methods to help us in developing our scaling routine, including some placeholder methods for implementing a standard scaling workflow and helper methods for doing common tasks.\n", - "\n", - "The cell below shows how to create our new class which we will name ``SolventReboilerScaler`` as well as two key methods we will fill out as part of this workshop." + "To create a new scaling routine for the solvent reboiler, we start by creating a new ``Scaler`` class which inherits from the ``CustomScalerBase`` class in ``idaes.core.scaling``." ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -1113,7 +547,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "As you know from the first scaling tutorial, the ``variable_scaling_routine`` and ``constraint_scaling_routine`` methods are used to implement subroutines for scaling the variables and constraints in the model respectively. Separately, there is a ``scale_model`` method that will call each of these in sequence in order to scale an entire model by applying the following steps:\n", + "As you know from the [first scaling tutorial](./scaler_workshop_doc.md), the ``variable_scaling_routine`` and ``constraint_scaling_routine`` methods are used to implement subroutines for scaling the variables and constraints in the model respectively. Separately, there is a ``scale_model`` method that will call each of these in sequence in order to scale an entire model by applying the following steps:\n", "\n", "1. apply variable scaling routine,\n", "2. apply first stage scaling fill-in,\n", @@ -1129,7 +563,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -1182,7 +616,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -1199,30 +633,9 @@ }, { "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'flow_mol_phase': ,\n", - " 'mole_frac_phase_comp': 10,\n", - " 'temperature': 0.0033333333333333335,\n", - " 'pressure': 1e-05,\n", - " 'enth_mol_phase': ,\n", - " 'visc_d_phase': ,\n", - " 'therm_cond_phase': ,\n", - " 'mole_frac_phase_comp_true': 10,\n", - " 'mole_frac_phase_comp_apparent': 10,\n", - " 'dens_mol_phase': ,\n", - " 'vol_mol_phase': }" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "liquid_properties_scaler.default_scaling_factors" ] @@ -1235,14 +648,14 @@ "\n", "With an inlet flow of about 80 mol/s, a scaling factor of 1/80 is appropriate. We can ignore ``visc_d_phase`` and ``therm_cond_phase``, because this unit model does not require dynamic viscosity or thermal conductivity. Molar enthalpy is a tougher quantity to scale.\n", "\n", - "By convention, the molar enthalpy of each element in its pure form at $25^\\circ\\text{C}$ and $1\\:\\text{atm}$ is set equal to zero. In some property packages, enthalpy of formation is taken into account for compounds, while in some property packages it is not. However, the scaling factor for enthalpy should not depend on this convention---only enthalpy *differences* are meaningful. So we need to determine how to determine what constitutes a \"significant\" enthalpy difference for this property package. The way the modular property scaler object estimates this is through the temperature scaling factor, which determines what a \"significant\" temperature difference is, and the observation that a wide range of substances have a specific heat capacity around $2\\:\\frac{\\text{J}}{\\text{g K}}$.\n", + "By convention, the molar enthalpy of each element in its pure form at $25^\\circ\\text{C}$ and $1\\:\\text{atm}$ is set equal to zero. In some property packages, enthalpy of formation is taken into account for compounds, while in some property packages it is not. However, the scaling factor for enthalpy should not depend on this convention\u2014only enthalpy *differences* are meaningful. So we need to determine how to determine what constitutes a \"significant\" enthalpy difference for this property package. The way the modular property scaler object estimates this is through the temperature scaling factor, which determines what a \"significant\" temperature difference is, and the observation that a wide range of substances have a specific heat capacity around $2\\:\\frac{\\text{J}}{\\text{g K}}$.\n", "\n", "This default method is good enough for our purposes now. We can revisit it later, if necessary." ] }, { "cell_type": "code", - "execution_count": 12, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -1262,45 +675,9 @@ }, { "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "====================================================================================\n", - "Model Statistics\n", - "\n", - " Jacobian Condition Number: 7.165E+10\n", - "\n", - "------------------------------------------------------------------------------------\n", - "1 WARNINGS\n", - "\n", - " WARNING: 1 Constraint with large residuals (>1.0E-05)\n", - "\n", - "------------------------------------------------------------------------------------\n", - "8 Cautions\n", - "\n", - " Caution: 9 Variables with value close to their bounds (abs=1.0E-04, rel=1.0E-04)\n", - " Caution: 14 Variables with value close to zero (tol=1.0E-08)\n", - " Caution: 27 Variables with extreme value (<1.0E-04 or >1.0E+04)\n", - " Caution: 2 Constraints with mismatched terms\n", - " Caution: 1 Constraint with potential cancellation of terms\n", - " Caution: 10 Variables with extreme Jacobian column norms (<1.0E-04 or >1.0E+04)\n", - " Caution: 4 Constraints with extreme Jacobian row norms (<1.0E-04 or >1.0E+04)\n", - " Caution: 33 extreme Jacobian Entries (<1.0E-04 or >1.0E+04)\n", - "\n", - "------------------------------------------------------------------------------------\n", - "Suggested next steps:\n", - "\n", - " display_constraints_with_large_residuals()\n", - " compute_infeasibility_explanation()\n", - "\n", - "====================================================================================\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "reboiler_scaler = SolventReboilerScaler()\n", "reboiler_scaler.scale_model(m.fs.unit)\n", @@ -1318,7 +695,7 @@ "$$\n", "\\max\\left(\\frac{||\\mathbf{r}_\\text{max}||_2}{||\\mathbf{r}_\\text{min}||_2}, \\frac{||\\mathbf{c}_\\text{max}||_2}{||\\mathbf{c}_\\text{min}||_2}\\right) \\leq \\kappa(\\mathbf{J}(\\mathbf{x}))\n", "$$\n", - "Consequently, Jacobian rows or columns with extremely large or extremely small norms indicate that the Jacobian is ill-conditioned. Each row is associated with a constraint and each column is associated with a variable. So the extreme Jacobian rows and columns give us a list of variables and constraints to investigate for scaling.\n", + "Consequently, Jacobian rows or columns with extremely large or extremely small norms indicate that the Jacobian is ill-conditioned. Each row is associated with a constraint and each column is associated with a variable. Thus, the extreme Jacobian rows and columns give us a list of variables and constraints to investigate for scaling.\n", "\n", "
\n", "Just because a variable or constraint has a Jacobian column or row with an extreme norm does not mean it is badly-scaled. Frequently, either a constraint containing the variable or a variable present in a constraint is the actual problem. \n", @@ -1337,40 +714,9 @@ }, { "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "====================================================================================\n", - "The following variable(s) correspond to Jacobian columns with extreme norms(<1.0E-04 or>1.0E+04):\n", - "\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,CO2]: 3.450E+07\n", - " fs.unit.liquid_phase.enthalpy_transfer[0.0]: 1.970E+06\n", - " fs.unit.liquid_phase.properties_out[0.0].temperature: 1.586E+06\n", - " fs.unit.vapor_phase[0.0].pressure: 1.353E+05\n", - " fs.unit.vapor_phase[0.0].temperature: 1.014E+05\n", - " fs.unit.liquid_phase.properties_out[0.0].pressure: 1.000E+05\n", - " fs.unit.vapor_phase[0.0].flow_mol_phase[Vap]: 3.256E+04\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,H2O]: 1.954E+04\n", - " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]: 1.873E+04\n", - " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]: 1.863E+04\n", - "\n", - "====================================================================================\n", - "====================================================================================\n", - "The following constraint(s) correspond to Jacobian rows with extreme norms (<1.0E-04 or>1.0E+04):\n", - "\n", - " fs.unit.unit_phase_equilibrium[0.0,CO2]: 3.450E+07\n", - " fs.unit.unit_enthalpy_balance[0.0]: 1.973E+06\n", - " fs.unit.unit_phase_equilibrium[0.0,H2O]: 1.589E+06\n", - " fs.unit.unit_pressure_balance[0.0]: 1.414E+05\n", - "\n", - "====================================================================================\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "dt.display_variables_with_extreme_jacobians()\n", "dt.display_constraints_with_extreme_jacobians()" @@ -1384,22 +730,14 @@ "\n", "## Step 5: Unit Model Level Scaling\n", "\n", - "We should take a look at the constraints before determining their scaling factors. However, Pyomo's `pprint` method often prints out multiple terminal pages' worth of thermodynamic expressions, which are extremely difficult to parse. The output is so verbose because it descends into named `Expressions` and recursively subsititutes them into the constraint expression. Since IDAES makes heavy use of named `Expressions` to decrease the number of `Constraints` in a model, the output becomes unmanangable for all but the most simple constraints. The `print_compact_form` utility function usually results in much more readable output." + "We should take a look at the constraints before determining their scaling factors. However, Pyomo's `pprint` method often prints out multiple terminal pages' worth of thermodynamic expressions, which are extremely difficult to parse. The output is so verbose because it descends into named `Expressions` and recursively subsititutes them into the constraint expression. Since IDAES makes heavy use of named `Expressions` to reduce the number of `Constraints` in a model, the output becomes unmanangable for all but the most simple constraints. The `print_compact_form` utility function usually results in much more readable output." ] }, { "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "- fs.unit.liquid_phase.enthalpy_transfer[0.0] == (kg*m**2/J/s**2)*fs.unit.vapor_phase[0.0]._enthalpy_flow_term[Vap]\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "from idaes.core.util.misc import print_compact_form\n", "\n", @@ -1418,20 +756,9 @@ }, { "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "5.076760620583219e-07" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "get_scaling_factor(m.fs.unit.liquid_phase.enthalpy_transfer[0.0])" ] @@ -1447,17 +774,9 @@ }, { "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "None\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "print(get_scaling_factor(m.fs.unit.vapor_phase[0.0]._enthalpy_flow_term[\"Vap\"]))" ] @@ -1471,17 +790,9 @@ }, { "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "fs.unit.vapor_phase[0.0].flow_mol_phase[Vap]*fs.unit.vapor_phase[0.0].enth_mol_phase[Vap]\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "print_compact_form(m.fs.unit.vapor_phase[0.0]._enthalpy_flow_term[\"Vap\"])" ] @@ -1495,20 +806,9 @@ }, { "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0.1" - ] - }, - "execution_count": 20, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "get_scaling_factor(m.fs.unit.vapor_phase[0.0].flow_mol_phase[\"Vap\"])" ] @@ -1522,20 +822,9 @@ }, { "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "5.46268982847154e-05" - ] - }, - "execution_count": 21, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "get_scaling_factor(m.fs.unit.vapor_phase[0.0].enth_mol_phase[\"Vap\"])" ] @@ -1549,20 +838,9 @@ }, { "cell_type": "code", - "execution_count": 22, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0.0125" - ] - }, - "execution_count": 22, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "get_scaling_factor(m.fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase[\"Liq\"])" ] @@ -1577,7 +855,7 @@ "$$\n", "Let $\\sigma(v)$ denote the scaling factor of the variable $v$. Then `get_sum_terms_nominal_values` substitutes the inverse of the variable scaling factor into each term in the sum and returns it as a list:\n", "$$\n", - "\\left[\\frac{1}{\\sigma(a)},\\; \\frac{1}{\\sigma(b) \\cdot \\sigma(c)}, \\frac{\\left(\\frac{1}{\\sigma(e)} - \\frac{1}{\\sigma(f)}\\right)}{\\sigma(d)} \\right]\n", + "\\left[\\frac{1}{\\sigma(a)},\\; \\frac{1}{\\sigma(b) \\cdot \\sigma(c)}, \\frac{-\\left(\\frac{1}{\\sigma(e)} - \\frac{1}{\\sigma(f)}\\right)}{\\sigma(d)} \\right]\n", "$$\n", "\n", "This process can produce reliable estimates of expression magnitude for certain operations:\n", @@ -1605,20 +883,9 @@ }, { "cell_type": "code", - "execution_count": 23, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[1969759.9999999995, 183060.0]" - ] - }, - "execution_count": 23, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "reboiler_scaler.get_sum_terms_nominal_values(m.fs.unit.unit_enthalpy_balance[0.0])" ] @@ -1627,7 +894,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "The inverse of either of these numbers would be reasonable scaling factors. The `scale_constraint_by_nominal value` function automatically scales a constraint by using one of these numbers. Which number we use is selected using the `ConstraintScalingScheme` `Enum` If we take the inverse of the larger number, we are saying that the constraint needs to be satisfied with the same precision as the largest term in the sum. This corresponds to `ConstraintScalingScheme.inverseMaximum`. If we take the inverse of the smaller number, we are saying that the constraint needs to be satisfied with the same precision as the smallest term in the sum. This corresponds to `ConstraintScalingScheme.inverseMinimum`.\n", + "The inverse of either of these numbers would be reasonable scaling factors. The `scale_constraint_by_nominal value` function automatically scales a constraint by using one of these numbers. Which number we use is selected using the `ConstraintScalingScheme` `Enum`. If we take the inverse of the larger number, we are saying that the constraint needs to be satisfied with the same precision as the largest term in the sum. This corresponds to `ConstraintScalingScheme.inverseMaximum`. If we take the inverse of the smaller number, we are saying that the constraint needs to be satisfied with the same precision as the smallest term in the sum. This corresponds to `ConstraintScalingScheme.inverseMinimum`.\n", "\n", "In general, the `inverseMinimum` scheme is the safest to use, because it demands the most precision. Let's use the `inverseMinimum` method for this constraint in order to more precisely determine the vapor phase's temperature.\n", "\n", @@ -1636,23 +903,11 @@ }, { "cell_type": "code", - "execution_count": 24, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[Liq,CO2] == fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,CO2]\n", - "\n", - "\n", - "fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[Liq,H2O] == fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,H2O]\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "print_compact_form(m.fs.unit.unit_phase_equilibrium[0.0, \"CO2\"])\n", - "print(\"\\n\")\n", "print_compact_form(m.fs.unit.unit_phase_equilibrium[0.0, \"H2O\"])" ] }, @@ -1665,18 +920,9 @@ }, { "cell_type": "code", - "execution_count": 26, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[7623092.433711249, 10000.0]\n", - "[355.3596511053128, 10000.0]\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "print(\n", " reboiler_scaler.get_sum_terms_nominal_values(\n", @@ -1694,22 +940,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Here, we see that, while the vapor phase fugacities are associated with a nominal value of 10000, the liquid phase fugacities have wildly different nominal values. We do expect the vapor phase to be enriched in $\\text{CO}_2$, but not by a factor of $2\\cdot 10^4$. Let's unpack these values. We are using the ideal gas law for the vapor phase, so the fugacity is simply the product of the mole fraction and vapor pressure:" + "Here, we see that, while the vapor phase fugacities are associated with a nominal value of `10000`, the liquid phase fugacities have wildly different nominal values. We do expect the vapor phase to be enriched in $\\text{CO}_2$, but not by a factor of $2\\cdot 10^4$. Let's unpack these values. We are using the ideal gas law for the vapor phase, so the fugacity is simply the product of the mole fraction and vapor pressure:" ] }, { "cell_type": "code", - "execution_count": 27, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]*fs.unit.vapor_phase[0.0].pressure\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "print_compact_form(m.fs.unit.vapor_phase[0.0].fug_phase_comp[\"Vap\", \"CO2\"])" ] @@ -1723,17 +961,9 @@ }, { "cell_type": "code", - "execution_count": 28, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,CO2]*(exp(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O])*log(244800.0*exp(-1348*K/fs.unit.liquid_phase.properties_out[0.0].temperature)*(3520000.0*exp(-2113*K/fs.unit.liquid_phase.properties_out[0.0].temperature)/(8449000.0*exp(-2283*K/fs.unit.liquid_phase.properties_out[0.0].temperature)))) + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O])*log(3520000.0*exp(-2113*K/fs.unit.liquid_phase.properties_out[0.0].temperature)) + fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O])*(fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]))*(fs.liquid_properties.CO2.lwm_coeff_1 + K**(-1)*fs.liquid_properties.CO2.lwm_coeff_2*(fs.unit.liquid_phase.properties_out[0.0].temperature - 273.15*K) + K**(-2)*fs.liquid_properties.CO2.lwm_coeff_3*(fs.unit.liquid_phase.properties_out[0.0].temperature - 273.15*K)**2 + fs.liquid_properties.CO2.lwm_coeff_4*(fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]))))*Pa*m**3*mol**(-1))\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "print_compact_form(\n", " m.fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[\"Liq\", \"CO2\"]\n", @@ -1744,25 +974,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Parsing the entire pile of thermodynamic gibberish is unnecessary to plan our next move. We can plainly see that the liquid phase fugacity expression is rife with subtraction and exponentiation, both of which are dangerous for the nominal value expression walker. Even worse, we are scaling based on a failed solution, so the values may be off anyway. It is far better to base the scaling factor on the vapor phase fugacity. The `get_expression_nominal_value` function allows the user to get the nominal value of a single expression." + "Parsing the entire pile of thermodynamic gibberish is unnecessary to plan our next move. We can see that the liquid phase fugacity expression is rife with subtraction and exponentiation, both of which are dangerous for the nominal value expression walker. Even worse, we are scaling based on a failed solution, so the values may be off anyway. It is far better to base the scaling factor on the vapor phase fugacity. The `get_expression_nominal_value` function allows the user to get the nominal value of a single expression." ] }, { "cell_type": "code", - "execution_count": 29, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "10000.0" - ] - }, - "execution_count": 29, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "reboiler_scaler.get_expression_nominal_value(\n", " m.fs.unit.vapor_phase[0.0].fug_phase_comp[\"Vap\", \"CO2\"]\n", @@ -1780,17 +999,9 @@ }, { "cell_type": "code", - "execution_count": 30, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "fs.unit.liquid_phase.properties_out[0.0].pressure == fs.unit.vapor_phase[0.0].pressure\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "print_compact_form(m.fs.unit.unit_pressure_balance[0.0])" ] @@ -1806,51 +1017,9 @@ }, { "cell_type": "code", - "execution_count": 31, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Scaling Factors for block fs.unit\n", - "\n", - "Variable Scaling Factor Value Scaled Value\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol 1.250E-02 8.389E+01 1.049E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[H2O] 1.000E+01 8.589E-01 8.589E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[MEA] 1.000E+01 1.085E-01 1.085E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[CO2] 1.000E+01 3.260E-02 3.260E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].temperature 3.333E-03 3.925E+02 1.308E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol 1.250E-02 7.424E+01 9.279E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O] 1.000E+01 8.527E-01 8.527E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] 1.000E+01 1.226E-01 1.226E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[CO2] 1.000E+01 2.471E-02 2.471E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].temperature 3.333E-03 3.926E+02 1.309E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", - "fs.unit.vapor_phase[0.0].flow_mol 1.000E-01 9.654E+00 9.654E-01\n", - "fs.unit.vapor_phase[0.0].mole_frac_comp[CO2] 1.000E+01 9.329E-02 9.329E-01\n", - "fs.unit.vapor_phase[0.0].mole_frac_comp[H2O] 1.000E+01 9.067E-01 9.067E+00\n", - "fs.unit.vapor_phase[0.0].mole_frac_comp[N2] 1.000E+01 1.055E-09 1.055E-08\n", - "fs.unit.vapor_phase[0.0].mole_frac_comp[O2] 1.000E+01 1.055E-09 1.055E-08\n", - "fs.unit.vapor_phase[0.0].temperature 3.333E-03 3.926E+02 1.309E+00\n", - "fs.unit.vapor_phase[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", - "fs.unit.liquid_phase.heat[0.0] 5.077E-07 4.306E+05 2.186E-01\n", - "\n", - "Constraint Scaling Factor\n", - "fs.unit.unit_material_balance[0.0,CO2] None\n", - "fs.unit.unit_material_balance[0.0,H2O] None\n", - "fs.unit.unit_material_balance[0.0,N2] None\n", - "fs.unit.unit_material_balance[0.0,O2] None\n", - "fs.unit.unit_material_balance[0.0,MEA] None\n", - "fs.unit.unit_phase_equilibrium[0.0,CO2] None\n", - "fs.unit.unit_phase_equilibrium[0.0,H2O] None\n", - "fs.unit.unit_temperature_equality[0.0] None\n", - "fs.unit.unit_enthalpy_balance[0.0] None\n", - "fs.unit.unit_pressure_balance[0.0] None\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "from idaes.core.scaling.util import report_scaling_factors\n", "\n", @@ -1866,17 +1035,9 @@ }, { "cell_type": "code", - "execution_count": 32, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "fs.unit.liquid_phase.properties_out[0.0].temperature == fs.unit.vapor_phase[0.0].temperature\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "print_compact_form(m.fs.unit.unit_temperature_equality[0.0])" ] @@ -1892,28 +1053,12 @@ }, { "cell_type": "code", - "execution_count": 33, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "- fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,CO2] == fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,CO2]\n", - "\n", - "\n", - "fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,MEA] == 0*(mol*s**(-1))\n", - "\n", - "\n", - "fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,N2] == fs.unit.zero_flow_param\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "print_compact_form(m.fs.unit.unit_material_balance[0.0, \"CO2\"])\n", - "print(\"\\n\")\n", "print_compact_form(m.fs.unit.unit_material_balance[0.0, \"MEA\"])\n", - "print(\"\\n\")\n", "print_compact_form(m.fs.unit.unit_material_balance[0.0, \"N2\"])" ] }, @@ -1937,7 +1082,7 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -2019,53 +1164,26 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Now we can see how this works on the model. We'll pass `overwrite=True` config option when creating the scaler object to ensure we have up-to-date scaling factors." + "Now we can see how this works on the model. We will create a new instance of the model to demonstrate that the improved scaling is sufficient to allow the model to initialize without a custom-tailored initial guess." ] }, { "cell_type": "code", - "execution_count": 35, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Starting initialization routine\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Bubble, dew, and critical point initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Equilibrium temperature initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: State variable initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Phase equilibrium initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Property initialization routine finished.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Starting initialization routine\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Bubble, dew, and critical point initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Equilibrium temperature initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: State variable initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Phase equilibrium initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Property initialization routine finished.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: Starting initialization routine\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: Bubble, dew, and critical point initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: Equilibrium temperature initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: State variable initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: Phase equilibrium initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: Property initialization routine finished.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit: Initialization Complete: optimal - \n" - ] - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 35, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ - "scaler_obj = SolventReboilerScaler(overwrite=True)\n", + "m = create_model()\n", + "\n", + "# Since this is a new instance of the model, we need to set the default\n", + "# scaler objects again.\n", + "m.fs.liquid_properties.default_state_scaler_object = liquid_properties_scaler\n", + "m.fs.vapor_properties.default_state_scaler_object = vapor_properties_scaler\n", + "\n", + "scaler_obj = SolventReboilerScaler()\n", "scaler_obj.scale_model(m.fs.unit)\n", + "\n", + "reboiler_init = m.fs.unit.default_initializer(always_estimate_states=True)\n", "reboiler_init.initialize(m.fs.unit)" ] }, @@ -2073,50 +1191,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "We see that scaling improved the model enough so that initialization could succeed. Now let's look at the numerical issues." + "We see that scaling improved the robustness of the model enough so that initialization could succeed. Now let's look at the numerical issues." ] }, { "cell_type": "code", - "execution_count": 36, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "====================================================================================\n", - "Model Statistics\n", - "\n", - " Jacobian Condition Number: 5.400E+06\n", - "\n", - "------------------------------------------------------------------------------------\n", - "0 WARNINGS\n", - "\n", - " No warnings found!\n", - "\n", - "------------------------------------------------------------------------------------\n", - "6 Cautions\n", - "\n", - " Caution: 9 Variables with value close to their bounds (abs=1.0E-04, rel=1.0E-04)\n", - " Caution: 14 Variables with value close to zero (tol=1.0E-08)\n", - " Caution: 27 Variables with extreme value (<1.0E-04 or >1.0E+04)\n", - " Caution: 2 Constraints with mismatched terms\n", - " Caution: 1 Constraint with potential cancellation of terms\n", - " Caution: 20 extreme Jacobian Entries (<1.0E-04 or >1.0E+04)\n", - "\n", - "------------------------------------------------------------------------------------\n", - "Suggested next steps:\n", - "\n", - " If you still have issues converging your model consider:\n", - "\n", - " prepare_degeneracy_hunter()\n", - " prepare_svd_toolbox()\n", - "\n", - "====================================================================================\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "dt = DiagnosticsToolbox(m)\n", "dt.report_numerical_issues()" @@ -2159,7 +1241,7 @@ "\n", "Because $\\mathbf{U}$ and $\\mathbf{V}$ are orthogonal and $\\mathbf{\\Sigma}$ is diagonal, computing a Newton step is easy once the SVD is calculated.\n", "$$\n", - "\\mathbf{\\delta x}_k = -\\mathbf{V \\Sigma^{-1} U}^T \\cdot \\mathbf{f}(\\mathbf{x}_k)\n", + "\\mathbf{\\delta x}_k = -\\mathbf{V \\Sigma}^{-1} \\mathbf{U}^T \\cdot \\mathbf{f}(\\mathbf{x}_k)\n", "$$\n", "Since we have to refactorize $\\mathbf{J}$ at each iteration, the SVD is not an efficient method to calculate a Newton step. However, this process has a geometric interpretation that is useful for model diagnostics and scaling. First, the constraint residual is decomposed into orthogonal components by $\\mathbf{U}$:\n", "$$\n", @@ -2167,7 +1249,7 @@ "$$\n", "Next, these orthogonal components are scaled by the inverse of the associated singular value:\n", "$$\n", - "\\mathbf{\\tilde{s}} = \\Sigma^{-1} \\cdot \\mathbf{s}\n", + "\\mathbf{\\tilde{s}} = \\mathbf{\\Sigma}^{-1} \\cdot \\mathbf{s}\n", "$$\n", "Finally, these independent components are translated into the variable space by $\\mathbf{V}$:\n", "$$\n", @@ -2178,163 +1260,20 @@ "
\n", "NOTE\n", "\n", - "The singular vectors $\\mathbf{u}_j$ and $\\mathbf{v}_j$ are typically dense. In order to link them with specific variables and constraints, a thresholding scheme is applied. The `size_cutoff_in_singular_vector` config option for the `SVDToolbox` controls the magnitude of an entry in $\\mathbf{u}_j$ and $\\mathbf{v}_j$ that is sufficient to link a variable or constraint to the $\\sigma_j$. It is `0.1` by default, but can take on values between about `0.05` and `0.3`. Decrease it to show fewer variables and constraints, increase it to show more variables and constraints.\n", + "The singular vectors $\\mathbf{u}_j$ and $\\mathbf{v}_j$ are typically dense. In order to link them with specific variables and constraints, a thresholding scheme is applied. The `size_cutoff_in_singular_vector` config option for the `SVDToolbox` controls the magnitude of an entry in $\\mathbf{u}_j$ and $\\mathbf{v}_j$ that is sufficient to link a variable or constraint to the $\\sigma_j$. It is `0.1` by default, but typically has a value between `0.05` and `0.3`. Decrease it to show fewer variables and constraints, increase it to show more variables and constraints.\n", "\n", "
\n", "\n", - "So let's create an instance of the `SVDToolbox` and display the variables and constraints associated with the 5 smallest singular values.\n" + "So let's create an instance of the `SVDToolbox` and display the variables and constraints associated with the 5 smallest singular values. (For a full description of all the methods available, look at the [SVD toolbox documentation](https://idaes-pse.readthedocs.io/en/latest/reference_guides/core/util/diagnostics/svd_toolbox.html#svd-toolbox).)\n" ] }, { "cell_type": "code", - "execution_count": 38, + "execution_count": null, "metadata": { "scrolled": true }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "====================================================================================\n", - "Constraints and Variables associated with smallest singular values\n", - "\n", - " 1st Smallest Singular Value: 6.356e-04\n", - "\n", - " Variables:\n", - "\n", - " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_comp[CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_comp[H2O]\n", - "\n", - " Constraints:\n", - "\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2]\n", - "\n", - " 2nd Smallest Singular Value: 2.781e-02\n", - "\n", - " Variables:\n", - "\n", - " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_comp[CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_comp[H2O]\n", - "\n", - " Constraints:\n", - "\n", - " fs.unit.unit_material_balance[0.0,CO2]\n", - " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", - "\n", - " 3rd Smallest Singular Value: 3.679e-02\n", - "\n", - " Variables:\n", - "\n", - " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_comp[CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_comp[H2O]\n", - "\n", - " Constraints:\n", - "\n", - " fs.unit.unit_material_balance[0.0,CO2]\n", - " fs.unit.liquid_phase.material_balances[0.0,MEA]\n", - " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", - " fs.unit.liquid_phase.enthalpy_balances[0.0]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", - " fs.unit.unit_material_balance[0.0,MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,HCO3_-]\n", - " fs.unit.vapor_phase[0.0].sum_mole_frac_out\n", - "\n", - " 4th Smallest Singular Value: 6.842e-02\n", - "\n", - " Variables:\n", - "\n", - " fs.unit.vapor_phase[0.0].flow_mol_phase[Vap]\n", - " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,H2O]\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]\n", - " fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,H2O]\n", - " fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,H2O]\n", - " fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,H2O]\n", - " fs.unit.vapor_phase[0.0].mole_frac_comp[H2O]\n", - " fs.unit.vapor_phase[0.0].flow_mol\n", - "\n", - " Constraints:\n", - "\n", - " fs.unit.unit_material_balance[0.0,CO2]\n", - " fs.unit.liquid_phase.material_balances[0.0,MEA]\n", - " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", - " fs.unit.liquid_phase.enthalpy_balances[0.0]\n", - " fs.unit.unit_material_balance[0.0,MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].total_flow_balance\n", - " fs.unit.vapor_phase[0.0].sum_mole_frac_out\n", - "\n", - " 5th Smallest Singular Value: 7.703e-02\n", - "\n", - " Variables:\n", - "\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,H2O]\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]\n", - " fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,H2O]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_k_eq[bicarbonate]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_k_eq[carbamate]\n", - "\n", - " Constraints:\n", - "\n", - " fs.unit.liquid_phase.material_balances[0.0,MEA]\n", - " fs.unit.unit_material_balance[0.0,MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].total_flow_balance\n", - " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[MEA]\n", - " fs.unit.liquid_phase.properties_out[0.0].sum_mole_frac_out\n", - "\n", - "====================================================================================\n" - ] - } - ], + "outputs": [], "source": [ "st = dt.prepare_svd_toolbox()\n", "# The SVD toolbox displays 10 singular values by default, but we are going to\n", @@ -2351,17 +1290,9 @@ }, { "cell_type": "code", - "execution_count": 40, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "exp(fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]) == fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,CO2]/(mol/m**3)\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "print_compact_form(\n", " m.fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[\n", @@ -2381,29 +1312,9 @@ }, { "cell_type": "code", - "execution_count": 41, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "====================================================================================\n", - "The following variables are involved in fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2]:\n", - "\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,H2O]: 4.333e-05\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,MEA]: 1.441e-04\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,CO2]: 6.126e-05\n", - " fs.unit.liquid_phase.properties_out[0.0].temperature: 1.576e-04\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]: -5.255e-07\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA]: 5.123e-06\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,CO2]: -1.648e+00\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]: 5.621e-04\n", - "\n", - "====================================================================================\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "st.display_variables_in_constraint(\n", " m.fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[\n", @@ -2419,7 +1330,7 @@ "
\n", "NOTE\n", "\n", - "At this point of the process, the original author found a shortcoming in the `ModularPropertiesScaler`. No scaling hint was set for the molar density expression, so the expression walker descended into it and came back with an inappropriate nominal value. Revising the scaler to estimate the phase density resulted in a condition number improvement of 1-2 orders of magnitude.\n", + "At this point of the process, the author of this notebook found a shortcoming in the `ModularPropertiesScaler`. No scaling hint was set for the molar density expression, so the expression walker descended into it and came back with an inappropriate nominal value. Revising the scaler to estimate the phase density resulted in a condition number improvement of 1-2 orders of magnitude.\n", "\n", "Remember:\n", "1. Scaling is an iterative process.\n", @@ -2434,24 +1345,15 @@ }, { "cell_type": "code", - "execution_count": 42, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Left hand side value: 1.3698e+00\n", - "CO2 true concentration value: 1.3698e+00\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "print(\n", - " f\"Left hand side value: {value(exp(m.fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[\"Liq\",\"CO2\"])):.4e}\"\n", + " f\"Left hand side value: {value(exp(m.fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true['Liq','CO2'])):.4e}\"\n", ")\n", "print(\n", - " f\"CO2 true concentration value: {value(m.fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[\"Liq\",\"CO2\"]):.4e}\"\n", + " f\"CO2 true concentration value: {value(m.fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true['Liq','CO2']):.4e}\"\n", ")" ] }, @@ -2464,17 +1366,9 @@ }, { "cell_type": "code", - "execution_count": 44, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0.0004103666666666667\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "print(\n", " get_scaling_factor(\n", @@ -2498,24 +1392,15 @@ }, { "cell_type": "code", - "execution_count": 45, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True CO2 mole fraction: 3.410357e-05\n", - "True MEACOO- mole fraction: 2.796223e-02\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "print(\n", - " f\"True CO2 mole fraction: {m.fs.unit.liquid_phase.properties_out[0].mole_frac_phase_comp_true[\"Liq\",\"CO2\"].value:4e}\"\n", + " f\"True CO2 mole fraction: {m.fs.unit.liquid_phase.properties_out[0].mole_frac_phase_comp_true['Liq','CO2'].value:4e}\"\n", ")\n", "print(\n", - " f\"True MEACOO- mole fraction: {m.fs.unit.liquid_phase.properties_out[0].mole_frac_phase_comp_true[\"Liq\",\"MEACOO_-\"].value:4e}\"\n", + " f\"True MEACOO- mole fraction: {m.fs.unit.liquid_phase.properties_out[0].mole_frac_phase_comp_true['Liq','MEACOO_-'].value:4e}\"\n", ")" ] }, @@ -2528,7 +1413,7 @@ }, { "cell_type": "code", - "execution_count": 46, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -2558,66 +1443,11 @@ }, { "cell_type": "code", - "execution_count": 47, + "execution_count": null, "metadata": { "scrolled": true }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Starting initialization routine\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Bubble, dew, and critical point initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Equilibrium temperature initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: State variable initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Phase equilibrium initialization completed.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Property initialization routine finished.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Starting initialization routine\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Bubble, dew, and critical point initialization completed.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Equilibrium temperature initialization completed.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: State variable initialization completed.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Phase equilibrium initialization completed.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Property initialization routine finished.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: Starting initialization routine\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: Bubble, dew, and critical point initialization completed.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: Equilibrium temperature initialization completed.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: State variable initialization completed.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: Phase equilibrium initialization completed.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: Property initialization routine finished.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit: Initialization Complete: optimal - \n", - "====================================================================================\n", - "Model Statistics\n", - "\n", - " Jacobian Condition Number: 2.945E+05\n", - "\n", - "------------------------------------------------------------------------------------\n", - "0 WARNINGS\n", - "\n", - " No warnings found!\n", - "\n", - "------------------------------------------------------------------------------------\n", - "6 Cautions\n", - "\n", - " Caution: 9 Variables with value close to their bounds (abs=1.0E-04, rel=1.0E-04)\n", - " Caution: 14 Variables with value close to zero (tol=1.0E-08)\n", - " Caution: 27 Variables with extreme value (<1.0E-04 or >1.0E+04)\n", - " Caution: 2 Constraints with mismatched terms\n", - " Caution: 1 Constraint with potential cancellation of terms\n", - " Caution: 16 extreme Jacobian Entries (<1.0E-04 or >1.0E+04)\n", - "\n", - "------------------------------------------------------------------------------------\n", - "Suggested next steps:\n", - "\n", - " If you still have issues converging your model consider:\n", - "\n", - " prepare_degeneracy_hunter()\n", - " prepare_svd_toolbox()\n", - "\n", - "====================================================================================\n" - ] - } - ], + "outputs": [], "source": [ "scaler_obj = SolventReboilerScaler(overwrite=True)\n", "scaler_obj.scale_model(m.fs.unit)\n", @@ -2635,173 +1465,16 @@ }, { "cell_type": "code", - "execution_count": 49, + "execution_count": null, "metadata": { "scrolled": true }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "====================================================================================\n", - "Constraints and Variables associated with smallest singular values\n", - "\n", - " 1st Smallest Singular Value: 6.965e-04\n", - "\n", - " Variables:\n", - "\n", - " fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[bicarbonate]\n", - " fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[carbamate]\n", - " fs.unit.liquid_phase.properties_out[0.0].apparent_inherent_reaction_extent[carbamate]\n", - "\n", - " Constraints:\n", - "\n", - " fs.unit.unit_material_balance[0.0,CO2]\n", - " fs.unit.unit_material_balance[0.0,H2O]\n", - " fs.unit.liquid_phase.material_balances[0.0,H2O]\n", - " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].total_flow_balance\n", - " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", - "\n", - " 2nd Smallest Singular Value: 1.047e-03\n", - "\n", - " Variables:\n", - "\n", - " fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[carbamate]\n", - " fs.unit.liquid_phase.properties_out[0.0].apparent_inherent_reaction_extent[carbamate]\n", - "\n", - " Constraints:\n", - "\n", - " fs.unit.unit_material_balance[0.0,CO2]\n", - " fs.unit.unit_material_balance[0.0,H2O]\n", - " fs.unit.liquid_phase.material_balances[0.0,H2O]\n", - " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEA_+]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA_+]\n", - "\n", - " 3rd Smallest Singular Value: 4.024e-03\n", - "\n", - " Variables:\n", - "\n", - " fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[bicarbonate]\n", - " fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[carbamate]\n", - "\n", - " Constraints:\n", - "\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,H2O]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,H2O]\n", - " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,H2O]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", - "\n", - " 4th Smallest Singular Value: 5.218e-03\n", - "\n", - " Variables:\n", - "\n", - " fs.unit.liquid_phase.properties_out[0.0].apparent_inherent_reaction_extent[bicarbonate]\n", - "\n", - " Constraints:\n", - "\n", - " fs.unit.unit_material_balance[0.0,CO2]\n", - " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,HCO3_-]\n", - "\n", - " 5th Smallest Singular Value: 5.115e-02\n", - "\n", - " Variables:\n", - "\n", - " fs.unit.vapor_phase[0.0].flow_mol_phase[Vap]\n", - " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_comp[CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_comp[H2O]\n", - " fs.unit.vapor_phase[0.0].flow_mol\n", - "\n", - " Constraints:\n", - "\n", - " fs.unit.unit_material_balance[0.0,CO2]\n", - " fs.unit.unit_material_balance[0.0,H2O]\n", - " fs.unit.liquid_phase.material_balances[0.0,H2O]\n", - " fs.unit.liquid_phase.material_balances[0.0,MEA]\n", - " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEA_+]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEA]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA_+]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA]\n", - " fs.unit.unit_material_balance[0.0,MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].total_flow_balance\n", - " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA_+]\n", - " fs.unit.liquid_phase.properties_out[0.0].sum_mole_frac_out\n", - " fs.unit.vapor_phase[0.0].sum_mole_frac_out\n", - "\n", - "====================================================================================\n" - ] - } - ], + "outputs": [], "source": [ "st = dt.prepare_svd_toolbox()\n", "st.display_underdetermined_variables_and_constraints([1, 2, 3, 4, 5])" ] }, - { - "cell_type": "code", - "execution_count": 50, - "metadata": {}, - "outputs": [], - "source": [ - "assert st.s[0] == pytest.approx(6.965e-04, rel=1e-2)\n", - "assert st.s[3] == pytest.approx(5.218e-03, rel=1e-2)\n", - "assert st.s[4] == pytest.approx(5.115e-02, rel=1e-2)" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -2815,243 +1488,11 @@ }, { "cell_type": "code", - "execution_count": 51, + "execution_count": null, "metadata": { "scrolled": true }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Scaling Factors for block fs.unit\n", - "\n", - "Variable Scaling Factor Value Scaled Value\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol 1.250E-02 8.389E+01 1.049E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[H2O] 1.000E+00 8.589E-01 8.589E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[MEA] 1.000E+01 1.085E-01 1.085E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[CO2] 1.000E+01 3.260E-02 3.260E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].temperature 3.333E-03 3.925E+02 1.308E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol 1.250E-02 7.410E+01 9.263E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O] 1.000E+00 8.487E-01 8.487E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] 1.000E+01 1.228E-01 1.228E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[CO2] 1.000E+01 2.851E-02 2.851E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].temperature 3.333E-03 3.938E+02 1.313E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", - "fs.unit.vapor_phase[0.0].flow_mol 1.000E-01 9.785E+00 9.785E-01\n", - "fs.unit.vapor_phase[0.0].mole_frac_comp[CO2] 1.000E+01 6.361E-02 6.361E-01\n", - "fs.unit.vapor_phase[0.0].mole_frac_comp[H2O] 1.000E+01 9.364E-01 9.364E+00\n", - "fs.unit.vapor_phase[0.0].mole_frac_comp[N2] 1.000E+01 1.022E-09 1.022E-08\n", - "fs.unit.vapor_phase[0.0].mole_frac_comp[O2] 1.000E+01 1.022E-09 1.022E-08\n", - "fs.unit.vapor_phase[0.0].temperature 3.333E-03 3.938E+02 1.313E+00\n", - "fs.unit.vapor_phase[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", - "fs.unit.liquid_phase.heat[0.0] 8.763E-07 4.306E+05 3.773E-01\n", - "fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,H2O] 1.250E-02 -9.163E+00 -1.145E-01\n", - "fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,MEA] 1.250E-01 0.000E+00 0.000E+00\n", - "fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,CO2] 1.250E-01 -6.224E-01 -7.780E-02\n", - "fs.unit.liquid_phase.enthalpy_transfer[0.0] 8.763E-07 -3.209E+04 -2.812E-02\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase[Liq] 1.250E-02 8.389E+01 1.049E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp[Liq,H2O] 1.000E+00 8.589E-01 8.589E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp[Liq,MEA] 1.000E+01 1.085E-01 1.085E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp[Liq,CO2] 1.000E+01 3.260E-02 3.260E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].phase_frac[Liq] 1.000E+00 1.000E+00 1.000E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,MEACOO_-] 1.250E-01 2.550E+00 3.187E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,HCO3_-] 1.250E+00 1.785E-01 2.231E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,MEA_+] 1.250E-01 2.728E+00 3.410E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,H2O] 1.250E-02 7.187E+01 8.984E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,MEA] 1.250E-01 3.825E+00 4.781E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,CO2] 1.250E+02 6.803E-03 8.504E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,MEACOO_-] 1.000E+01 3.141E-02 3.141E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,HCO3_-] 1.000E+02 2.199E-03 2.199E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,MEA_+] 1.000E+01 3.361E-02 3.361E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,H2O] 1.000E+00 8.856E-01 8.856E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,MEA] 1.000E+01 4.712E-02 4.712E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,CO2] 1.000E+04 8.383E-05 8.383E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[bicarbonate] 1.250E+02 1.785E-01 2.231E+01\n", - "fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[carbamate] 1.250E+02 2.550E+00 3.187E+02\n", - "fs.unit.liquid_phase.properties_in[0.0].log_k_eq[bicarbonate] None -7.578E+00 -7.578E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].log_k_eq[carbamate] None -1.985E+00 -1.985E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-] 1.000E+00 7.168E+00 7.168E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-] 1.000E+00 4.509E+00 4.509E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+] 1.000E+00 7.236E+00 7.236E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,H2O] 1.000E+00 1.051E+01 1.051E+01\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEA] 1.000E+00 7.573E+00 7.573E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,CO2] 1.000E+00 1.242E+00 1.242E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase[Liq] 1.250E-02 7.410E+01 9.263E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,H2O] 1.000E+00 8.487E-01 8.487E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,MEA] 1.000E+01 1.228E-01 1.228E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,CO2] 1.000E+01 2.851E-02 2.851E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].phase_frac[Liq] 1.000E+00 1.000E+00 1.000E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,MEACOO_-] 1.250E-01 2.013E+00 2.516E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,HCO3_-] 1.250E+00 9.684E-02 1.210E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,MEA_+] 1.250E-01 2.110E+00 2.637E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,H2O] 1.250E-02 6.279E+01 7.849E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,MEA] 1.250E-01 4.979E+00 6.224E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,CO2] 1.250E+02 2.455E-03 3.069E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,MEACOO_-] 1.000E+01 2.796E-02 2.796E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,HCO3_-] 1.000E+02 1.345E-03 1.345E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,MEA_+] 1.000E+01 2.931E-02 2.931E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,H2O] 1.000E+00 8.722E-01 8.722E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,MEA] 1.000E+01 6.916E-02 6.916E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,CO2] 1.000E+04 3.410E-05 3.410E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].apparent_inherent_reaction_extent[bicarbonate] 1.250E+02 9.684E-02 1.210E+01\n", - "fs.unit.liquid_phase.properties_out[0.0].apparent_inherent_reaction_extent[carbamate] 1.250E+02 2.013E+00 2.516E+02\n", - "fs.unit.liquid_phase.properties_out[0.0].log_k_eq[bicarbonate] None -7.648E+00 -7.648E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].log_k_eq[carbamate] None -2.079E+00 -2.079E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-] 1.000E+00 7.024E+00 7.024E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-] 1.000E+00 3.989E+00 3.989E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+] 1.000E+00 7.071E+00 7.071E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,H2O] 1.000E+00 1.046E+01 1.046E+01\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA] 1.000E+00 7.929E+00 7.929E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2] 1.000E+00 3.147E-01 3.147E-01\n", - "fs.unit.vapor_phase[0.0].flow_mol_phase[Vap] 1.000E-01 9.785E+00 9.785E-01\n", - "fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2] 1.000E+01 6.361E-02 6.361E-01\n", - "fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O] 1.000E+01 9.364E-01 9.364E+00\n", - "fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,N2] 1.000E+01 1.022E-09 1.022E-08\n", - "fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,O2] 1.000E+01 1.022E-09 1.022E-08\n", - "fs.unit.vapor_phase[0.0].phase_frac[Vap] 1.000E+00 1.000E+00 1.000E+00\n", - "\n", - "Constraint Scaling Factor\n", - "fs.unit.unit_material_balance[0.0,CO2] 1.250E-01\n", - "fs.unit.unit_material_balance[0.0,H2O] 1.250E-02\n", - "fs.unit.unit_material_balance[0.0,N2] 1.000E+00\n", - "fs.unit.unit_material_balance[0.0,O2] 1.000E+00\n", - "fs.unit.unit_material_balance[0.0,MEA] 1.250E-01\n", - "fs.unit.unit_phase_equilibrium[0.0,CO2] 1.000E-04\n", - "fs.unit.unit_phase_equilibrium[0.0,H2O] 1.000E-04\n", - "fs.unit.unit_temperature_equality[0.0] 3.333E-03\n", - "fs.unit.unit_enthalpy_balance[0.0] 5.463E-06\n", - "fs.unit.unit_pressure_balance[0.0] 1.000E-05\n", - "fs.unit.liquid_phase.material_balances[0.0,H2O] 1.250E-02\n", - "fs.unit.liquid_phase.material_balances[0.0,MEA] 1.250E-01\n", - "fs.unit.liquid_phase.material_balances[0.0,CO2] 1.250E-01\n", - "fs.unit.liquid_phase.enthalpy_balances[0.0] 8.763E-07\n", - "fs.unit.liquid_phase.pressure_balance[0.0] 1.000E-05\n", - "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEACOO_-] 1.250E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,HCO3_-] 1.250E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEA_+] 1.250E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,H2O] 1.250E-02\n", - "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEA] 1.250E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2] 1.250E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEACOO_-] 1.250E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,HCO3_-] 1.250E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEA_+] 1.250E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,H2O] 1.250E-02\n", - "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEA] 1.250E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,CO2] 1.250E+02\n", - "fs.unit.liquid_phase.properties_in[0.0].total_flow_balance 1.250E-02\n", - "fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[H2O] 1.000E+01\n", - "fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[MEA] 1.000E+01\n", - "fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2] 1.000E+01\n", - "fs.unit.liquid_phase.properties_in[0.0].phase_fraction_constraint[Liq] 1.000E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].log_k_eq_constraint[bicarbonate] None\n", - "fs.unit.liquid_phase.properties_in[0.0].log_k_eq_constraint[carbamate] None\n", - "fs.unit.liquid_phase.properties_in[0.0].inherent_equilibrium_constraint[bicarbonate] 1.000E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].inherent_equilibrium_constraint[carbamate] 1.000E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-] 2.377E-04\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-] 2.377E-03\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA_+] 2.377E-04\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,H2O] 2.377E-05\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA] 2.377E-04\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2] 2.377E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEACOO_-] 1.250E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,HCO3_-] 1.250E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA_+] 1.250E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,H2O] 1.250E-02\n", - "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA] 1.250E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2] 1.250E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEACOO_-] 1.250E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,HCO3_-] 1.250E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEA_+] 1.250E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,H2O] 1.250E-02\n", - "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEA] 1.250E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,CO2] 1.250E+02\n", - "fs.unit.liquid_phase.properties_out[0.0].sum_mole_frac_out 1.000E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].total_flow_balance 1.250E-02\n", - "fs.unit.liquid_phase.properties_out[0.0].component_flow_balances[H2O] 1.000E+01\n", - "fs.unit.liquid_phase.properties_out[0.0].component_flow_balances[MEA] 1.000E+01\n", - "fs.unit.liquid_phase.properties_out[0.0].component_flow_balances[CO2] 1.000E+01\n", - "fs.unit.liquid_phase.properties_out[0.0].phase_fraction_constraint[Liq] 1.000E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].log_k_eq_constraint[bicarbonate] None\n", - "fs.unit.liquid_phase.properties_out[0.0].log_k_eq_constraint[carbamate] None\n", - "fs.unit.liquid_phase.properties_out[0.0].inherent_equilibrium_constraint[bicarbonate] 1.000E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].inherent_equilibrium_constraint[carbamate] 1.000E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-] 2.377E-04\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-] 2.377E-03\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA_+] 2.377E-04\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,H2O] 2.377E-05\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA] 2.377E-04\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2] 2.377E-01\n", - "fs.unit.vapor_phase[0.0].sum_mole_frac_out 1.000E+00\n", - "fs.unit.vapor_phase[0.0].total_flow_balance 1.000E-01\n", - "fs.unit.vapor_phase[0.0].component_flow_balances[CO2] 1.000E+01\n", - "fs.unit.vapor_phase[0.0].component_flow_balances[H2O] 1.000E+01\n", - "fs.unit.vapor_phase[0.0].component_flow_balances[N2] 1.000E+01\n", - "fs.unit.vapor_phase[0.0].component_flow_balances[O2] 1.000E+01\n", - "fs.unit.vapor_phase[0.0].phase_fraction_constraint[Vap] 1.000E+00\n", - "\n", - "Expression Scaling Hint\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp[Liq,H2O] 1.250E-02\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp[Liq,MEA] 1.250E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp[Liq,CO2] 1.250E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].k_eq[bicarbonate] None\n", - "fs.unit.liquid_phase.properties_in[0.0].k_eq[carbamate] None\n", - "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,MEACOO_-] None\n", - "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,HCO3_-] None\n", - "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,MEA_+] None\n", - "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,H2O] None\n", - "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,MEA] None\n", - "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,CO2] None\n", - "fs.unit.liquid_phase.properties_in[0.0].dens_mol_phase[Liq] 2.377E-05\n", - "fs.unit.liquid_phase.properties_in[0.0].vol_mol_phase[Liq] 4.206E+04\n", - "fs.unit.liquid_phase.properties_in[0.0]._enthalpy_flow_term[Liq] None\n", - "fs.unit.liquid_phase.properties_in[0.0].enth_mol_phase[Liq] 7.010E-05\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_comp[H2O] 1.250E-02\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_comp[MEA] 1.250E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_comp[CO2] 1.250E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp[Liq,H2O] 1.250E-02\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp[Liq,MEA] 1.250E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp[Liq,CO2] 1.250E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].k_eq[bicarbonate] None\n", - "fs.unit.liquid_phase.properties_out[0.0].k_eq[carbamate] None\n", - "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,MEACOO_-] None\n", - "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,HCO3_-] None\n", - "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,MEA_+] None\n", - "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,H2O] None\n", - "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,MEA] None\n", - "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,CO2] None\n", - "fs.unit.liquid_phase.properties_out[0.0].dens_mol_phase[Liq] 2.377E-05\n", - "fs.unit.liquid_phase.properties_out[0.0].vol_mol_phase[Liq] 4.206E+04\n", - "fs.unit.liquid_phase.properties_out[0.0]._enthalpy_flow_term[Liq] None\n", - "fs.unit.liquid_phase.properties_out[0.0].enth_mol_phase[Liq] 7.010E-05\n", - "fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[Liq,H2O] None\n", - "fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[Liq,MEA] None\n", - "fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[Liq,CO2] None\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_comp[H2O] 1.250E-02\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_comp[MEA] 1.250E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_comp[CO2] 1.250E-01\n", - "fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,CO2] 1.000E+00\n", - "fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,H2O] 1.000E+00\n", - "fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,N2] 1.000E+00\n", - "fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,O2] 1.000E+00\n", - "fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,CO2] None\n", - "fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,H2O] None\n", - "fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,N2] None\n", - "fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,O2] None\n", - "fs.unit.vapor_phase[0.0]._enthalpy_flow_term[Vap] None\n", - "fs.unit.vapor_phase[0.0].enth_mol_phase[Vap] 5.463E-05\n", - "fs.unit.vapor_phase[0.0].enth_mol_phase_comp[Vap,CO2] 3.787E-05\n", - "fs.unit.vapor_phase[0.0].enth_mol_phase_comp[Vap,H2O] 9.249E-05\n", - "fs.unit.vapor_phase[0.0].enth_mol_phase_comp[Vap,N2] 5.950E-05\n", - "fs.unit.vapor_phase[0.0].enth_mol_phase_comp[Vap,O2] 5.208E-05\n", - "fs.unit.vapor_phase[0.0].flow_mol_comp[CO2] 1.000E+00\n", - "fs.unit.vapor_phase[0.0].flow_mol_comp[H2O] 1.000E+00\n", - "fs.unit.vapor_phase[0.0].flow_mol_comp[N2] 1.000E+00\n", - "fs.unit.vapor_phase[0.0].flow_mol_comp[O2] 1.000E+00\n" - ] - } - ], + "outputs": [], "source": [ "from idaes.core.scaling.util import report_scaling_factors\n", "\n", @@ -3062,7 +1503,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Most variable values have scaled values within a couple orders of magnitude of one, which is what we like. The outliers are inherent reaction extents, which we already know are a bit problematic, and variables corresponding to the components $\\text{N}_2$ and $\\text{O}_2$, which are present in the vapor property package but not the vapor stream.\n", + "Most variable values have scaled values within a couple orders of magnitude of one, which is what we like. The outliers are inherent reaction extents, which we already know are a bit problematic, and variables corresponding to the components $\\text{N}_2$ and $\\text{O}_2$. Because those components are present in the vapor property package but not the vapor stream, they should not be scaled to order one, and their current scaling factors are fine.\n", "\n", "We have reduced the condition number to $3 \\cdot 10^5$, which is not quite as low as we would have liked, but is a vast improvement over the value $3 \\cdot 10^{13}$, which we started out with. " ] @@ -3102,7 +1543,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.12" + "version": "3.10.20" } }, "nbformat": 4, diff --git a/idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques_test.ipynb b/idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques_test.ipynb index 615d4087..4661fb39 100644 --- a/idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques_test.ipynb +++ b/idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques_test.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -32,532 +32,28 @@ "\n", "## Introduction\n", "\n", - "This notebook is intended to give the user further insight into how the scaling toolbox can be used to improve robustness. A large portion of the material is an adaptation of [Allan, Ostace, and Polly (2025)](#references). By the end of this study, the user should understand:\n", + "This notebook is intended to give the user further insight into how the scaling toolbox can be used to improve robustness. It is a followup to a [previous notebook](./scaler_workshop_test.ipynb) about how to create scaler objects in IDAES, and it assumes some familiarity with the material contained therein. A large portion of the material is an adaptation of [Allan, Ostace, and Polly (2025)](#references). By the end of this study, the user should understand:\n", "* How a default scaler object can be specified for a property package\n", "* How to set default scaling factors for property package variables\n", + "* How to use the `DiagnosticsToolbox` to troubleshoot saling issues\n", "* The strengths and weaknesses of the ``NominalValueExpressionWalker`` used in ``CustomScalerBase.get_sum_terms_nominal_values`` and ``CustomScalerBase.get_expression_nominal_value`` for use in constraint scaling\n", "* How to use the ``SVDToolbox`` to troubleshoot scaling issues\n", "\n", "## Step 1: Set Up Test Case\n", - "We will use the `SolventReboiler` unit model as a case study. It is a component in a stripping column used for solvent regeneration. It is modeled as a single equilibrium stage with an external heat duty. The inlet stream is entirely liquid, while it has both boilup and bottoms outlet streams. The liquid and vapor phases use different configurations of the modular property framework.\n", + "We will use the `SolventReboiler` unit model as a case study. It is a component in a stripping column used for solvent regeneration. It is modeled as a single equilibrium stage with an external heat duty. The inlet stream is entirely liquid, while it has both boilup and bottoms outlet streams. The liquid and vapor phases use different configurations of the [modular property framework](https://idaes-pse.readthedocs.io/en/latest/explanations/components/property_package/general/index.html).\n", "\n", "First, we set up and attempt to initialize the unit model." ] }, { "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2026-04-29 17:11:54 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Starting initialization routine\n", - "2026-04-29 17:11:54 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Bubble, dew, and critical point initialization completed.\n", - "2026-04-29 17:11:54 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Equilibrium temperature initialization completed.\n", - "2026-04-29 17:11:54 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: State variable initialization completed.\n", - "2026-04-29 17:11:54 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Phase equilibrium initialization completed.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Ipopt 3.13.2: linear_solver=\"ma57\"\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: max_iter=200\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: nlp_scaling_method=\"gradient-based\"\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: tol=1e-06\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: ******************************************************************************\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: For more information visit http://projects.coin-or.org/Ipopt\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: This version of Ipopt was compiled from source code available at\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: for large-scale scientific computation. All technical papers, sales and\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: publicity material resulting from use of the HSL codes within IPOPT must\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: contain the following acknowledgement:\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: HSL, a collection of Fortran codes for large-scale scientific\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: computation. See http://www.hsl.rl.ac.uk.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: ******************************************************************************\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of nonzeros in equality constraint Jacobian...: 74\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of nonzeros in inequality constraint Jacobian.: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of nonzeros in Lagrangian Hessian.............: 42\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Total number of variables............................: 18\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: variables with only lower bounds: 6\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: variables with lower and upper bounds: 12\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: variables with only upper bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Total number of equality constraints.................: 18\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Total number of inequality constraints...............: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: inequality constraints with only lower bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: inequality constraints with lower and upper bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: inequality constraints with only upper bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 0 0.0000000e+00 4.13e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Reallocating memory for MA57: lfact (1377)\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 1 0.0000000e+00 4.05e+02 1.89e+12 -1.0 6.07e+01 - 1.92e-01 1.98e-02H 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 2 0.0000000e+00 1.62e+04 1.56e+17 -1.0 8.76e+01 - 1.69e-01 5.07e-01H 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 3 0.0000000e+00 1.62e+04 1.55e+17 -1.0 4.59e+01 - 1.21e-07 3.23e-03H 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 4 0.0000000e+00 2.15e+04 1.93e+17 -1.0 4.88e+01 - 1.06e-02 9.12e-01h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Reallocating memory for MA57: lfact (1542)\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 5 0.0000000e+00 2.15e+04 1.93e+17 -1.0 3.05e+02 - 4.08e-04 6.58e-04h 2\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Reallocating memory for MA57: lfact (1662)\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 6 0.0000000e+00 2.09e+04 1.87e+17 -1.0 1.11e+01 - 4.04e-03 3.08e-02h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 7 0.0000000e+00 1.50e+04 1.37e+17 -1.0 1.37e+01 - 1.44e-04 3.14e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 8 0.0000000e+00 1.49e+04 1.36e+17 -1.0 4.21e+00 - 5.37e-01 9.11e-03h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 9 0.0000000e+00 1.49e+04 1.36e+17 -1.0 4.10e+00 - 9.86e-01 9.35e-05h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 10r 0.0000000e+00 1.49e+04 1.00e+03 1.6 0.00e+00 - 0.00e+00 4.68e-07R 2\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 11r 0.0000000e+00 5.25e+03 2.22e+03 1.6 3.13e+04 - 3.88e-03 1.14e-03f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 12r 0.0000000e+00 5.08e+03 4.24e+04 1.6 1.22e+03 - 1.88e-01 5.18e-03f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 13r 0.0000000e+00 4.77e+03 3.36e+04 1.6 6.27e+01 - 3.06e-02 6.76e-02f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 14r 0.0000000e+00 4.33e+03 1.32e+05 1.6 8.06e+00 - 5.05e-01 9.81e-02f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 15r 0.0000000e+00 4.19e+03 1.12e+05 1.6 9.20e+00 - 3.38e-01 3.25e-02f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 16r 0.0000000e+00 1.89e+03 5.50e+04 1.6 2.54e+00 - 8.42e-02 7.08e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 17r 0.0000000e+00 1.72e+03 4.73e+04 1.6 7.82e+00 - 2.36e-01 1.01e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 18r 0.0000000e+00 1.14e+03 2.84e+04 1.6 1.92e+00 - 7.10e-01 4.02e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 19r 0.0000000e+00 1.06e+03 2.92e+04 1.6 5.12e+00 - 7.85e-01 7.79e-02f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 20r 0.0000000e+00 2.69e+02 3.66e+03 1.6 5.52e-01 - 1.00e+00 9.33e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 21r 0.0000000e+00 1.64e+01 3.96e+02 0.9 1.63e-01 - 9.76e-01 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 22r 0.0000000e+00 6.87e-01 1.09e+02 0.2 3.52e-02 - 1.00e+00 9.59e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 23r 0.0000000e+00 2.05e-01 8.47e+03 -0.5 2.72e-03 - 1.00e+00 6.98e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 24r 0.0000000e+00 1.34e-03 2.18e-01 -0.5 1.87e-03 - 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 25r 0.0000000e+00 1.29e-02 1.88e+02 -2.9 3.36e-04 - 1.00e+00 9.47e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 26r 0.0000000e+00 2.90e-06 4.04e-05 -2.9 7.48e-05 - 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of Iterations....: 26\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: (scaled) (unscaled)\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Constraint violation....: 2.1131334015933589e-08 2.8957967970200116e-06\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Overall NLP error.......: 2.1131334015933589e-08 2.8957967970200116e-06\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of objective function evaluations = 34\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of objective gradient evaluations = 12\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of equality constraint evaluations = 36\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of inequality constraint evaluations = 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of equality constraint Jacobian evaluations = 28\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of inequality constraint Jacobian evaluations = 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of Lagrangian Hessian evaluations = 26\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Total CPU secs in IPOPT (w/o function evaluations) = 0.006\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Total CPU secs in NLP function evaluations = 0.000\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: EXIT: Optimal Solution Found.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Property initialization routine finished.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Starting initialization routine\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Bubble, dew, and critical point initialization completed.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Equilibrium temperature initialization completed.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: State variable initialization completed.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Phase equilibrium initialization completed.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Ipopt 3.13.2: linear_solver=\"ma57\"\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: max_iter=200\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: nlp_scaling_method=\"gradient-based\"\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: tol=1e-06\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: ******************************************************************************\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: For more information visit http://projects.coin-or.org/Ipopt\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: This version of Ipopt was compiled from source code available at\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: for large-scale scientific computation. All technical papers, sales and\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: publicity material resulting from use of the HSL codes within IPOPT must\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: contain the following acknowledgement:\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: HSL, a collection of Fortran codes for large-scale scientific\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: computation. See http://www.hsl.rl.ac.uk.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: ******************************************************************************\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of nonzeros in equality constraint Jacobian...: 74\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of nonzeros in inequality constraint Jacobian.: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of nonzeros in Lagrangian Hessian.............: 42\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Total number of variables............................: 18\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: variables with only lower bounds: 6\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: variables with lower and upper bounds: 12\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: variables with only upper bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Total number of equality constraints.................: 18\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Total number of inequality constraints...............: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: inequality constraints with only lower bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: inequality constraints with lower and upper bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: inequality constraints with only upper bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 0 0.0000000e+00 4.13e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Reallocating memory for MA57: lfact (1377)\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 1 0.0000000e+00 4.05e+02 1.89e+12 -1.0 6.07e+01 - 1.92e-01 1.98e-02H 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 2 0.0000000e+00 1.62e+04 1.56e+17 -1.0 8.76e+01 - 1.69e-01 5.07e-01H 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 3 0.0000000e+00 1.62e+04 1.55e+17 -1.0 4.59e+01 - 1.21e-07 3.23e-03H 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 4 0.0000000e+00 2.15e+04 1.93e+17 -1.0 4.88e+01 - 1.06e-02 9.12e-01h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Reallocating memory for MA57: lfact (1542)\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 5 0.0000000e+00 2.15e+04 1.93e+17 -1.0 3.05e+02 - 4.08e-04 6.58e-04h 2\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Reallocating memory for MA57: lfact (1662)\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 6 0.0000000e+00 2.09e+04 1.87e+17 -1.0 1.11e+01 - 4.04e-03 3.08e-02h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 7 0.0000000e+00 1.50e+04 1.37e+17 -1.0 1.37e+01 - 1.44e-04 3.14e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 8 0.0000000e+00 1.49e+04 1.36e+17 -1.0 4.21e+00 - 5.37e-01 9.11e-03h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 9 0.0000000e+00 1.49e+04 1.36e+17 -1.0 4.10e+00 - 9.86e-01 9.35e-05h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 10r 0.0000000e+00 1.49e+04 1.00e+03 1.6 0.00e+00 - 0.00e+00 4.68e-07R 2\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 11r 0.0000000e+00 5.25e+03 2.22e+03 1.6 3.13e+04 - 3.88e-03 1.14e-03f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 12r 0.0000000e+00 5.08e+03 4.24e+04 1.6 1.22e+03 - 1.88e-01 5.18e-03f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 13r 0.0000000e+00 4.77e+03 3.36e+04 1.6 6.27e+01 - 3.06e-02 6.76e-02f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 14r 0.0000000e+00 4.33e+03 1.32e+05 1.6 8.06e+00 - 5.05e-01 9.81e-02f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 15r 0.0000000e+00 4.19e+03 1.12e+05 1.6 9.20e+00 - 3.38e-01 3.25e-02f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 16r 0.0000000e+00 1.89e+03 5.50e+04 1.6 2.54e+00 - 8.42e-02 7.08e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 17r 0.0000000e+00 1.72e+03 4.73e+04 1.6 7.82e+00 - 2.36e-01 1.01e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 18r 0.0000000e+00 1.14e+03 2.84e+04 1.6 1.92e+00 - 7.10e-01 4.02e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 19r 0.0000000e+00 1.06e+03 2.92e+04 1.6 5.12e+00 - 7.85e-01 7.79e-02f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 20r 0.0000000e+00 2.69e+02 3.66e+03 1.6 5.52e-01 - 1.00e+00 9.33e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 21r 0.0000000e+00 1.64e+01 3.96e+02 0.9 1.63e-01 - 9.76e-01 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 22r 0.0000000e+00 6.87e-01 1.09e+02 0.2 3.52e-02 - 1.00e+00 9.59e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 23r 0.0000000e+00 2.05e-01 8.47e+03 -0.5 2.72e-03 - 1.00e+00 6.98e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 24r 0.0000000e+00 1.34e-03 2.18e-01 -0.5 1.87e-03 - 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 25r 0.0000000e+00 1.29e-02 1.88e+02 -2.9 3.36e-04 - 1.00e+00 9.47e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 26r 0.0000000e+00 2.90e-06 4.04e-05 -2.9 7.48e-05 - 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of Iterations....: 26\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: (scaled) (unscaled)\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Constraint violation....: 2.1131334015933589e-08 2.8957967970200116e-06\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Overall NLP error.......: 2.1131334015933589e-08 2.8957967970200116e-06\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of objective function evaluations = 34\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of objective gradient evaluations = 12\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of equality constraint evaluations = 36\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of inequality constraint evaluations = 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of equality constraint Jacobian evaluations = 28\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of inequality constraint Jacobian evaluations = 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of Lagrangian Hessian evaluations = 26\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Total CPU secs in IPOPT (w/o function evaluations) = 0.008\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Total CPU secs in NLP function evaluations = 0.000\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: EXIT: Optimal Solution Found.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Property initialization routine finished.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase: Control volume properties initialization complete\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase: Control volume reactions initialization complete\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit: Initialization Step 1 Complete.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: Starting initialization routine\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: Bubble, dew, and critical point initialization completed.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: Equilibrium temperature initialization completed.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: State variable initialization completed.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: Phase equilibrium initialization completed.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: Property initialization routine finished.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit: Initialization Step 2 Complete.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Ipopt 3.13.2: linear_solver=\"ma57\"\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: max_iter=200\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: nlp_scaling_method=\"gradient-based\"\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: tol=1e-06\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: ******************************************************************************\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: For more information visit http://projects.coin-or.org/Ipopt\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: This version of Ipopt was compiled from source code available at\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: for large-scale scientific computation. All technical papers, sales and\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: publicity material resulting from use of the HSL codes within IPOPT must\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: contain the following acknowledgement:\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: HSL, a collection of Fortran codes for large-scale scientific\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: computation. See http://www.hsl.rl.ac.uk.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: ******************************************************************************\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of nonzeros in equality constraint Jacobian...: 231\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of nonzeros in inequality constraint Jacobian.: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of nonzeros in Lagrangian Hessian.............: 149\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Total number of variables............................: 51\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: variables with only lower bounds: 12\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: variables with lower and upper bounds: 34\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: variables with only upper bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Total number of equality constraints.................: 51\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Total number of inequality constraints...............: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: inequality constraints with only lower bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: inequality constraints with lower and upper bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: inequality constraints with only upper bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 0 0.0000000e+00 3.62e+06 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Reallocating memory for MA57: lfact (3323)\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 1 0.0000000e+00 3.00e+06 1.18e+02 -1.0 3.71e+04 - 5.00e-01 1.73e-01h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 2 0.0000000e+00 2.99e+06 3.06e+03 -1.0 2.81e+04 - 8.76e-01 3.30e-03h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 3 0.0000000e+00 2.99e+06 8.95e+07 -1.0 2.80e+04 - 9.79e-01 3.34e-05h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 4r 0.0000000e+00 2.99e+06 1.00e+03 1.9 0.00e+00 - 0.00e+00 1.74e-07R 2\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 5r 0.0000000e+00 2.93e+06 9.98e+02 1.9 3.19e+04 - 2.43e-03 2.43e-03f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 6r 0.0000000e+00 2.86e+06 1.02e+03 1.2 3.69e+02 - 3.26e-01 2.09e-03f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 7r 0.0000000e+00 2.23e+06 1.04e+03 1.2 2.85e+02 - 1.93e-01 8.65e-02f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 8r 0.0000000e+00 1.90e+06 1.12e+05 1.2 2.94e+02 - 7.31e-02 2.42e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 9r 0.0000000e+00 1.44e+06 7.08e+04 1.2 1.51e+02 - 7.79e-01 2.13e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 10r 0.0000000e+00 1.21e+06 3.79e+04 1.2 1.60e+00 2.0 4.46e-01 1.46e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 11r 0.0000000e+00 7.63e+04 1.14e+04 1.2 9.97e+01 - 3.46e-01 9.00e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 12r 0.0000000e+00 4.57e+04 2.79e+04 1.2 8.49e+01 - 1.00e+00 2.61e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 13r 0.0000000e+00 5.79e+04 9.55e+03 1.2 3.35e+01 - 1.00e+00 7.44e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 14r 0.0000000e+00 1.21e+05 1.45e+04 1.2 2.11e+01 - 1.00e+00 1.00e+00h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 15r 0.0000000e+00 2.24e+05 6.34e+02 1.2 7.86e+00 - 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 16r 0.0000000e+00 2.19e+05 4.22e+03 0.5 1.77e+00 - 1.00e+00 9.43e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 17r 0.0000000e+00 3.93e+05 6.53e+02 0.5 1.02e+02 - 5.02e-01 4.46e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 18r 0.0000000e+00 4.24e+05 4.17e+03 0.5 1.55e+01 - 1.00e+00 2.17e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 19r 0.0000000e+00 4.87e+05 1.47e+01 0.5 7.37e+00 - 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 20r 0.0000000e+00 5.23e+05 2.31e+03 -0.9 1.53e+00 - 9.40e-01 7.50e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 21r 0.0000000e+00 5.39e+05 7.30e+03 -0.9 2.08e+02 - 8.07e-01 3.86e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 22r 0.0000000e+00 5.39e+05 5.05e+03 -0.9 1.37e+02 - 1.00e+00 4.43e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 23r 0.0000000e+00 5.38e+05 7.93e+00 -0.9 7.27e+01 - 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 24r 0.0000000e+00 5.39e+05 1.75e-03 -0.9 2.41e-01 - 1.00e+00 1.00e+00h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 25r 0.0000000e+00 5.44e+05 2.59e+01 -3.6 3.79e+00 - 9.90e-01 9.73e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 26r 0.0000000e+00 4.44e+05 3.73e+02 -3.6 6.08e+03 - 7.62e-02 6.44e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 27r 0.0000000e+00 3.34e+05 7.09e+02 -3.6 2.85e+03 - 5.42e-02 9.37e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 28r 0.0000000e+00 2.87e+03 9.51e+02 -3.6 1.42e+03 - 1.73e-01 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 29r 0.0000000e+00 8.65e+04 2.35e+02 -3.6 1.10e+03 - 1.00e+00 1.00e+00H 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 30r 0.0000000e+00 8.28e+04 4.88e-01 -3.6 1.19e+02 - 1.00e+00 1.00e+00h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 31r 0.0000000e+00 8.28e+04 9.25e-05 -3.6 2.69e-01 - 1.00e+00 1.00e+00h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 32r 0.0000000e+00 8.28e+04 2.10e+00 -5.4 5.64e-02 - 1.00e+00 9.70e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 33r 0.0000000e+00 8.28e+04 2.49e+02 -5.4 1.00e-03 1.5 8.85e-01 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 34r 0.0000000e+00 8.27e+04 3.33e-02 -5.4 3.00e-03 1.0 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 35r 0.0000000e+00 8.27e+04 3.31e-02 -5.4 8.93e-03 0.6 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 36r 0.0000000e+00 8.26e+04 3.24e-02 -5.4 2.63e-02 0.1 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 37r 0.0000000e+00 8.23e+04 3.06e-02 -5.4 7.43e-02 -0.4 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 38r 0.0000000e+00 8.16e+04 2.59e-02 -5.4 1.89e-01 -0.9 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 39r 0.0000000e+00 8.02e+04 4.92e-02 -5.4 3.67e-01 -1.3 1.00e+00 1.00e+00h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 40r 0.0000000e+00 7.85e+04 6.76e-02 -5.4 1.01e+00 -1.8 1.00e+00 1.00e+00h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 41r 0.0000000e+00 7.76e+04 2.21e-02 -5.4 3.03e+00 -2.3 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 42r 0.0000000e+00 7.73e+04 1.54e-02 -5.4 9.07e+00 -2.8 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 43r 0.0000000e+00 7.69e+04 1.54e-02 -5.4 2.72e+01 -3.2 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 44r 0.0000000e+00 7.57e+04 9.45e-02 -5.4 8.16e+01 -3.7 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 45r 0.0000000e+00 7.21e+04 7.98e-01 -5.4 2.45e+02 -4.2 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 46r 0.0000000e+00 6.17e+04 5.91e+00 -5.4 7.40e+02 -4.7 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 47r 0.0000000e+00 3.69e+04 5.13e+01 -5.4 2.31e+03 -5.2 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 48r 0.0000000e+00 7.15e+04 1.47e+02 -5.4 1.10e+04 -5.6 1.00e+00 2.17e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 49r 0.0000000e+00 7.15e+04 4.98e+02 -5.4 4.07e+03 -5.2 1.00e+00 5.56e-06h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 50r 0.0000000e+00 2.07e+05 4.58e+03 -5.4 2.01e+04 -5.7 4.61e-01 1.75e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 51r 0.0000000e+00 1.19e+06 4.31e+04 -5.4 9.31e+03 -5.3 2.11e-06 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 52r 0.0000000e+00 1.16e+06 3.63e+04 -5.4 1.14e+02 -0.3 4.01e-01 1.23e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 53r 0.0000000e+00 1.16e+06 3.63e+04 -5.4 2.83e+01 0.1 7.36e-01 7.74e-07h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 54r 0.0000000e+00 1.16e+06 3.63e+04 -5.4 3.94e+03 - 1.59e-01 7.41e-06h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 55r 0.0000000e+00 7.95e+05 2.50e+04 -5.4 4.00e+03 - 7.84e-01 3.17e-01h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 56r 0.0000000e+00 3.83e+05 1.19e+04 -5.4 1.69e+03 - 1.35e-05 5.23e-01h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 57r 0.0000000e+00 2.95e+05 9.19e+03 -5.4 9.94e+00 -0.4 5.56e-01 2.31e-01h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 58r 0.0000000e+00 1.29e+04 7.45e+02 -5.4 1.55e+03 - 2.88e-06 1.00e+00h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 59r 0.0000000e+00 1.05e+04 3.57e+00 -5.4 8.95e-02 -0.8 1.00e+00 1.00e+00h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 60r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 7.60e-02 -1.3 1.00e+00 1.00e+00h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 61r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 2.28e-01 -1.8 1.00e+00 2.50e-01h 3\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 62r 0.0000000e+00 1.05e+04 1.03e-02 -5.4 6.84e-01 -2.3 1.00e+00 1.56e-02h 7\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 63r 0.0000000e+00 1.05e+04 3.12e-02 -5.4 2.05e+00 -2.8 1.00e+00 9.77e-04h 11\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 64r 0.0000000e+00 1.05e+04 9.35e-02 -5.4 6.16e+00 -3.2 1.00e+00 1.22e-04h 14\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 65r 0.0000000e+00 1.05e+04 2.81e-01 -5.4 1.85e+01 -3.7 1.00e+00 7.45e-09h 28\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 66r 0.0000000e+00 1.05e+04 8.49e-01 -5.4 5.60e+01 -4.2 1.00e+00 1.86e-09h 30\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 67r 0.0000000e+00 1.05e+04 2.61e+00 -5.4 1.72e+02 -4.7 1.00e+00 1.16e-10h 34\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 68r 0.0000000e+00 1.05e+04 8.40e+00 -5.4 5.54e+02 -5.1 1.00e+00 3.64e-12h 39\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 69r 0.0000000e+00 1.05e+04 8.40e+00 -5.4 2.14e+03 -5.6 0.00e+00 3.59e-18R 58\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 70r 0.0000000e+00 1.05e+04 1.94e+01 -5.4 4.50e+04 -6.1 1.63e-02 1.43e-12f 35\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 71r 0.0000000e+00 1.05e+04 3.85e+01 -5.4 2.54e+03 -5.7 1.00e+00 1.27e-11f 36\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 72r 0.0000000e+00 1.05e+04 1.11e+01 -5.4 7.22e+02 -5.2 9.93e-01 2.91e-11f 36\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 73r 0.0000000e+00 1.05e+04 3.70e+01 -5.4 3.05e+03 -5.7 7.35e-01 1.32e-12f 39\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 74r 0.0000000e+00 1.05e+04 1.25e+01 -5.4 8.27e+02 -5.3 1.00e+00 3.64e-12f 39\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 75r 0.0000000e+00 1.05e+04 3.60e+01 -5.4 3.72e+03 -5.8 5.36e-01 1.35e-13f 42\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 76r 0.0000000e+00 1.05e+04 1.44e+01 -5.4 9.51e+02 -5.3 1.00e+00 1.14e-13f 44\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 77r 0.0000000e+00 1.05e+04 2.35e+01 -5.4 4.61e+03 -5.8 1.64e-01 1.36e-14f 45\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 78r 0.0000000e+00 1.05e+04 1.66e+01 -5.4 1.10e+03 -5.4 1.00e+00 3.55e-15f 49\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 79r 0.0000000e+00 1.05e+04 2.55e+01 -5.4 5.86e+03 -5.9 1.22e-01 3.35e-16f 50\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 80r 0.0000000e+00 2.67e+04 5.84e+01 -5.4 1.27e+03 -5.4 1.00e+00 8.72e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 81r 0.0000000e+00 2.67e+04 2.19e+03 -5.4 1.28e+03 - 4.11e-03 2.62e-05w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 82r 0.0000000e+00 4.42e+04 8.23e+02 -5.4 3.84e+03 -5.9 5.02e-01 4.78e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 83r 0.0000000e+00 1.05e+04 1.92e+01 -5.4 1.21e+04 - 1.00e+00 7.74e-16f 50\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 84r 0.0000000e+00 1.05e+04 2.07e+01 -5.4 1.47e+03 -5.5 4.87e-01 3.33e-16h 52\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 85r 0.0000000e+00 1.05e+04 5.09e+01 -5.4 1.08e+04 -6.0 2.11e-01 1.14e-17f 54\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 86r 0.0000000e+00 1.05e+04 6.78e+01 -5.4 1.72e+03 -5.5 1.00e+00 1.78e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 87r 0.0000000e+00 1.05e+04 1.11e+02 -5.4 1.65e+04 -6.0 4.54e-02 1.86e-18f 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 88r 0.0000000e+00 1.05e+04 2.03e+02 -5.4 2.02e+03 -5.6 1.00e+00 1.52e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 89r 0.0000000e+00 1.05e+04 3.30e+02 -5.4 3.06e+04 -6.1 2.34e-02 1.00e-18f 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 90r 0.0000000e+00 1.05e+04 7.12e+02 -5.4 2.38e+03 -5.7 1.00e+00 1.29e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 91r 0.0000000e+00 1.05e+04 7.29e+02 -5.4 9.01e+04 -6.1 3.00e-04 3.41e-19f 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 92r 0.0000000e+00 1.05e+04 3.99e+01 -5.4 2.95e+03 -5.7 3.70e-01 2.84e-18h 59\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 93r 0.0000000e+00 2.20e+04 3.07e+01 -5.4 7.91e+02 -5.3 1.00e+00 1.00e+00w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 94r 0.0000000e+00 3.01e+04 4.20e+01 -5.4 2.61e+03 -5.8 7.22e-01 2.55e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 95r 0.0000000e+00 3.01e+04 1.37e+03 -5.4 1.07e+03 - 1.99e-03 3.17e-05w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 96r 0.0000000e+00 1.05e+04 1.20e+01 -5.4 7.00e+03 -6.2 1.00e+00 1.78e-15h 49\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 97r 0.0000000e+00 1.05e+04 2.31e+01 -5.4 4.29e+03 -5.8 2.10e-01 6.00e-11f 33\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 98r 0.0000000e+00 1.05e+04 1.59e+01 -5.4 1.05e+03 -5.4 1.00e+00 7.28e-12f 38\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 99r 0.0000000e+00 1.05e+04 2.46e+01 -5.4 5.40e+03 -5.9 1.33e-01 4.76e-11f 33\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 100r 0.0000000e+00 1.05e+04 1.83e+01 -5.4 1.21e+03 -5.4 1.00e+00 1.07e-10f 34\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 101r 0.0000000e+00 1.05e+04 2.73e+01 -5.4 7.03e+03 -5.9 1.02e-01 3.66e-11f 33\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 102r 0.0000000e+00 1.05e+04 2.77e+01 -5.4 1.40e+03 -5.5 1.00e+00 1.43e-12f 40\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 103r 0.0000000e+00 1.05e+04 4.37e+01 -5.4 9.60e+03 -6.0 7.47e-02 5.24e-14f 42\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 104r 0.0000000e+00 1.05e+04 6.49e+01 -5.4 1.63e+03 -5.5 1.00e+00 7.69e-14f 44\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 105r 0.0000000e+00 1.05e+04 1.04e+02 -5.4 1.42e+04 -6.0 5.06e-02 1.11e-15f 47\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 106r 0.0000000e+00 2.67e+04 1.58e+01 -5.4 1.91e+03 -5.6 1.00e+00 5.77e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 107r 0.0000000e+00 2.67e+04 1.40e+03 -5.4 9.67e+02 - 2.90e-03 3.66e-04w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 108r 0.0000000e+00 4.39e+04 4.78e+02 -5.4 5.57e+03 -6.1 3.84e-01 3.25e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 109r 0.0000000e+00 1.05e+04 1.80e+02 -5.4 6.38e+03 - 1.00e+00 4.10e-15f 47\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 110r 0.0000000e+00 1.05e+04 2.40e+02 -5.4 2.26e+03 -5.6 3.17e-01 3.47e-15f 48\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 111r 0.0000000e+00 1.05e+04 5.44e+02 -5.4 6.90e+04 -6.1 2.06e-02 1.14e-16f 48\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 112r 0.0000000e+00 1.05e+04 4.95e+01 -5.4 2.79e+03 -5.7 2.55e-01 7.69e-16f 51\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 113r 0.0000000e+00 1.05e+04 1.15e+01 -5.4 7.57e+02 -5.3 1.00e+00 7.11e-15f 48\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 114r 0.0000000e+00 1.05e+04 2.06e+01 -5.4 3.26e+03 -5.7 2.41e-01 6.02e-16f 50\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 115r 0.0000000e+00 1.05e+04 1.32e+01 -5.4 8.68e+02 -5.3 1.00e+00 2.22e-16h 53\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 116r 0.0000000e+00 1.05e+04 2.17e+01 -5.4 3.99e+03 -5.8 1.79e-01 3.07e-17h 54\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 117r 0.0000000e+00 1.05e+04 1.51e+01 -5.4 9.98e+02 -5.4 1.00e+00 2.78e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 118r 0.0000000e+00 1.05e+04 2.38e+01 -5.4 4.99e+03 -5.8 1.44e-01 6.14e-18h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 119r 0.0000000e+00 2.67e+04 5.98e+01 -5.4 1.15e+03 -5.4 1.00e+00 9.60e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 120r 0.0000000e+00 2.67e+04 2.31e+03 -5.4 1.66e+03 - 4.25e-03 1.30e-05w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 121r 0.0000000e+00 4.43e+04 8.41e+02 -5.4 3.52e+03 -5.9 5.33e-01 5.24e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 122r 0.0000000e+00 1.05e+04 1.75e+01 -5.4 1.31e+04 - 1.00e+00 2.66e-17h 55\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 123r 0.0000000e+00 1.05e+04 1.89e+01 -5.4 1.33e+03 -5.5 5.38e-01 2.30e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 124r 0.0000000e+00 1.05e+04 4.92e+01 -5.4 8.61e+03 -5.9 2.71e-01 3.56e-18h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 125r 0.0000000e+00 1.05e+04 2.98e+01 -5.4 1.55e+03 -5.5 1.00e+00 1.98e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 126r 0.0000000e+00 1.05e+04 4.92e+01 -5.4 1.23e+04 -6.0 6.33e-02 2.48e-18h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 127r 0.0000000e+00 1.05e+04 8.12e+01 -5.4 1.82e+03 -5.6 1.00e+00 1.69e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 128r 0.0000000e+00 1.05e+04 1.31e+02 -5.4 2.00e+04 -6.0 3.59e-02 1.53e-18f 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 129r 0.0000000e+00 1.05e+04 2.54e+02 -5.4 2.14e+03 -5.6 1.00e+00 1.43e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 130r 0.0000000e+00 1.05e+04 4.15e+02 -5.4 4.32e+04 -6.1 1.66e-02 7.10e-19f 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 131r 0.0000000e+00 1.05e+04 9.52e+02 -5.4 2.53e+03 -5.7 1.00e+00 1.21e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 132r 0.0000000e+00 2.67e+04 2.24e+01 -5.4 4.51e+05 -6.1 1.18e-04 2.45e-03w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 133r 0.0000000e+00 4.32e+04 1.53e+02 -5.4 4.75e+04 -6.6 3.50e-02 3.68e-02w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 134r 0.0000000e+00 4.32e+04 3.80e+02 -5.4 3.44e+03 - 1.99e-02 3.86e-06w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 135r 0.0000000e+00 1.05e+04 9.98e+02 -5.4 8.04e+02 - 1.18e-04 6.81e-20f 55\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 136r 0.0000000e+00 1.05e+04 2.21e+01 -5.4 8.37e+02 -5.3 6.52e-01 5.55e-17h 55\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 137r 0.0000000e+00 1.05e+04 2.91e+01 -5.4 3.73e+03 -5.8 2.04e-01 8.22e-18h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 138r 0.0000000e+00 1.05e+04 1.45e+01 -5.4 9.53e+02 -5.3 1.00e+00 5.55e-17h 55\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 139r 0.0000000e+00 1.05e+04 2.31e+01 -5.4 4.63e+03 -5.8 1.55e-01 6.62e-18h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 140r 0.0000000e+00 1.05e+04 1.67e+01 -5.4 1.10e+03 -5.4 1.00e+00 2.78e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 141r 0.0000000e+00 1.05e+04 2.55e+01 -5.4 5.89e+03 -5.9 1.22e-01 5.20e-18h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 142r 0.0000000e+00 1.05e+04 1.93e+01 -5.4 1.27e+03 -5.4 1.00e+00 2.41e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 143r 0.0000000e+00 1.05e+04 2.84e+01 -5.4 7.78e+03 -5.9 9.22e-02 3.94e-18h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 144r 0.0000000e+00 1.05e+04 3.40e+01 -5.4 1.48e+03 -5.5 1.00e+00 2.08e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 145r 0.0000000e+00 2.67e+04 4.04e+01 -5.4 1.09e+04 -6.0 6.60e-02 1.02e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 146r 0.0000000e+00 2.67e+04 1.47e+03 -5.4 1.02e+03 - 2.88e-03 1.10e-04w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 147r 0.0000000e+00 4.33e+04 7.00e+02 -5.4 1.97e+04 -6.5 1.24e-01 8.93e-02w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 148r 0.0000000e+00 1.05e+04 5.40e+01 -5.4 6.24e+03 - 6.60e-02 2.82e-18h 55\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 149r 0.0000000e+00 1.05e+04 1.51e+02 -5.4 1.68e+04 -6.0 1.26e-01 1.83e-18h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 150r 0.0000000e+00 1.05e+04 5.58e+01 -5.4 2.10e+03 -5.6 1.51e-01 9.25e-19h 60\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 151r 0.0000000e+00 1.05e+04 6.31e+01 -5.4 3.28e+04 -6.1 1.66e-02 9.36e-19f 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 152r 0.0000000e+00 1.05e+04 6.32e+01 -5.4 3.63e+03 -5.7 8.61e-03 1.56e-18h 54\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 153r 0.0000000e+00 1.05e+04 6.33e+01 -5.4 2.10e+05 -6.1 1.98e-05 1.48e-19f 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 154r 0.0000000e+00 1.05e+04 8.87e-01 -5.4 1.46e-02 -0.3 1.00e+00 1.43e-06h 4\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 155r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 2.09e-02 -0.8 1.00e+00 5.00e-01f 2\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 156r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 6.26e-02 -1.2 1.00e+00 2.44e-04h 13\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 157r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 1.88e-01 -1.7 1.00e+00 1.53e-05h 17\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 158r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 5.64e-01 -2.2 1.00e+00 1.00e+00w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 159r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 1.69e+00 -2.7 1.00e+00 1.00e+00w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 160r 0.0000000e+00 1.06e+04 3.62e-03 -5.4 5.08e+00 -3.1 1.00e+00 1.00e+00w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 161r 0.0000000e+00 1.05e+04 8.60e-03 -5.4 1.53e+01 -3.6 1.00e+00 7.45e-09h 27\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 162r 0.0000000e+00 1.05e+04 6.99e-01 -5.4 4.61e+01 -4.1 1.00e+00 1.14e-13h 44\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 163r 0.0000000e+00 1.05e+04 2.14e+00 -5.4 1.41e+02 -4.6 1.00e+00 2.84e-14h 46\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 164r 0.0000000e+00 1.05e+04 6.79e+00 -5.4 4.48e+02 -5.1 1.00e+00 4.66e-10f 32\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 165r 0.0000000e+00 1.05e+04 2.13e+01 -5.4 1.64e+03 -5.5 8.03e-01 1.96e-11f 36\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 166r 0.0000000e+00 1.05e+04 5.45e+01 -5.4 1.44e+04 -6.0 1.69e-01 5.60e-13f 38\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 167r 0.0000000e+00 1.05e+04 2.91e+01 -5.4 1.92e+03 -5.6 1.00e+00 1.31e-13f 43\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 168r 0.0000000e+00 1.05e+04 3.94e+01 -5.4 2.52e+04 -6.1 2.91e-02 3.11e-16f 48\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 169r 0.0000000e+00 1.05e+04 3.44e+01 -5.4 2.27e+03 -5.6 1.00e+00 3.46e-15h 48\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 170r 0.0000000e+00 1.05e+04 4.50e+01 -5.4 7.69e+04 -6.1 9.32e-03 1.28e-17f 51\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 171r 0.0000000e+00 2.67e+04 3.33e+01 -5.4 2.71e+03 -5.7 1.00e+00 4.08e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 172r 0.0000000e+00 2.67e+04 9.73e+02 -5.4 1.12e+03 - 1.93e-03 9.14e-05w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 173r 0.0000000e+00 4.37e+04 5.94e+02 -5.4 7.46e+03 -6.2 2.29e-01 2.40e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 174r 0.0000000e+00 1.05e+04 4.51e+01 -5.4 3.87e+03 - 1.00e+00 2.97e-12f 37\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 175r 0.0000000e+00 1.05e+04 6.47e+01 -5.4 3.27e+03 -5.7 2.19e-01 7.69e-14f 43\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 176r 0.0000000e+00 1.05e+04 5.10e+01 -5.4 8.69e+02 -5.3 1.00e+00 1.14e-13h 44\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 177r 0.0000000e+00 1.05e+04 7.51e+01 -5.4 4.00e+03 -5.8 1.79e-01 6.43e-11f 33\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 178r 0.0000000e+00 1.05e+04 6.82e+01 -5.4 1.00e+03 -5.4 1.00e+00 4.66e-10f 32\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 179r 0.0000000e+00 1.05e+04 1.03e+02 -5.4 5.00e+03 -5.8 1.43e-01 1.29e-11f 35\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 180r 0.0000000e+00 1.05e+04 1.08e+02 -5.4 1.15e+03 -5.4 1.00e+00 1.39e-11f 37\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 181r 0.0000000e+00 1.05e+04 1.65e+02 -5.4 6.42e+03 -5.9 1.12e-01 5.01e-12f 36\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 182r 0.0000000e+00 1.05e+04 2.00e+02 -5.4 1.34e+03 -5.5 1.00e+00 1.20e-11f 37\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 183r 0.0000000e+00 1.05e+04 3.13e+02 -5.4 8.54e+03 -5.9 8.39e-02 9.41e-13f 38\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 184r 0.0000000e+00 2.67e+04 6.63e+01 -5.4 1.55e+03 -5.5 1.00e+00 7.13e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 185r 0.0000000e+00 2.67e+04 8.09e+02 -5.4 1.01e+03 - 2.25e-03 8.90e-04w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 186r 0.0000000e+00 4.40e+04 1.17e+02 -5.4 4.65e+03 -6.0 4.39e-01 3.92e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 187r 0.0000000e+00 1.05e+04 4.40e+02 -5.4 8.89e+03 - 1.00e+00 2.07e-11f 35\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 188r 0.0000000e+00 1.05e+04 5.51e+02 -5.4 1.81e+03 -5.6 3.96e-01 8.88e-12f 37\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 189r 0.0000000e+00 1.05e+04 8.25e+02 -5.4 1.87e+04 -6.0 3.12e-02 1.08e-13f 40\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 190r 0.0000000e+00 1.05e+04 3.35e+01 -5.4 2.20e+03 -5.6 4.67e-01 2.27e-13f 43\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 191r 0.0000000e+00 1.05e+04 4.40e+01 -5.4 4.69e+04 -6.1 1.56e-02 5.36e-15f 43\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 192r 0.0000000e+00 1.05e+04 3.87e+01 -5.4 2.56e+03 -5.7 1.00e+00 2.46e-14f 45\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 193r 0.0000000e+00 1.05e+04 1.92e+01 -5.4 7.26e+02 -5.2 9.88e-01 1.14e-13h 44\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 194r 0.0000000e+00 1.05e+04 4.68e+01 -5.4 3.07e+03 -5.7 7.96e-01 1.68e-10f 32\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 195r 0.0000000e+00 1.05e+04 3.54e+01 -5.4 8.31e+02 -5.3 1.00e+00 5.82e-11f 35\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 196r 0.0000000e+00 1.05e+04 8.07e+01 -5.4 3.74e+03 -5.8 5.32e-01 6.87e-11f 33\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 197r 0.0000000e+00 2.44e+04 4.51e+01 -5.4 9.55e+02 -5.3 1.00e+00 1.00e+00w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 198r 0.0000000e+00 2.90e+04 1.83e+02 -5.4 3.03e+03 -5.8 6.02e-01 1.26e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 199r 0.0000000e+00 2.90e+04 3.65e+02 -5.4 1.03e+03 - 1.58e-03 1.30e-03w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 200r 0.0000000e+00 1.05e+04 6.99e+01 -5.4 9.09e+03 -6.3 1.00e+00 2.91e-11f 35\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of Iterations....: 200\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: (scaled) (unscaled)\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Dual infeasibility......: 6.9908071367141474e+01 6.9908071367141474e+01\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Constraint violation....: 2.8645094423111342e-03 1.0458847092153306e+04\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Complementarity.........: 1.3579265591895737e-03 1.3579265591895737e-03\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Overall NLP error.......: 2.8645094423111342e-03 1.0458847092153306e+04\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of objective function evaluations = 5209\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of objective gradient evaluations = 6\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of equality constraint evaluations = 5210\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of inequality constraint evaluations = 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of equality constraint Jacobian evaluations = 203\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of inequality constraint Jacobian evaluations = 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of Lagrangian Hessian evaluations = 200\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Total CPU secs in IPOPT (w/o function evaluations) = 0.176\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Total CPU secs in NLP function evaluations = 0.014\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: EXIT: Maximum Number of Iterations Exceeded.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit: Initialization Step 3 maxIterations - .\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit: Initialization Complete: maxIterations - \n", - "Initialization failed.\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "import logging\n", + "import traceback\n", + "\n", "from pyomo.environ import (\n", " ComponentMap,\n", " ConcreteModel,\n", @@ -615,14 +111,19 @@ " return m\n", "\n", "\n", - "if __name__ == \"__main__\":\n", - " m = create_model()\n", - "\n", - " reboiler_init = m.fs.unit.default_initializer(always_estimate_states=True)\n", - " try:\n", - " reboiler_init.initialize(m.fs.unit, output_level=idaeslog.DEBUG)\n", - " except InitializationError:\n", - " print(\"Initialization failed.\")" + "m = create_model()\n", + "reboiler_init = m.fs.unit.default_initializer(always_estimate_states=True)\n", + "try:\n", + " reboiler_init.initialize(m.fs.unit, output_level=idaeslog.DEBUG)\n", + "except InitializationError:\n", + " traceback.print_exc()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here we see that initialization failed due to the unit model solve terminating after reaching the maximum number of iterations. However, when solution of a square problem reaches 200-300 iterations without converging, increasing the number of iterations usually does not help. In this case, it terminates with a `Restoration Failed` status after about 500 iterations. When confronted with a failing solve, we should first head to the `DiagnosticsToolbox`." ] }, { @@ -630,54 +131,77 @@ "metadata": {}, "source": [ "## Step 2: Run Model Diagnostics\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "While initialization fails in every version of Python supported presently (3.10, 3.11, 3.12 3.13), the model termination point(s) that Python 3.10 and 3.11 come to are different than the model termination point that 3.12 and 3.13 come to. In order to ensure that the diagnostic output is the same in every supported version, we load the model state from a `json` file." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [ + "testing" + ] + }, + "outputs": [], + "source": [ + "# Uncomment this cell in order to regenerate the cached solution\n", + "# from idaes.core.util import to_json\n", + "# to_json(m, fname=\"advanced_scaling_failed_solution.json\", human_read=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "from idaes.core.util import from_json, StoreSpec\n", "\n", - "We see that the unit model failed to initialize. When confronted with a bad solution state, we should first use the `DiagnosticsToolbox` to check to see if there are structural issues with the model." + "from_json(m, fname=\"advanced_scaling_failed_solution.json\", wts=StoreSpec.value())" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "First, we will use the `DiagnosticsToolbox` to check to see if there are structural issues with the model. (More information about the `DiagnosticsToolbox` can be found in its [documentation](https://idaes-pse.readthedocs.io/en/stable/explanations/model_diagnostics/index.html) and [tutorial notebook](https://idaes-examples.readthedocs.io/en/latest/docs/diagnostics/diagnostics_toolbox_doc.html)" ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": { - "scrolled": true + "editable": true, + "scrolled": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "====================================================================================\n", - "Model Statistics\n", - "\n", - " Activated Blocks: 23 (Deactivated: 0)\n", - " Free Variables in Activated Constraints: 77 (External: 0)\n", - " Free Variables with only lower bounds: 15\n", - " Free Variables with only upper bounds: 0\n", - " Free Variables with upper and lower bounds: 50\n", - " Fixed Variables in Activated Constraints: 66 (External: 0)\n", - " Activated Equality Constraints: 77 (Deactivated: 0)\n", - " Activated Inequality Constraints: 0 (Deactivated: 0)\n", - " Activated Objectives: 0 (Deactivated: 0)\n", - "\n", - "------------------------------------------------------------------------------------\n", - "1 WARNINGS\n", - "\n", - " WARNING: Found 9 potential evaluation errors.\n", - "\n", - "------------------------------------------------------------------------------------\n", - "2 Cautions\n", - "\n", - " Caution: 11 variables fixed to 0\n", - " Caution: 82 unused variables (82 fixed)\n", - "\n", - "------------------------------------------------------------------------------------\n", - "Suggested next steps:\n", - "\n", - " display_potential_evaluation_errors()\n", - "\n", - "====================================================================================\n" - ] - } - ], + "outputs": [], "source": [ "from idaes.core.util import DiagnosticsToolbox\n", "\n", @@ -689,63 +213,23 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "The density relationship is being flagged for potential evaluation errors. The interval arithmetic used to identify potential evaluation errors can produce relatively loose bounds, especially for the sort of large polynomial expressions favored in the literature. Independent testing of the density relationship over a wide range of values has demonstrated that no evaluation errors occur, so we can ignore these warnings.\n", + "The density relationship is being flagged for potential evaluation errors. The interval arithmetic used to identify potential evaluation errors can produce relatively loose bounds, especially for the sort of large polynomial expressions favored in engineering literature. Independent testing of the density relationship over a wide range of values has demonstrated that no evaluation errors occur, so we can ignore these warnings.\n", "\n", "The next step is determining which numerical issues exist." ] }, { "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "====================================================================================\n", - "Model Statistics\n", - "\n", - " Jacobian Condition Number: 2.718E+13\n", - "\n", - "------------------------------------------------------------------------------------\n", - "3 WARNINGS\n", - "\n", - " WARNING: 3 Constraints with large residuals (>1.0E-05)\n", - " WARNING: 1 Variable with extreme Jacobian column norms (<1.0E-08 or >1.0E+08)\n", - " WARNING: 1 Constraint with extreme Jacobian row norms (<1.0E-08 or >1.0E+08)\n", - "\n", - "------------------------------------------------------------------------------------\n", - "8 Cautions\n", - "\n", - " Caution: 9 Variables with value close to their bounds (abs=1.0E-04, rel=1.0E-04)\n", - " Caution: 18 Variables with value close to zero (tol=1.0E-08)\n", - " Caution: 30 Variables with extreme value (<1.0E-04 or >1.0E+04)\n", - " Caution: 2 Constraints with mismatched terms\n", - " Caution: 1 Constraint with potential cancellation of terms\n", - " Caution: 27 Variables with extreme Jacobian column norms (<1.0E-04 or >1.0E+04)\n", - " Caution: 16 Constraints with extreme Jacobian row norms (<1.0E-04 or >1.0E+04)\n", - " Caution: 50 extreme Jacobian Entries (<1.0E-04 or >1.0E+04)\n", - "\n", - "------------------------------------------------------------------------------------\n", - "Suggested next steps:\n", - "\n", - " display_constraints_with_large_residuals()\n", - " compute_infeasibility_explanation()\n", - " display_variables_with_extreme_jacobians()\n", - " display_constraints_with_extreme_jacobians()\n", - "\n", - "====================================================================================\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "dt.report_numerical_issues()" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": { "tags": [ "testing" @@ -805,43 +289,14 @@ "$$\n", "With a condition number on the order of $10^{13}$ and the default tolerance $\\varepsilon = 10^{-6}$, then the difference between the computed solution $x_f$ and the true solution $x$ could be on the order of $10^7$.\n", "\n", - "In practice, however, we frequently end up with much better results than those predicted by this worst-case bound. Frequently, we find that most constraints have residuals on the order of $10^{-10}$ or less, with a few problematic constraints having larger residuals. That is the case here." + "In practice, however, we frequently end up with much better results than those predicted by this worst-case bound. The condition number of the unscaled Jacobian does not taken into account that some variables are much bigger than others. For example, the liquid phase mole fraction of $\\text{CO}_2$ is on the order of $10^{-5}$, whereas the heat duty is on the order of $10^6$. Unless we scale the model, we have no way of determining which changes to the solution are significant and which are not. Additionally, we frequently find that most constraints have residuals on the order of $10^{-10}$ or less, with only a few problematic constraints having larger residuals. That is the case here." ] }, { "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Number of constraints: 77\n", - "====================================================================================\n", - "The following constraint(s) have large residuals (>1.0E-10):\n", - "\n", - " fs.unit.unit_material_balance[0.0,CO2]: 1.84866E-10\n", - " fs.unit.unit_material_balance[0.0,N2]: 1.89950E-10\n", - " fs.unit.unit_material_balance[0.0,O2]: 1.87656E-10\n", - " fs.unit.unit_phase_equilibrium[0.0,CO2]: 1.04588E+04\n", - " fs.unit.unit_phase_equilibrium[0.0,H2O]: 8.88278E-07\n", - " fs.unit.unit_enthalpy_balance[0.0]: 5.05679E-10\n", - " fs.unit.liquid_phase.material_balances[0.0,CO2]: 1.70459E-10\n", - " fs.unit.liquid_phase.enthalpy_balances[0.0]: 1.17285E-05\n", - " fs.unit.liquid_phase.properties_out[0.0].sum_mole_frac_out: 2.08134E-10\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-]: 8.83857E-06\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]: 1.54414E-07\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA_+]: 7.69821E-06\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,H2O]: 2.50511E-08\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA]: 4.55346E-06\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2]: 4.42749E-05\n", - " fs.unit.vapor_phase[0.0].sum_mole_frac_out: 1.71144E-10\n", - "\n", - "====================================================================================\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "import idaes.core.util.model_statistics as mstat\n", "\n", @@ -863,7 +318,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -1098,14 +553,12 @@ "\n", "## Step 3: Creating a New Scaler Class\n", "\n", - "To create a new scaling routine for the equilibrium reactor, we start by creating a new ``Scaler`` class which inherits from the ``CustomScalerBase`` class in ``idaes.core.scaling``. The ``CustomScalerBase`` class contains a number of useful methods to help us in developing our scaling routine, including some placeholder methods for implementing a standard scaling workflow and helper methods for doing common tasks.\n", - "\n", - "The cell below shows how to create our new class which we will name ``SolventReboilerScaler`` as well as two key methods we will fill out as part of this workshop." + "To create a new scaling routine for the solvent reboiler, we start by creating a new ``Scaler`` class which inherits from the ``CustomScalerBase`` class in ``idaes.core.scaling``." ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -1130,7 +583,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "As you know from the first scaling tutorial, the ``variable_scaling_routine`` and ``constraint_scaling_routine`` methods are used to implement subroutines for scaling the variables and constraints in the model respectively. Separately, there is a ``scale_model`` method that will call each of these in sequence in order to scale an entire model by applying the following steps:\n", + "As you know from the [first scaling tutorial](./scaler_workshop_test.ipynb), the ``variable_scaling_routine`` and ``constraint_scaling_routine`` methods are used to implement subroutines for scaling the variables and constraints in the model respectively. Separately, there is a ``scale_model`` method that will call each of these in sequence in order to scale an entire model by applying the following steps:\n", "\n", "1. apply variable scaling routine,\n", "2. apply first stage scaling fill-in,\n", @@ -1146,7 +599,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -1199,7 +652,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -1216,30 +669,9 @@ }, { "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'flow_mol_phase': ,\n", - " 'mole_frac_phase_comp': 10,\n", - " 'temperature': 0.0033333333333333335,\n", - " 'pressure': 1e-05,\n", - " 'enth_mol_phase': ,\n", - " 'visc_d_phase': ,\n", - " 'therm_cond_phase': ,\n", - " 'mole_frac_phase_comp_true': 10,\n", - " 'mole_frac_phase_comp_apparent': 10,\n", - " 'dens_mol_phase': ,\n", - " 'vol_mol_phase': }" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "liquid_properties_scaler.default_scaling_factors" ] @@ -1252,14 +684,14 @@ "\n", "With an inlet flow of about 80 mol/s, a scaling factor of 1/80 is appropriate. We can ignore ``visc_d_phase`` and ``therm_cond_phase``, because this unit model does not require dynamic viscosity or thermal conductivity. Molar enthalpy is a tougher quantity to scale.\n", "\n", - "By convention, the molar enthalpy of each element in its pure form at $25^\\circ\\text{C}$ and $1\\:\\text{atm}$ is set equal to zero. In some property packages, enthalpy of formation is taken into account for compounds, while in some property packages it is not. However, the scaling factor for enthalpy should not depend on this convention---only enthalpy *differences* are meaningful. So we need to determine how to determine what constitutes a \"significant\" enthalpy difference for this property package. The way the modular property scaler object estimates this is through the temperature scaling factor, which determines what a \"significant\" temperature difference is, and the observation that a wide range of substances have a specific heat capacity around $2\\:\\frac{\\text{J}}{\\text{g K}}$.\n", + "By convention, the molar enthalpy of each element in its pure form at $25^\\circ\\text{C}$ and $1\\:\\text{atm}$ is set equal to zero. In some property packages, enthalpy of formation is taken into account for compounds, while in some property packages it is not. However, the scaling factor for enthalpy should not depend on this convention\u2014only enthalpy *differences* are meaningful. So we need to determine how to determine what constitutes a \"significant\" enthalpy difference for this property package. The way the modular property scaler object estimates this is through the temperature scaling factor, which determines what a \"significant\" temperature difference is, and the observation that a wide range of substances have a specific heat capacity around $2\\:\\frac{\\text{J}}{\\text{g K}}$.\n", "\n", "This default method is good enough for our purposes now. We can revisit it later, if necessary." ] }, { "cell_type": "code", - "execution_count": 12, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -1279,45 +711,9 @@ }, { "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "====================================================================================\n", - "Model Statistics\n", - "\n", - " Jacobian Condition Number: 7.165E+10\n", - "\n", - "------------------------------------------------------------------------------------\n", - "1 WARNINGS\n", - "\n", - " WARNING: 1 Constraint with large residuals (>1.0E-05)\n", - "\n", - "------------------------------------------------------------------------------------\n", - "8 Cautions\n", - "\n", - " Caution: 9 Variables with value close to their bounds (abs=1.0E-04, rel=1.0E-04)\n", - " Caution: 14 Variables with value close to zero (tol=1.0E-08)\n", - " Caution: 27 Variables with extreme value (<1.0E-04 or >1.0E+04)\n", - " Caution: 2 Constraints with mismatched terms\n", - " Caution: 1 Constraint with potential cancellation of terms\n", - " Caution: 10 Variables with extreme Jacobian column norms (<1.0E-04 or >1.0E+04)\n", - " Caution: 4 Constraints with extreme Jacobian row norms (<1.0E-04 or >1.0E+04)\n", - " Caution: 33 extreme Jacobian Entries (<1.0E-04 or >1.0E+04)\n", - "\n", - "------------------------------------------------------------------------------------\n", - "Suggested next steps:\n", - "\n", - " display_constraints_with_large_residuals()\n", - " compute_infeasibility_explanation()\n", - "\n", - "====================================================================================\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "reboiler_scaler = SolventReboilerScaler()\n", "reboiler_scaler.scale_model(m.fs.unit)\n", @@ -1327,7 +723,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": null, "metadata": { "tags": [ "testing" @@ -1348,7 +744,7 @@ "$$\n", "\\max\\left(\\frac{||\\mathbf{r}_\\text{max}||_2}{||\\mathbf{r}_\\text{min}||_2}, \\frac{||\\mathbf{c}_\\text{max}||_2}{||\\mathbf{c}_\\text{min}||_2}\\right) \\leq \\kappa(\\mathbf{J}(\\mathbf{x}))\n", "$$\n", - "Consequently, Jacobian rows or columns with extremely large or extremely small norms indicate that the Jacobian is ill-conditioned. Each row is associated with a constraint and each column is associated with a variable. So the extreme Jacobian rows and columns give us a list of variables and constraints to investigate for scaling.\n", + "Consequently, Jacobian rows or columns with extremely large or extremely small norms indicate that the Jacobian is ill-conditioned. Each row is associated with a constraint and each column is associated with a variable. Thus, the extreme Jacobian rows and columns give us a list of variables and constraints to investigate for scaling.\n", "\n", "
\n", "Just because a variable or constraint has a Jacobian column or row with an extreme norm does not mean it is badly-scaled. Frequently, either a constraint containing the variable or a variable present in a constraint is the actual problem. \n", @@ -1367,40 +763,9 @@ }, { "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "====================================================================================\n", - "The following variable(s) correspond to Jacobian columns with extreme norms(<1.0E-04 or>1.0E+04):\n", - "\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,CO2]: 3.450E+07\n", - " fs.unit.liquid_phase.enthalpy_transfer[0.0]: 1.970E+06\n", - " fs.unit.liquid_phase.properties_out[0.0].temperature: 1.586E+06\n", - " fs.unit.vapor_phase[0.0].pressure: 1.353E+05\n", - " fs.unit.vapor_phase[0.0].temperature: 1.014E+05\n", - " fs.unit.liquid_phase.properties_out[0.0].pressure: 1.000E+05\n", - " fs.unit.vapor_phase[0.0].flow_mol_phase[Vap]: 3.256E+04\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,H2O]: 1.954E+04\n", - " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]: 1.873E+04\n", - " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]: 1.863E+04\n", - "\n", - "====================================================================================\n", - "====================================================================================\n", - "The following constraint(s) correspond to Jacobian rows with extreme norms (<1.0E-04 or>1.0E+04):\n", - "\n", - " fs.unit.unit_phase_equilibrium[0.0,CO2]: 3.450E+07\n", - " fs.unit.unit_enthalpy_balance[0.0]: 1.973E+06\n", - " fs.unit.unit_phase_equilibrium[0.0,H2O]: 1.589E+06\n", - " fs.unit.unit_pressure_balance[0.0]: 1.414E+05\n", - "\n", - "====================================================================================\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "dt.display_variables_with_extreme_jacobians()\n", "dt.display_constraints_with_extreme_jacobians()" @@ -1414,22 +779,14 @@ "\n", "## Step 5: Unit Model Level Scaling\n", "\n", - "We should take a look at the constraints before determining their scaling factors. However, Pyomo's `pprint` method often prints out multiple terminal pages' worth of thermodynamic expressions, which are extremely difficult to parse. The output is so verbose because it descends into named `Expressions` and recursively subsititutes them into the constraint expression. Since IDAES makes heavy use of named `Expressions` to decrease the number of `Constraints` in a model, the output becomes unmanangable for all but the most simple constraints. The `print_compact_form` utility function usually results in much more readable output." + "We should take a look at the constraints before determining their scaling factors. However, Pyomo's `pprint` method often prints out multiple terminal pages' worth of thermodynamic expressions, which are extremely difficult to parse. The output is so verbose because it descends into named `Expressions` and recursively subsititutes them into the constraint expression. Since IDAES makes heavy use of named `Expressions` to reduce the number of `Constraints` in a model, the output becomes unmanangable for all but the most simple constraints. The `print_compact_form` utility function usually results in much more readable output." ] }, { "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "- fs.unit.liquid_phase.enthalpy_transfer[0.0] == (kg*m**2/J/s**2)*fs.unit.vapor_phase[0.0]._enthalpy_flow_term[Vap]\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "from idaes.core.util.misc import print_compact_form\n", "\n", @@ -1448,20 +805,9 @@ }, { "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "5.076760620583219e-07" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "get_scaling_factor(m.fs.unit.liquid_phase.enthalpy_transfer[0.0])" ] @@ -1477,17 +823,9 @@ }, { "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "None\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "print(get_scaling_factor(m.fs.unit.vapor_phase[0.0]._enthalpy_flow_term[\"Vap\"]))" ] @@ -1501,17 +839,9 @@ }, { "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "fs.unit.vapor_phase[0.0].flow_mol_phase[Vap]*fs.unit.vapor_phase[0.0].enth_mol_phase[Vap]\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "print_compact_form(m.fs.unit.vapor_phase[0.0]._enthalpy_flow_term[\"Vap\"])" ] @@ -1525,20 +855,9 @@ }, { "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0.1" - ] - }, - "execution_count": 20, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "get_scaling_factor(m.fs.unit.vapor_phase[0.0].flow_mol_phase[\"Vap\"])" ] @@ -1552,20 +871,9 @@ }, { "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "5.46268982847154e-05" - ] - }, - "execution_count": 21, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "get_scaling_factor(m.fs.unit.vapor_phase[0.0].enth_mol_phase[\"Vap\"])" ] @@ -1579,20 +887,9 @@ }, { "cell_type": "code", - "execution_count": 22, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0.0125" - ] - }, - "execution_count": 22, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "get_scaling_factor(m.fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase[\"Liq\"])" ] @@ -1607,7 +904,7 @@ "$$\n", "Let $\\sigma(v)$ denote the scaling factor of the variable $v$. Then `get_sum_terms_nominal_values` substitutes the inverse of the variable scaling factor into each term in the sum and returns it as a list:\n", "$$\n", - "\\left[\\frac{1}{\\sigma(a)},\\; \\frac{1}{\\sigma(b) \\cdot \\sigma(c)}, \\frac{\\left(\\frac{1}{\\sigma(e)} - \\frac{1}{\\sigma(f)}\\right)}{\\sigma(d)} \\right]\n", + "\\left[\\frac{1}{\\sigma(a)},\\; \\frac{1}{\\sigma(b) \\cdot \\sigma(c)}, \\frac{-\\left(\\frac{1}{\\sigma(e)} - \\frac{1}{\\sigma(f)}\\right)}{\\sigma(d)} \\right]\n", "$$\n", "\n", "This process can produce reliable estimates of expression magnitude for certain operations:\n", @@ -1635,20 +932,9 @@ }, { "cell_type": "code", - "execution_count": 23, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[1969759.9999999995, 183060.0]" - ] - }, - "execution_count": 23, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "reboiler_scaler.get_sum_terms_nominal_values(m.fs.unit.unit_enthalpy_balance[0.0])" ] @@ -1657,7 +943,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "The inverse of either of these numbers would be reasonable scaling factors. The `scale_constraint_by_nominal value` function automatically scales a constraint by using one of these numbers. Which number we use is selected using the `ConstraintScalingScheme` `Enum` If we take the inverse of the larger number, we are saying that the constraint needs to be satisfied with the same precision as the largest term in the sum. This corresponds to `ConstraintScalingScheme.inverseMaximum`. If we take the inverse of the smaller number, we are saying that the constraint needs to be satisfied with the same precision as the smallest term in the sum. This corresponds to `ConstraintScalingScheme.inverseMinimum`.\n", + "The inverse of either of these numbers would be reasonable scaling factors. The `scale_constraint_by_nominal value` function automatically scales a constraint by using one of these numbers. Which number we use is selected using the `ConstraintScalingScheme` `Enum`. If we take the inverse of the larger number, we are saying that the constraint needs to be satisfied with the same precision as the largest term in the sum. This corresponds to `ConstraintScalingScheme.inverseMaximum`. If we take the inverse of the smaller number, we are saying that the constraint needs to be satisfied with the same precision as the smallest term in the sum. This corresponds to `ConstraintScalingScheme.inverseMinimum`.\n", "\n", "In general, the `inverseMinimum` scheme is the safest to use, because it demands the most precision. Let's use the `inverseMinimum` method for this constraint in order to more precisely determine the vapor phase's temperature.\n", "\n", @@ -1666,23 +952,11 @@ }, { "cell_type": "code", - "execution_count": 24, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[Liq,CO2] == fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,CO2]\n", - "\n", - "\n", - "fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[Liq,H2O] == fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,H2O]\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "print_compact_form(m.fs.unit.unit_phase_equilibrium[0.0, \"CO2\"])\n", - "print(\"\\n\")\n", "print_compact_form(m.fs.unit.unit_phase_equilibrium[0.0, \"H2O\"])" ] }, @@ -1695,7 +969,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": null, "metadata": { "tags": [ "testing" @@ -1720,18 +994,9 @@ }, { "cell_type": "code", - "execution_count": 26, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[7623092.433711249, 10000.0]\n", - "[355.3596511053128, 10000.0]\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "print(\n", " reboiler_scaler.get_sum_terms_nominal_values(\n", @@ -1749,22 +1014,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Here, we see that, while the vapor phase fugacities are associated with a nominal value of 10000, the liquid phase fugacities have wildly different nominal values. We do expect the vapor phase to be enriched in $\\text{CO}_2$, but not by a factor of $2\\cdot 10^4$. Let's unpack these values. We are using the ideal gas law for the vapor phase, so the fugacity is simply the product of the mole fraction and vapor pressure:" + "Here, we see that, while the vapor phase fugacities are associated with a nominal value of `10000`, the liquid phase fugacities have wildly different nominal values. We do expect the vapor phase to be enriched in $\\text{CO}_2$, but not by a factor of $2\\cdot 10^4$. Let's unpack these values. We are using the ideal gas law for the vapor phase, so the fugacity is simply the product of the mole fraction and vapor pressure:" ] }, { "cell_type": "code", - "execution_count": 27, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]*fs.unit.vapor_phase[0.0].pressure\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "print_compact_form(m.fs.unit.vapor_phase[0.0].fug_phase_comp[\"Vap\", \"CO2\"])" ] @@ -1778,17 +1035,9 @@ }, { "cell_type": "code", - "execution_count": 28, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,CO2]*(exp(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O])*log(244800.0*exp(-1348*K/fs.unit.liquid_phase.properties_out[0.0].temperature)*(3520000.0*exp(-2113*K/fs.unit.liquid_phase.properties_out[0.0].temperature)/(8449000.0*exp(-2283*K/fs.unit.liquid_phase.properties_out[0.0].temperature)))) + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O])*log(3520000.0*exp(-2113*K/fs.unit.liquid_phase.properties_out[0.0].temperature)) + fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O])*(fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]))*(fs.liquid_properties.CO2.lwm_coeff_1 + K**(-1)*fs.liquid_properties.CO2.lwm_coeff_2*(fs.unit.liquid_phase.properties_out[0.0].temperature - 273.15*K) + K**(-2)*fs.liquid_properties.CO2.lwm_coeff_3*(fs.unit.liquid_phase.properties_out[0.0].temperature - 273.15*K)**2 + fs.liquid_properties.CO2.lwm_coeff_4*(fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]))))*Pa*m**3*mol**(-1))\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "print_compact_form(\n", " m.fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[\"Liq\", \"CO2\"]\n", @@ -1799,25 +1048,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Parsing the entire pile of thermodynamic gibberish is unnecessary to plan our next move. We can plainly see that the liquid phase fugacity expression is rife with subtraction and exponentiation, both of which are dangerous for the nominal value expression walker. Even worse, we are scaling based on a failed solution, so the values may be off anyway. It is far better to base the scaling factor on the vapor phase fugacity. The `get_expression_nominal_value` function allows the user to get the nominal value of a single expression." + "Parsing the entire pile of thermodynamic gibberish is unnecessary to plan our next move. We can see that the liquid phase fugacity expression is rife with subtraction and exponentiation, both of which are dangerous for the nominal value expression walker. Even worse, we are scaling based on a failed solution, so the values may be off anyway. It is far better to base the scaling factor on the vapor phase fugacity. The `get_expression_nominal_value` function allows the user to get the nominal value of a single expression." ] }, { "cell_type": "code", - "execution_count": 29, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "10000.0" - ] - }, - "execution_count": 29, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "reboiler_scaler.get_expression_nominal_value(\n", " m.fs.unit.vapor_phase[0.0].fug_phase_comp[\"Vap\", \"CO2\"]\n", @@ -1835,17 +1073,9 @@ }, { "cell_type": "code", - "execution_count": 30, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "fs.unit.liquid_phase.properties_out[0.0].pressure == fs.unit.vapor_phase[0.0].pressure\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "print_compact_form(m.fs.unit.unit_pressure_balance[0.0])" ] @@ -1861,51 +1091,9 @@ }, { "cell_type": "code", - "execution_count": 31, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Scaling Factors for block fs.unit\n", - "\n", - "Variable Scaling Factor Value Scaled Value\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol 1.250E-02 8.389E+01 1.049E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[H2O] 1.000E+01 8.589E-01 8.589E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[MEA] 1.000E+01 1.085E-01 1.085E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[CO2] 1.000E+01 3.260E-02 3.260E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].temperature 3.333E-03 3.925E+02 1.308E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol 1.250E-02 7.424E+01 9.279E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O] 1.000E+01 8.527E-01 8.527E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] 1.000E+01 1.226E-01 1.226E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[CO2] 1.000E+01 2.471E-02 2.471E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].temperature 3.333E-03 3.926E+02 1.309E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", - "fs.unit.vapor_phase[0.0].flow_mol 1.000E-01 9.654E+00 9.654E-01\n", - "fs.unit.vapor_phase[0.0].mole_frac_comp[CO2] 1.000E+01 9.329E-02 9.329E-01\n", - "fs.unit.vapor_phase[0.0].mole_frac_comp[H2O] 1.000E+01 9.067E-01 9.067E+00\n", - "fs.unit.vapor_phase[0.0].mole_frac_comp[N2] 1.000E+01 1.055E-09 1.055E-08\n", - "fs.unit.vapor_phase[0.0].mole_frac_comp[O2] 1.000E+01 1.055E-09 1.055E-08\n", - "fs.unit.vapor_phase[0.0].temperature 3.333E-03 3.926E+02 1.309E+00\n", - "fs.unit.vapor_phase[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", - "fs.unit.liquid_phase.heat[0.0] 5.077E-07 4.306E+05 2.186E-01\n", - "\n", - "Constraint Scaling Factor\n", - "fs.unit.unit_material_balance[0.0,CO2] None\n", - "fs.unit.unit_material_balance[0.0,H2O] None\n", - "fs.unit.unit_material_balance[0.0,N2] None\n", - "fs.unit.unit_material_balance[0.0,O2] None\n", - "fs.unit.unit_material_balance[0.0,MEA] None\n", - "fs.unit.unit_phase_equilibrium[0.0,CO2] None\n", - "fs.unit.unit_phase_equilibrium[0.0,H2O] None\n", - "fs.unit.unit_temperature_equality[0.0] None\n", - "fs.unit.unit_enthalpy_balance[0.0] None\n", - "fs.unit.unit_pressure_balance[0.0] None\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "from idaes.core.scaling.util import report_scaling_factors\n", "\n", @@ -1921,17 +1109,9 @@ }, { "cell_type": "code", - "execution_count": 32, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "fs.unit.liquid_phase.properties_out[0.0].temperature == fs.unit.vapor_phase[0.0].temperature\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "print_compact_form(m.fs.unit.unit_temperature_equality[0.0])" ] @@ -1947,28 +1127,12 @@ }, { "cell_type": "code", - "execution_count": 33, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "- fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,CO2] == fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,CO2]\n", - "\n", - "\n", - "fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,MEA] == 0*(mol*s**(-1))\n", - "\n", - "\n", - "fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,N2] == fs.unit.zero_flow_param\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "print_compact_form(m.fs.unit.unit_material_balance[0.0, \"CO2\"])\n", - "print(\"\\n\")\n", "print_compact_form(m.fs.unit.unit_material_balance[0.0, \"MEA\"])\n", - "print(\"\\n\")\n", "print_compact_form(m.fs.unit.unit_material_balance[0.0, \"N2\"])" ] }, @@ -1992,7 +1156,7 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -2074,53 +1238,26 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Now we can see how this works on the model. We'll pass `overwrite=True` config option when creating the scaler object to ensure we have up-to-date scaling factors." + "Now we can see how this works on the model. We will create a new instance of the model to demonstrate that the improved scaling is sufficient to allow the model to initialize without a custom-tailored initial guess." ] }, { "cell_type": "code", - "execution_count": 35, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Starting initialization routine\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Bubble, dew, and critical point initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Equilibrium temperature initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: State variable initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Phase equilibrium initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Property initialization routine finished.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Starting initialization routine\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Bubble, dew, and critical point initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Equilibrium temperature initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: State variable initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Phase equilibrium initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Property initialization routine finished.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: Starting initialization routine\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: Bubble, dew, and critical point initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: Equilibrium temperature initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: State variable initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: Phase equilibrium initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: Property initialization routine finished.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit: Initialization Complete: optimal - \n" - ] - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 35, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ - "scaler_obj = SolventReboilerScaler(overwrite=True)\n", + "m = create_model()\n", + "\n", + "# Since this is a new instance of the model, we need to set the default\n", + "# scaler objects again.\n", + "m.fs.liquid_properties.default_state_scaler_object = liquid_properties_scaler\n", + "m.fs.vapor_properties.default_state_scaler_object = vapor_properties_scaler\n", + "\n", + "scaler_obj = SolventReboilerScaler()\n", "scaler_obj.scale_model(m.fs.unit)\n", + "\n", + "reboiler_init = m.fs.unit.default_initializer(always_estimate_states=True)\n", "reboiler_init.initialize(m.fs.unit)" ] }, @@ -2128,50 +1265,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "We see that scaling improved the model enough so that initialization could succeed. Now let's look at the numerical issues." + "We see that scaling improved the robustness of the model enough so that initialization could succeed. Now let's look at the numerical issues." ] }, { "cell_type": "code", - "execution_count": 36, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "====================================================================================\n", - "Model Statistics\n", - "\n", - " Jacobian Condition Number: 5.400E+06\n", - "\n", - "------------------------------------------------------------------------------------\n", - "0 WARNINGS\n", - "\n", - " No warnings found!\n", - "\n", - "------------------------------------------------------------------------------------\n", - "6 Cautions\n", - "\n", - " Caution: 9 Variables with value close to their bounds (abs=1.0E-04, rel=1.0E-04)\n", - " Caution: 14 Variables with value close to zero (tol=1.0E-08)\n", - " Caution: 27 Variables with extreme value (<1.0E-04 or >1.0E+04)\n", - " Caution: 2 Constraints with mismatched terms\n", - " Caution: 1 Constraint with potential cancellation of terms\n", - " Caution: 20 extreme Jacobian Entries (<1.0E-04 or >1.0E+04)\n", - "\n", - "------------------------------------------------------------------------------------\n", - "Suggested next steps:\n", - "\n", - " If you still have issues converging your model consider:\n", - "\n", - " prepare_degeneracy_hunter()\n", - " prepare_svd_toolbox()\n", - "\n", - "====================================================================================\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "dt = DiagnosticsToolbox(m)\n", "dt.report_numerical_issues()" @@ -2179,7 +1280,7 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": null, "metadata": { "tags": [ "testing" @@ -2227,7 +1328,7 @@ "\n", "Because $\\mathbf{U}$ and $\\mathbf{V}$ are orthogonal and $\\mathbf{\\Sigma}$ is diagonal, computing a Newton step is easy once the SVD is calculated.\n", "$$\n", - "\\mathbf{\\delta x}_k = -\\mathbf{V \\Sigma^{-1} U}^T \\cdot \\mathbf{f}(\\mathbf{x}_k)\n", + "\\mathbf{\\delta x}_k = -\\mathbf{V \\Sigma}^{-1} \\mathbf{U}^T \\cdot \\mathbf{f}(\\mathbf{x}_k)\n", "$$\n", "Since we have to refactorize $\\mathbf{J}$ at each iteration, the SVD is not an efficient method to calculate a Newton step. However, this process has a geometric interpretation that is useful for model diagnostics and scaling. First, the constraint residual is decomposed into orthogonal components by $\\mathbf{U}$:\n", "$$\n", @@ -2235,7 +1336,7 @@ "$$\n", "Next, these orthogonal components are scaled by the inverse of the associated singular value:\n", "$$\n", - "\\mathbf{\\tilde{s}} = \\Sigma^{-1} \\cdot \\mathbf{s}\n", + "\\mathbf{\\tilde{s}} = \\mathbf{\\Sigma}^{-1} \\cdot \\mathbf{s}\n", "$$\n", "Finally, these independent components are translated into the variable space by $\\mathbf{V}$:\n", "$$\n", @@ -2246,163 +1347,20 @@ "
\n", "NOTE\n", "\n", - "The singular vectors $\\mathbf{u}_j$ and $\\mathbf{v}_j$ are typically dense. In order to link them with specific variables and constraints, a thresholding scheme is applied. The `size_cutoff_in_singular_vector` config option for the `SVDToolbox` controls the magnitude of an entry in $\\mathbf{u}_j$ and $\\mathbf{v}_j$ that is sufficient to link a variable or constraint to the $\\sigma_j$. It is `0.1` by default, but can take on values between about `0.05` and `0.3`. Decrease it to show fewer variables and constraints, increase it to show more variables and constraints.\n", + "The singular vectors $\\mathbf{u}_j$ and $\\mathbf{v}_j$ are typically dense. In order to link them with specific variables and constraints, a thresholding scheme is applied. The `size_cutoff_in_singular_vector` config option for the `SVDToolbox` controls the magnitude of an entry in $\\mathbf{u}_j$ and $\\mathbf{v}_j$ that is sufficient to link a variable or constraint to the $\\sigma_j$. It is `0.1` by default, but typically has a value between `0.05` and `0.3`. Decrease it to show fewer variables and constraints, increase it to show more variables and constraints.\n", "\n", "
\n", "\n", - "So let's create an instance of the `SVDToolbox` and display the variables and constraints associated with the 5 smallest singular values.\n" + "So let's create an instance of the `SVDToolbox` and display the variables and constraints associated with the 5 smallest singular values. (For a full description of all the methods available, look at the [SVD toolbox documentation](https://idaes-pse.readthedocs.io/en/latest/reference_guides/core/util/diagnostics/svd_toolbox.html#svd-toolbox).)\n" ] }, { "cell_type": "code", - "execution_count": 38, + "execution_count": null, "metadata": { "scrolled": true }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "====================================================================================\n", - "Constraints and Variables associated with smallest singular values\n", - "\n", - " 1st Smallest Singular Value: 6.356e-04\n", - "\n", - " Variables:\n", - "\n", - " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_comp[CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_comp[H2O]\n", - "\n", - " Constraints:\n", - "\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2]\n", - "\n", - " 2nd Smallest Singular Value: 2.781e-02\n", - "\n", - " Variables:\n", - "\n", - " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_comp[CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_comp[H2O]\n", - "\n", - " Constraints:\n", - "\n", - " fs.unit.unit_material_balance[0.0,CO2]\n", - " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", - "\n", - " 3rd Smallest Singular Value: 3.679e-02\n", - "\n", - " Variables:\n", - "\n", - " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_comp[CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_comp[H2O]\n", - "\n", - " Constraints:\n", - "\n", - " fs.unit.unit_material_balance[0.0,CO2]\n", - " fs.unit.liquid_phase.material_balances[0.0,MEA]\n", - " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", - " fs.unit.liquid_phase.enthalpy_balances[0.0]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", - " fs.unit.unit_material_balance[0.0,MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,HCO3_-]\n", - " fs.unit.vapor_phase[0.0].sum_mole_frac_out\n", - "\n", - " 4th Smallest Singular Value: 6.842e-02\n", - "\n", - " Variables:\n", - "\n", - " fs.unit.vapor_phase[0.0].flow_mol_phase[Vap]\n", - " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,H2O]\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]\n", - " fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,H2O]\n", - " fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,H2O]\n", - " fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,H2O]\n", - " fs.unit.vapor_phase[0.0].mole_frac_comp[H2O]\n", - " fs.unit.vapor_phase[0.0].flow_mol\n", - "\n", - " Constraints:\n", - "\n", - " fs.unit.unit_material_balance[0.0,CO2]\n", - " fs.unit.liquid_phase.material_balances[0.0,MEA]\n", - " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", - " fs.unit.liquid_phase.enthalpy_balances[0.0]\n", - " fs.unit.unit_material_balance[0.0,MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].total_flow_balance\n", - " fs.unit.vapor_phase[0.0].sum_mole_frac_out\n", - "\n", - " 5th Smallest Singular Value: 7.703e-02\n", - "\n", - " Variables:\n", - "\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,H2O]\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]\n", - " fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,H2O]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_k_eq[bicarbonate]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_k_eq[carbamate]\n", - "\n", - " Constraints:\n", - "\n", - " fs.unit.liquid_phase.material_balances[0.0,MEA]\n", - " fs.unit.unit_material_balance[0.0,MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].total_flow_balance\n", - " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[MEA]\n", - " fs.unit.liquid_phase.properties_out[0.0].sum_mole_frac_out\n", - "\n", - "====================================================================================\n" - ] - } - ], + "outputs": [], "source": [ "st = dt.prepare_svd_toolbox()\n", "# The SVD toolbox displays 10 singular values by default, but we are going to\n", @@ -2412,7 +1370,7 @@ }, { "cell_type": "code", - "execution_count": 39, + "execution_count": null, "metadata": { "tags": [ "testing" @@ -2433,17 +1391,9 @@ }, { "cell_type": "code", - "execution_count": 40, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "exp(fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]) == fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,CO2]/(mol/m**3)\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "print_compact_form(\n", " m.fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[\n", @@ -2463,29 +1413,9 @@ }, { "cell_type": "code", - "execution_count": 41, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "====================================================================================\n", - "The following variables are involved in fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2]:\n", - "\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,H2O]: 4.333e-05\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,MEA]: 1.441e-04\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,CO2]: 6.126e-05\n", - " fs.unit.liquid_phase.properties_out[0.0].temperature: 1.576e-04\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]: -5.255e-07\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA]: 5.123e-06\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,CO2]: -1.648e+00\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]: 5.621e-04\n", - "\n", - "====================================================================================\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "st.display_variables_in_constraint(\n", " m.fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[\n", @@ -2501,7 +1431,7 @@ "
\n", "NOTE\n", "\n", - "At this point of the process, the original author found a shortcoming in the `ModularPropertiesScaler`. No scaling hint was set for the molar density expression, so the expression walker descended into it and came back with an inappropriate nominal value. Revising the scaler to estimate the phase density resulted in a condition number improvement of 1-2 orders of magnitude.\n", + "At this point of the process, the author of this notebook found a shortcoming in the `ModularPropertiesScaler`. No scaling hint was set for the molar density expression, so the expression walker descended into it and came back with an inappropriate nominal value. Revising the scaler to estimate the phase density resulted in a condition number improvement of 1-2 orders of magnitude.\n", "\n", "Remember:\n", "1. Scaling is an iterative process.\n", @@ -2516,24 +1446,15 @@ }, { "cell_type": "code", - "execution_count": 42, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Left hand side value: 1.3698e+00\n", - "CO2 true concentration value: 1.3698e+00\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "print(\n", - " f\"Left hand side value: {value(exp(m.fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[\"Liq\",\"CO2\"])):.4e}\"\n", + " f\"Left hand side value: {value(exp(m.fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true['Liq','CO2'])):.4e}\"\n", ")\n", "print(\n", - " f\"CO2 true concentration value: {value(m.fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[\"Liq\",\"CO2\"]):.4e}\"\n", + " f\"CO2 true concentration value: {value(m.fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true['Liq','CO2']):.4e}\"\n", ")" ] }, @@ -2546,7 +1467,7 @@ }, { "cell_type": "code", - "execution_count": 43, + "execution_count": null, "metadata": { "tags": [ "testing" @@ -2565,17 +1486,9 @@ }, { "cell_type": "code", - "execution_count": 44, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0.0004103666666666667\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "print(\n", " get_scaling_factor(\n", @@ -2599,24 +1512,15 @@ }, { "cell_type": "code", - "execution_count": 45, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True CO2 mole fraction: 3.410357e-05\n", - "True MEACOO- mole fraction: 2.796223e-02\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "print(\n", - " f\"True CO2 mole fraction: {m.fs.unit.liquid_phase.properties_out[0].mole_frac_phase_comp_true[\"Liq\",\"CO2\"].value:4e}\"\n", + " f\"True CO2 mole fraction: {m.fs.unit.liquid_phase.properties_out[0].mole_frac_phase_comp_true['Liq','CO2'].value:4e}\"\n", ")\n", "print(\n", - " f\"True MEACOO- mole fraction: {m.fs.unit.liquid_phase.properties_out[0].mole_frac_phase_comp_true[\"Liq\",\"MEACOO_-\"].value:4e}\"\n", + " f\"True MEACOO- mole fraction: {m.fs.unit.liquid_phase.properties_out[0].mole_frac_phase_comp_true['Liq','MEACOO_-'].value:4e}\"\n", ")" ] }, @@ -2629,7 +1533,7 @@ }, { "cell_type": "code", - "execution_count": 46, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -2659,66 +1563,11 @@ }, { "cell_type": "code", - "execution_count": 47, + "execution_count": null, "metadata": { "scrolled": true }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Starting initialization routine\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Bubble, dew, and critical point initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Equilibrium temperature initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: State variable initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Phase equilibrium initialization completed.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Property initialization routine finished.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Starting initialization routine\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Bubble, dew, and critical point initialization completed.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Equilibrium temperature initialization completed.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: State variable initialization completed.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Phase equilibrium initialization completed.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Property initialization routine finished.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: Starting initialization routine\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: Bubble, dew, and critical point initialization completed.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: Equilibrium temperature initialization completed.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: State variable initialization completed.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: Phase equilibrium initialization completed.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: Property initialization routine finished.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit: Initialization Complete: optimal - \n", - "====================================================================================\n", - "Model Statistics\n", - "\n", - " Jacobian Condition Number: 2.945E+05\n", - "\n", - "------------------------------------------------------------------------------------\n", - "0 WARNINGS\n", - "\n", - " No warnings found!\n", - "\n", - "------------------------------------------------------------------------------------\n", - "6 Cautions\n", - "\n", - " Caution: 9 Variables with value close to their bounds (abs=1.0E-04, rel=1.0E-04)\n", - " Caution: 14 Variables with value close to zero (tol=1.0E-08)\n", - " Caution: 27 Variables with extreme value (<1.0E-04 or >1.0E+04)\n", - " Caution: 2 Constraints with mismatched terms\n", - " Caution: 1 Constraint with potential cancellation of terms\n", - " Caution: 16 extreme Jacobian Entries (<1.0E-04 or >1.0E+04)\n", - "\n", - "------------------------------------------------------------------------------------\n", - "Suggested next steps:\n", - "\n", - " If you still have issues converging your model consider:\n", - "\n", - " prepare_degeneracy_hunter()\n", - " prepare_svd_toolbox()\n", - "\n", - "====================================================================================\n" - ] - } - ], + "outputs": [], "source": [ "scaler_obj = SolventReboilerScaler(overwrite=True)\n", "scaler_obj.scale_model(m.fs.unit)\n", @@ -2729,7 +1578,7 @@ }, { "cell_type": "code", - "execution_count": 48, + "execution_count": null, "metadata": { "tags": [ "testing" @@ -2749,157 +1598,11 @@ }, { "cell_type": "code", - "execution_count": 49, + "execution_count": null, "metadata": { "scrolled": true }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "====================================================================================\n", - "Constraints and Variables associated with smallest singular values\n", - "\n", - " 1st Smallest Singular Value: 6.965e-04\n", - "\n", - " Variables:\n", - "\n", - " fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[bicarbonate]\n", - " fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[carbamate]\n", - " fs.unit.liquid_phase.properties_out[0.0].apparent_inherent_reaction_extent[carbamate]\n", - "\n", - " Constraints:\n", - "\n", - " fs.unit.unit_material_balance[0.0,CO2]\n", - " fs.unit.unit_material_balance[0.0,H2O]\n", - " fs.unit.liquid_phase.material_balances[0.0,H2O]\n", - " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].total_flow_balance\n", - " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", - "\n", - " 2nd Smallest Singular Value: 1.047e-03\n", - "\n", - " Variables:\n", - "\n", - " fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[carbamate]\n", - " fs.unit.liquid_phase.properties_out[0.0].apparent_inherent_reaction_extent[carbamate]\n", - "\n", - " Constraints:\n", - "\n", - " fs.unit.unit_material_balance[0.0,CO2]\n", - " fs.unit.unit_material_balance[0.0,H2O]\n", - " fs.unit.liquid_phase.material_balances[0.0,H2O]\n", - " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEA_+]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA_+]\n", - "\n", - " 3rd Smallest Singular Value: 4.024e-03\n", - "\n", - " Variables:\n", - "\n", - " fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[bicarbonate]\n", - " fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[carbamate]\n", - "\n", - " Constraints:\n", - "\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,H2O]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,H2O]\n", - " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,H2O]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", - "\n", - " 4th Smallest Singular Value: 5.218e-03\n", - "\n", - " Variables:\n", - "\n", - " fs.unit.liquid_phase.properties_out[0.0].apparent_inherent_reaction_extent[bicarbonate]\n", - "\n", - " Constraints:\n", - "\n", - " fs.unit.unit_material_balance[0.0,CO2]\n", - " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,HCO3_-]\n", - "\n", - " 5th Smallest Singular Value: 5.115e-02\n", - "\n", - " Variables:\n", - "\n", - " fs.unit.vapor_phase[0.0].flow_mol_phase[Vap]\n", - " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_comp[CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_comp[H2O]\n", - " fs.unit.vapor_phase[0.0].flow_mol\n", - "\n", - " Constraints:\n", - "\n", - " fs.unit.unit_material_balance[0.0,CO2]\n", - " fs.unit.unit_material_balance[0.0,H2O]\n", - " fs.unit.liquid_phase.material_balances[0.0,H2O]\n", - " fs.unit.liquid_phase.material_balances[0.0,MEA]\n", - " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEA_+]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEA]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA_+]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA]\n", - " fs.unit.unit_material_balance[0.0,MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].total_flow_balance\n", - " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA_+]\n", - " fs.unit.liquid_phase.properties_out[0.0].sum_mole_frac_out\n", - " fs.unit.vapor_phase[0.0].sum_mole_frac_out\n", - "\n", - "====================================================================================\n" - ] - } - ], + "outputs": [], "source": [ "st = dt.prepare_svd_toolbox()\n", "st.display_underdetermined_variables_and_constraints([1, 2, 3, 4, 5])" @@ -2907,8 +1610,12 @@ }, { "cell_type": "code", - "execution_count": 50, - "metadata": {}, + "execution_count": null, + "metadata": { + "tags": [ + "testing" + ] + }, "outputs": [], "source": [ "assert st.s[0] == pytest.approx(6.965e-04, rel=1e-2)\n", @@ -2929,243 +1636,11 @@ }, { "cell_type": "code", - "execution_count": 51, + "execution_count": null, "metadata": { "scrolled": true }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Scaling Factors for block fs.unit\n", - "\n", - "Variable Scaling Factor Value Scaled Value\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol 1.250E-02 8.389E+01 1.049E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[H2O] 1.000E+00 8.589E-01 8.589E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[MEA] 1.000E+01 1.085E-01 1.085E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[CO2] 1.000E+01 3.260E-02 3.260E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].temperature 3.333E-03 3.925E+02 1.308E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol 1.250E-02 7.410E+01 9.263E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O] 1.000E+00 8.487E-01 8.487E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] 1.000E+01 1.228E-01 1.228E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[CO2] 1.000E+01 2.851E-02 2.851E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].temperature 3.333E-03 3.938E+02 1.313E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", - "fs.unit.vapor_phase[0.0].flow_mol 1.000E-01 9.785E+00 9.785E-01\n", - "fs.unit.vapor_phase[0.0].mole_frac_comp[CO2] 1.000E+01 6.361E-02 6.361E-01\n", - "fs.unit.vapor_phase[0.0].mole_frac_comp[H2O] 1.000E+01 9.364E-01 9.364E+00\n", - "fs.unit.vapor_phase[0.0].mole_frac_comp[N2] 1.000E+01 1.022E-09 1.022E-08\n", - "fs.unit.vapor_phase[0.0].mole_frac_comp[O2] 1.000E+01 1.022E-09 1.022E-08\n", - "fs.unit.vapor_phase[0.0].temperature 3.333E-03 3.938E+02 1.313E+00\n", - "fs.unit.vapor_phase[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", - "fs.unit.liquid_phase.heat[0.0] 8.763E-07 4.306E+05 3.773E-01\n", - "fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,H2O] 1.250E-02 -9.163E+00 -1.145E-01\n", - "fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,MEA] 1.250E-01 0.000E+00 0.000E+00\n", - "fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,CO2] 1.250E-01 -6.224E-01 -7.780E-02\n", - "fs.unit.liquid_phase.enthalpy_transfer[0.0] 8.763E-07 -3.209E+04 -2.812E-02\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase[Liq] 1.250E-02 8.389E+01 1.049E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp[Liq,H2O] 1.000E+00 8.589E-01 8.589E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp[Liq,MEA] 1.000E+01 1.085E-01 1.085E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp[Liq,CO2] 1.000E+01 3.260E-02 3.260E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].phase_frac[Liq] 1.000E+00 1.000E+00 1.000E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,MEACOO_-] 1.250E-01 2.550E+00 3.187E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,HCO3_-] 1.250E+00 1.785E-01 2.231E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,MEA_+] 1.250E-01 2.728E+00 3.410E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,H2O] 1.250E-02 7.187E+01 8.984E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,MEA] 1.250E-01 3.825E+00 4.781E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,CO2] 1.250E+02 6.803E-03 8.504E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,MEACOO_-] 1.000E+01 3.141E-02 3.141E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,HCO3_-] 1.000E+02 2.199E-03 2.199E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,MEA_+] 1.000E+01 3.361E-02 3.361E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,H2O] 1.000E+00 8.856E-01 8.856E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,MEA] 1.000E+01 4.712E-02 4.712E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,CO2] 1.000E+04 8.383E-05 8.383E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[bicarbonate] 1.250E+02 1.785E-01 2.231E+01\n", - "fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[carbamate] 1.250E+02 2.550E+00 3.187E+02\n", - "fs.unit.liquid_phase.properties_in[0.0].log_k_eq[bicarbonate] None -7.578E+00 -7.578E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].log_k_eq[carbamate] None -1.985E+00 -1.985E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-] 1.000E+00 7.168E+00 7.168E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-] 1.000E+00 4.509E+00 4.509E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+] 1.000E+00 7.236E+00 7.236E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,H2O] 1.000E+00 1.051E+01 1.051E+01\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEA] 1.000E+00 7.573E+00 7.573E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,CO2] 1.000E+00 1.242E+00 1.242E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase[Liq] 1.250E-02 7.410E+01 9.263E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,H2O] 1.000E+00 8.487E-01 8.487E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,MEA] 1.000E+01 1.228E-01 1.228E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,CO2] 1.000E+01 2.851E-02 2.851E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].phase_frac[Liq] 1.000E+00 1.000E+00 1.000E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,MEACOO_-] 1.250E-01 2.013E+00 2.516E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,HCO3_-] 1.250E+00 9.684E-02 1.210E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,MEA_+] 1.250E-01 2.110E+00 2.637E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,H2O] 1.250E-02 6.279E+01 7.849E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,MEA] 1.250E-01 4.979E+00 6.224E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,CO2] 1.250E+02 2.455E-03 3.069E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,MEACOO_-] 1.000E+01 2.796E-02 2.796E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,HCO3_-] 1.000E+02 1.345E-03 1.345E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,MEA_+] 1.000E+01 2.931E-02 2.931E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,H2O] 1.000E+00 8.722E-01 8.722E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,MEA] 1.000E+01 6.916E-02 6.916E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,CO2] 1.000E+04 3.410E-05 3.410E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].apparent_inherent_reaction_extent[bicarbonate] 1.250E+02 9.684E-02 1.210E+01\n", - "fs.unit.liquid_phase.properties_out[0.0].apparent_inherent_reaction_extent[carbamate] 1.250E+02 2.013E+00 2.516E+02\n", - "fs.unit.liquid_phase.properties_out[0.0].log_k_eq[bicarbonate] None -7.648E+00 -7.648E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].log_k_eq[carbamate] None -2.079E+00 -2.079E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-] 1.000E+00 7.024E+00 7.024E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-] 1.000E+00 3.989E+00 3.989E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+] 1.000E+00 7.071E+00 7.071E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,H2O] 1.000E+00 1.046E+01 1.046E+01\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA] 1.000E+00 7.929E+00 7.929E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2] 1.000E+00 3.147E-01 3.147E-01\n", - "fs.unit.vapor_phase[0.0].flow_mol_phase[Vap] 1.000E-01 9.785E+00 9.785E-01\n", - "fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2] 1.000E+01 6.361E-02 6.361E-01\n", - "fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O] 1.000E+01 9.364E-01 9.364E+00\n", - "fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,N2] 1.000E+01 1.022E-09 1.022E-08\n", - "fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,O2] 1.000E+01 1.022E-09 1.022E-08\n", - "fs.unit.vapor_phase[0.0].phase_frac[Vap] 1.000E+00 1.000E+00 1.000E+00\n", - "\n", - "Constraint Scaling Factor\n", - "fs.unit.unit_material_balance[0.0,CO2] 1.250E-01\n", - "fs.unit.unit_material_balance[0.0,H2O] 1.250E-02\n", - "fs.unit.unit_material_balance[0.0,N2] 1.000E+00\n", - "fs.unit.unit_material_balance[0.0,O2] 1.000E+00\n", - "fs.unit.unit_material_balance[0.0,MEA] 1.250E-01\n", - "fs.unit.unit_phase_equilibrium[0.0,CO2] 1.000E-04\n", - "fs.unit.unit_phase_equilibrium[0.0,H2O] 1.000E-04\n", - "fs.unit.unit_temperature_equality[0.0] 3.333E-03\n", - "fs.unit.unit_enthalpy_balance[0.0] 5.463E-06\n", - "fs.unit.unit_pressure_balance[0.0] 1.000E-05\n", - "fs.unit.liquid_phase.material_balances[0.0,H2O] 1.250E-02\n", - "fs.unit.liquid_phase.material_balances[0.0,MEA] 1.250E-01\n", - "fs.unit.liquid_phase.material_balances[0.0,CO2] 1.250E-01\n", - "fs.unit.liquid_phase.enthalpy_balances[0.0] 8.763E-07\n", - "fs.unit.liquid_phase.pressure_balance[0.0] 1.000E-05\n", - "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEACOO_-] 1.250E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,HCO3_-] 1.250E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEA_+] 1.250E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,H2O] 1.250E-02\n", - "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEA] 1.250E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2] 1.250E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEACOO_-] 1.250E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,HCO3_-] 1.250E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEA_+] 1.250E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,H2O] 1.250E-02\n", - "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEA] 1.250E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,CO2] 1.250E+02\n", - "fs.unit.liquid_phase.properties_in[0.0].total_flow_balance 1.250E-02\n", - "fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[H2O] 1.000E+01\n", - "fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[MEA] 1.000E+01\n", - "fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2] 1.000E+01\n", - "fs.unit.liquid_phase.properties_in[0.0].phase_fraction_constraint[Liq] 1.000E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].log_k_eq_constraint[bicarbonate] None\n", - "fs.unit.liquid_phase.properties_in[0.0].log_k_eq_constraint[carbamate] None\n", - "fs.unit.liquid_phase.properties_in[0.0].inherent_equilibrium_constraint[bicarbonate] 1.000E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].inherent_equilibrium_constraint[carbamate] 1.000E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-] 2.377E-04\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-] 2.377E-03\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA_+] 2.377E-04\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,H2O] 2.377E-05\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA] 2.377E-04\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2] 2.377E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEACOO_-] 1.250E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,HCO3_-] 1.250E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA_+] 1.250E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,H2O] 1.250E-02\n", - "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA] 1.250E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2] 1.250E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEACOO_-] 1.250E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,HCO3_-] 1.250E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEA_+] 1.250E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,H2O] 1.250E-02\n", - "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEA] 1.250E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,CO2] 1.250E+02\n", - "fs.unit.liquid_phase.properties_out[0.0].sum_mole_frac_out 1.000E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].total_flow_balance 1.250E-02\n", - "fs.unit.liquid_phase.properties_out[0.0].component_flow_balances[H2O] 1.000E+01\n", - "fs.unit.liquid_phase.properties_out[0.0].component_flow_balances[MEA] 1.000E+01\n", - "fs.unit.liquid_phase.properties_out[0.0].component_flow_balances[CO2] 1.000E+01\n", - "fs.unit.liquid_phase.properties_out[0.0].phase_fraction_constraint[Liq] 1.000E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].log_k_eq_constraint[bicarbonate] None\n", - "fs.unit.liquid_phase.properties_out[0.0].log_k_eq_constraint[carbamate] None\n", - "fs.unit.liquid_phase.properties_out[0.0].inherent_equilibrium_constraint[bicarbonate] 1.000E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].inherent_equilibrium_constraint[carbamate] 1.000E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-] 2.377E-04\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-] 2.377E-03\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA_+] 2.377E-04\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,H2O] 2.377E-05\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA] 2.377E-04\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2] 2.377E-01\n", - "fs.unit.vapor_phase[0.0].sum_mole_frac_out 1.000E+00\n", - "fs.unit.vapor_phase[0.0].total_flow_balance 1.000E-01\n", - "fs.unit.vapor_phase[0.0].component_flow_balances[CO2] 1.000E+01\n", - "fs.unit.vapor_phase[0.0].component_flow_balances[H2O] 1.000E+01\n", - "fs.unit.vapor_phase[0.0].component_flow_balances[N2] 1.000E+01\n", - "fs.unit.vapor_phase[0.0].component_flow_balances[O2] 1.000E+01\n", - "fs.unit.vapor_phase[0.0].phase_fraction_constraint[Vap] 1.000E+00\n", - "\n", - "Expression Scaling Hint\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp[Liq,H2O] 1.250E-02\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp[Liq,MEA] 1.250E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp[Liq,CO2] 1.250E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].k_eq[bicarbonate] None\n", - "fs.unit.liquid_phase.properties_in[0.0].k_eq[carbamate] None\n", - "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,MEACOO_-] None\n", - "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,HCO3_-] None\n", - "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,MEA_+] None\n", - "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,H2O] None\n", - "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,MEA] None\n", - "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,CO2] None\n", - "fs.unit.liquid_phase.properties_in[0.0].dens_mol_phase[Liq] 2.377E-05\n", - "fs.unit.liquid_phase.properties_in[0.0].vol_mol_phase[Liq] 4.206E+04\n", - "fs.unit.liquid_phase.properties_in[0.0]._enthalpy_flow_term[Liq] None\n", - "fs.unit.liquid_phase.properties_in[0.0].enth_mol_phase[Liq] 7.010E-05\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_comp[H2O] 1.250E-02\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_comp[MEA] 1.250E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_comp[CO2] 1.250E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp[Liq,H2O] 1.250E-02\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp[Liq,MEA] 1.250E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp[Liq,CO2] 1.250E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].k_eq[bicarbonate] None\n", - "fs.unit.liquid_phase.properties_out[0.0].k_eq[carbamate] None\n", - "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,MEACOO_-] None\n", - "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,HCO3_-] None\n", - "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,MEA_+] None\n", - "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,H2O] None\n", - "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,MEA] None\n", - "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,CO2] None\n", - "fs.unit.liquid_phase.properties_out[0.0].dens_mol_phase[Liq] 2.377E-05\n", - "fs.unit.liquid_phase.properties_out[0.0].vol_mol_phase[Liq] 4.206E+04\n", - "fs.unit.liquid_phase.properties_out[0.0]._enthalpy_flow_term[Liq] None\n", - "fs.unit.liquid_phase.properties_out[0.0].enth_mol_phase[Liq] 7.010E-05\n", - "fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[Liq,H2O] None\n", - "fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[Liq,MEA] None\n", - "fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[Liq,CO2] None\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_comp[H2O] 1.250E-02\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_comp[MEA] 1.250E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_comp[CO2] 1.250E-01\n", - "fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,CO2] 1.000E+00\n", - "fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,H2O] 1.000E+00\n", - "fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,N2] 1.000E+00\n", - "fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,O2] 1.000E+00\n", - "fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,CO2] None\n", - "fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,H2O] None\n", - "fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,N2] None\n", - "fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,O2] None\n", - "fs.unit.vapor_phase[0.0]._enthalpy_flow_term[Vap] None\n", - "fs.unit.vapor_phase[0.0].enth_mol_phase[Vap] 5.463E-05\n", - "fs.unit.vapor_phase[0.0].enth_mol_phase_comp[Vap,CO2] 3.787E-05\n", - "fs.unit.vapor_phase[0.0].enth_mol_phase_comp[Vap,H2O] 9.249E-05\n", - "fs.unit.vapor_phase[0.0].enth_mol_phase_comp[Vap,N2] 5.950E-05\n", - "fs.unit.vapor_phase[0.0].enth_mol_phase_comp[Vap,O2] 5.208E-05\n", - "fs.unit.vapor_phase[0.0].flow_mol_comp[CO2] 1.000E+00\n", - "fs.unit.vapor_phase[0.0].flow_mol_comp[H2O] 1.000E+00\n", - "fs.unit.vapor_phase[0.0].flow_mol_comp[N2] 1.000E+00\n", - "fs.unit.vapor_phase[0.0].flow_mol_comp[O2] 1.000E+00\n" - ] - } - ], + "outputs": [], "source": [ "from idaes.core.scaling.util import report_scaling_factors\n", "\n", @@ -3176,7 +1651,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Most variable values have scaled values within a couple orders of magnitude of one, which is what we like. The outliers are inherent reaction extents, which we already know are a bit problematic, and variables corresponding to the components $\\text{N}_2$ and $\\text{O}_2$, which are present in the vapor property package but not the vapor stream.\n", + "Most variable values have scaled values within a couple orders of magnitude of one, which is what we like. The outliers are inherent reaction extents, which we already know are a bit problematic, and variables corresponding to the components $\\text{N}_2$ and $\\text{O}_2$. Because those components are present in the vapor property package but not the vapor stream, they should not be scaled to order one, and their current scaling factors are fine.\n", "\n", "We have reduced the condition number to $3 \\cdot 10^5$, which is not quite as low as we would have liked, but is a vast improvement over the value $3 \\cdot 10^{13}$, which we started out with. " ] @@ -3216,7 +1691,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.12" + "version": "3.10.20" } }, "nbformat": 4, diff --git a/idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques_usr.ipynb b/idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques_usr.ipynb index f7000025..33241b2b 100644 --- a/idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques_usr.ipynb +++ b/idaes_examples/notebooks/docs/scaling/advanced_scaling_techniques_usr.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -32,532 +32,28 @@ "\n", "## Introduction\n", "\n", - "This notebook is intended to give the user further insight into how the scaling toolbox can be used to improve robustness. A large portion of the material is an adaptation of [Allan, Ostace, and Polly (2025)](#references). By the end of this study, the user should understand:\n", + "This notebook is intended to give the user further insight into how the scaling toolbox can be used to improve robustness. It is a followup to a [previous notebook](./scaler_workshop_usr.ipynb) about how to create scaler objects in IDAES, and it assumes some familiarity with the material contained therein. A large portion of the material is an adaptation of [Allan, Ostace, and Polly (2025)](#references). By the end of this study, the user should understand:\n", "* How a default scaler object can be specified for a property package\n", "* How to set default scaling factors for property package variables\n", + "* How to use the `DiagnosticsToolbox` to troubleshoot saling issues\n", "* The strengths and weaknesses of the ``NominalValueExpressionWalker`` used in ``CustomScalerBase.get_sum_terms_nominal_values`` and ``CustomScalerBase.get_expression_nominal_value`` for use in constraint scaling\n", "* How to use the ``SVDToolbox`` to troubleshoot scaling issues\n", "\n", "## Step 1: Set Up Test Case\n", - "We will use the `SolventReboiler` unit model as a case study. It is a component in a stripping column used for solvent regeneration. It is modeled as a single equilibrium stage with an external heat duty. The inlet stream is entirely liquid, while it has both boilup and bottoms outlet streams. The liquid and vapor phases use different configurations of the modular property framework.\n", + "We will use the `SolventReboiler` unit model as a case study. It is a component in a stripping column used for solvent regeneration. It is modeled as a single equilibrium stage with an external heat duty. The inlet stream is entirely liquid, while it has both boilup and bottoms outlet streams. The liquid and vapor phases use different configurations of the [modular property framework](https://idaes-pse.readthedocs.io/en/latest/explanations/components/property_package/general/index.html).\n", "\n", "First, we set up and attempt to initialize the unit model." ] }, { "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2026-04-29 17:11:54 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Starting initialization routine\n", - "2026-04-29 17:11:54 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Bubble, dew, and critical point initialization completed.\n", - "2026-04-29 17:11:54 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Equilibrium temperature initialization completed.\n", - "2026-04-29 17:11:54 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: State variable initialization completed.\n", - "2026-04-29 17:11:54 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Phase equilibrium initialization completed.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Ipopt 3.13.2: linear_solver=\"ma57\"\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: max_iter=200\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: nlp_scaling_method=\"gradient-based\"\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: tol=1e-06\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: ******************************************************************************\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: For more information visit http://projects.coin-or.org/Ipopt\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: This version of Ipopt was compiled from source code available at\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: for large-scale scientific computation. All technical papers, sales and\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: publicity material resulting from use of the HSL codes within IPOPT must\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: contain the following acknowledgement:\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: HSL, a collection of Fortran codes for large-scale scientific\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: computation. See http://www.hsl.rl.ac.uk.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: ******************************************************************************\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of nonzeros in equality constraint Jacobian...: 74\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of nonzeros in inequality constraint Jacobian.: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of nonzeros in Lagrangian Hessian.............: 42\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Total number of variables............................: 18\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: variables with only lower bounds: 6\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: variables with lower and upper bounds: 12\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: variables with only upper bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Total number of equality constraints.................: 18\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Total number of inequality constraints...............: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: inequality constraints with only lower bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: inequality constraints with lower and upper bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: inequality constraints with only upper bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 0 0.0000000e+00 4.13e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Reallocating memory for MA57: lfact (1377)\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 1 0.0000000e+00 4.05e+02 1.89e+12 -1.0 6.07e+01 - 1.92e-01 1.98e-02H 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 2 0.0000000e+00 1.62e+04 1.56e+17 -1.0 8.76e+01 - 1.69e-01 5.07e-01H 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 3 0.0000000e+00 1.62e+04 1.55e+17 -1.0 4.59e+01 - 1.21e-07 3.23e-03H 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 4 0.0000000e+00 2.15e+04 1.93e+17 -1.0 4.88e+01 - 1.06e-02 9.12e-01h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Reallocating memory for MA57: lfact (1542)\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 5 0.0000000e+00 2.15e+04 1.93e+17 -1.0 3.05e+02 - 4.08e-04 6.58e-04h 2\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Reallocating memory for MA57: lfact (1662)\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 6 0.0000000e+00 2.09e+04 1.87e+17 -1.0 1.11e+01 - 4.04e-03 3.08e-02h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 7 0.0000000e+00 1.50e+04 1.37e+17 -1.0 1.37e+01 - 1.44e-04 3.14e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 8 0.0000000e+00 1.49e+04 1.36e+17 -1.0 4.21e+00 - 5.37e-01 9.11e-03h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 9 0.0000000e+00 1.49e+04 1.36e+17 -1.0 4.10e+00 - 9.86e-01 9.35e-05h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 10r 0.0000000e+00 1.49e+04 1.00e+03 1.6 0.00e+00 - 0.00e+00 4.68e-07R 2\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 11r 0.0000000e+00 5.25e+03 2.22e+03 1.6 3.13e+04 - 3.88e-03 1.14e-03f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 12r 0.0000000e+00 5.08e+03 4.24e+04 1.6 1.22e+03 - 1.88e-01 5.18e-03f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 13r 0.0000000e+00 4.77e+03 3.36e+04 1.6 6.27e+01 - 3.06e-02 6.76e-02f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 14r 0.0000000e+00 4.33e+03 1.32e+05 1.6 8.06e+00 - 5.05e-01 9.81e-02f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 15r 0.0000000e+00 4.19e+03 1.12e+05 1.6 9.20e+00 - 3.38e-01 3.25e-02f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 16r 0.0000000e+00 1.89e+03 5.50e+04 1.6 2.54e+00 - 8.42e-02 7.08e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 17r 0.0000000e+00 1.72e+03 4.73e+04 1.6 7.82e+00 - 2.36e-01 1.01e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 18r 0.0000000e+00 1.14e+03 2.84e+04 1.6 1.92e+00 - 7.10e-01 4.02e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 19r 0.0000000e+00 1.06e+03 2.92e+04 1.6 5.12e+00 - 7.85e-01 7.79e-02f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 20r 0.0000000e+00 2.69e+02 3.66e+03 1.6 5.52e-01 - 1.00e+00 9.33e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 21r 0.0000000e+00 1.64e+01 3.96e+02 0.9 1.63e-01 - 9.76e-01 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 22r 0.0000000e+00 6.87e-01 1.09e+02 0.2 3.52e-02 - 1.00e+00 9.59e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 23r 0.0000000e+00 2.05e-01 8.47e+03 -0.5 2.72e-03 - 1.00e+00 6.98e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 24r 0.0000000e+00 1.34e-03 2.18e-01 -0.5 1.87e-03 - 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 25r 0.0000000e+00 1.29e-02 1.88e+02 -2.9 3.36e-04 - 1.00e+00 9.47e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: 26r 0.0000000e+00 2.90e-06 4.04e-05 -2.9 7.48e-05 - 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of Iterations....: 26\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: (scaled) (unscaled)\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Constraint violation....: 2.1131334015933589e-08 2.8957967970200116e-06\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Overall NLP error.......: 2.1131334015933589e-08 2.8957967970200116e-06\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of objective function evaluations = 34\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of objective gradient evaluations = 12\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of equality constraint evaluations = 36\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of inequality constraint evaluations = 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of equality constraint Jacobian evaluations = 28\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of inequality constraint Jacobian evaluations = 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Number of Lagrangian Hessian evaluations = 26\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Total CPU secs in IPOPT (w/o function evaluations) = 0.006\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: Total CPU secs in NLP function evaluations = 0.000\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_in: EXIT: Optimal Solution Found.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Property initialization routine finished.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Starting initialization routine\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Bubble, dew, and critical point initialization completed.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Equilibrium temperature initialization completed.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: State variable initialization completed.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Phase equilibrium initialization completed.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Ipopt 3.13.2: linear_solver=\"ma57\"\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: max_iter=200\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: nlp_scaling_method=\"gradient-based\"\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: tol=1e-06\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: ******************************************************************************\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: For more information visit http://projects.coin-or.org/Ipopt\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: This version of Ipopt was compiled from source code available at\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: for large-scale scientific computation. All technical papers, sales and\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: publicity material resulting from use of the HSL codes within IPOPT must\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: contain the following acknowledgement:\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: HSL, a collection of Fortran codes for large-scale scientific\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: computation. See http://www.hsl.rl.ac.uk.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: ******************************************************************************\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of nonzeros in equality constraint Jacobian...: 74\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of nonzeros in inequality constraint Jacobian.: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of nonzeros in Lagrangian Hessian.............: 42\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Total number of variables............................: 18\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: variables with only lower bounds: 6\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: variables with lower and upper bounds: 12\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: variables with only upper bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Total number of equality constraints.................: 18\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Total number of inequality constraints...............: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: inequality constraints with only lower bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: inequality constraints with lower and upper bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: inequality constraints with only upper bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 0 0.0000000e+00 4.13e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Reallocating memory for MA57: lfact (1377)\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 1 0.0000000e+00 4.05e+02 1.89e+12 -1.0 6.07e+01 - 1.92e-01 1.98e-02H 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 2 0.0000000e+00 1.62e+04 1.56e+17 -1.0 8.76e+01 - 1.69e-01 5.07e-01H 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 3 0.0000000e+00 1.62e+04 1.55e+17 -1.0 4.59e+01 - 1.21e-07 3.23e-03H 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 4 0.0000000e+00 2.15e+04 1.93e+17 -1.0 4.88e+01 - 1.06e-02 9.12e-01h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Reallocating memory for MA57: lfact (1542)\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 5 0.0000000e+00 2.15e+04 1.93e+17 -1.0 3.05e+02 - 4.08e-04 6.58e-04h 2\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Reallocating memory for MA57: lfact (1662)\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 6 0.0000000e+00 2.09e+04 1.87e+17 -1.0 1.11e+01 - 4.04e-03 3.08e-02h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 7 0.0000000e+00 1.50e+04 1.37e+17 -1.0 1.37e+01 - 1.44e-04 3.14e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 8 0.0000000e+00 1.49e+04 1.36e+17 -1.0 4.21e+00 - 5.37e-01 9.11e-03h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 9 0.0000000e+00 1.49e+04 1.36e+17 -1.0 4.10e+00 - 9.86e-01 9.35e-05h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 10r 0.0000000e+00 1.49e+04 1.00e+03 1.6 0.00e+00 - 0.00e+00 4.68e-07R 2\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 11r 0.0000000e+00 5.25e+03 2.22e+03 1.6 3.13e+04 - 3.88e-03 1.14e-03f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 12r 0.0000000e+00 5.08e+03 4.24e+04 1.6 1.22e+03 - 1.88e-01 5.18e-03f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 13r 0.0000000e+00 4.77e+03 3.36e+04 1.6 6.27e+01 - 3.06e-02 6.76e-02f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 14r 0.0000000e+00 4.33e+03 1.32e+05 1.6 8.06e+00 - 5.05e-01 9.81e-02f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 15r 0.0000000e+00 4.19e+03 1.12e+05 1.6 9.20e+00 - 3.38e-01 3.25e-02f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 16r 0.0000000e+00 1.89e+03 5.50e+04 1.6 2.54e+00 - 8.42e-02 7.08e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 17r 0.0000000e+00 1.72e+03 4.73e+04 1.6 7.82e+00 - 2.36e-01 1.01e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 18r 0.0000000e+00 1.14e+03 2.84e+04 1.6 1.92e+00 - 7.10e-01 4.02e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 19r 0.0000000e+00 1.06e+03 2.92e+04 1.6 5.12e+00 - 7.85e-01 7.79e-02f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 20r 0.0000000e+00 2.69e+02 3.66e+03 1.6 5.52e-01 - 1.00e+00 9.33e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 21r 0.0000000e+00 1.64e+01 3.96e+02 0.9 1.63e-01 - 9.76e-01 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 22r 0.0000000e+00 6.87e-01 1.09e+02 0.2 3.52e-02 - 1.00e+00 9.59e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 23r 0.0000000e+00 2.05e-01 8.47e+03 -0.5 2.72e-03 - 1.00e+00 6.98e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 24r 0.0000000e+00 1.34e-03 2.18e-01 -0.5 1.87e-03 - 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 25r 0.0000000e+00 1.29e-02 1.88e+02 -2.9 3.36e-04 - 1.00e+00 9.47e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: 26r 0.0000000e+00 2.90e-06 4.04e-05 -2.9 7.48e-05 - 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of Iterations....: 26\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: (scaled) (unscaled)\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Constraint violation....: 2.1131334015933589e-08 2.8957967970200116e-06\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Overall NLP error.......: 2.1131334015933589e-08 2.8957967970200116e-06\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of objective function evaluations = 34\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of objective gradient evaluations = 12\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of equality constraint evaluations = 36\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of inequality constraint evaluations = 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of equality constraint Jacobian evaluations = 28\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of inequality constraint Jacobian evaluations = 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Number of Lagrangian Hessian evaluations = 26\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Total CPU secs in IPOPT (w/o function evaluations) = 0.008\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: Total CPU secs in NLP function evaluations = 0.000\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit.liquid_phase.properties_out: EXIT: Optimal Solution Found.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Property initialization routine finished.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase: Control volume properties initialization complete\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.liquid_phase: Control volume reactions initialization complete\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit: Initialization Step 1 Complete.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: Starting initialization routine\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: Bubble, dew, and critical point initialization completed.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: Equilibrium temperature initialization completed.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: State variable initialization completed.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: Phase equilibrium initialization completed.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit.vapor_phase: Property initialization routine finished.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit: Initialization Step 2 Complete.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Ipopt 3.13.2: linear_solver=\"ma57\"\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: max_iter=200\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: nlp_scaling_method=\"gradient-based\"\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: tol=1e-06\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: ******************************************************************************\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: For more information visit http://projects.coin-or.org/Ipopt\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: This version of Ipopt was compiled from source code available at\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: for large-scale scientific computation. All technical papers, sales and\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: publicity material resulting from use of the HSL codes within IPOPT must\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: contain the following acknowledgement:\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: HSL, a collection of Fortran codes for large-scale scientific\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: computation. See http://www.hsl.rl.ac.uk.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: ******************************************************************************\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of nonzeros in equality constraint Jacobian...: 231\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of nonzeros in inequality constraint Jacobian.: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of nonzeros in Lagrangian Hessian.............: 149\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Total number of variables............................: 51\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: variables with only lower bounds: 12\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: variables with lower and upper bounds: 34\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: variables with only upper bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Total number of equality constraints.................: 51\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Total number of inequality constraints...............: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: inequality constraints with only lower bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: inequality constraints with lower and upper bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: inequality constraints with only upper bounds: 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 0 0.0000000e+00 3.62e+06 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Reallocating memory for MA57: lfact (3323)\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 1 0.0000000e+00 3.00e+06 1.18e+02 -1.0 3.71e+04 - 5.00e-01 1.73e-01h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 2 0.0000000e+00 2.99e+06 3.06e+03 -1.0 2.81e+04 - 8.76e-01 3.30e-03h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 3 0.0000000e+00 2.99e+06 8.95e+07 -1.0 2.80e+04 - 9.79e-01 3.34e-05h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 4r 0.0000000e+00 2.99e+06 1.00e+03 1.9 0.00e+00 - 0.00e+00 1.74e-07R 2\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 5r 0.0000000e+00 2.93e+06 9.98e+02 1.9 3.19e+04 - 2.43e-03 2.43e-03f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 6r 0.0000000e+00 2.86e+06 1.02e+03 1.2 3.69e+02 - 3.26e-01 2.09e-03f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 7r 0.0000000e+00 2.23e+06 1.04e+03 1.2 2.85e+02 - 1.93e-01 8.65e-02f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 8r 0.0000000e+00 1.90e+06 1.12e+05 1.2 2.94e+02 - 7.31e-02 2.42e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 9r 0.0000000e+00 1.44e+06 7.08e+04 1.2 1.51e+02 - 7.79e-01 2.13e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 10r 0.0000000e+00 1.21e+06 3.79e+04 1.2 1.60e+00 2.0 4.46e-01 1.46e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 11r 0.0000000e+00 7.63e+04 1.14e+04 1.2 9.97e+01 - 3.46e-01 9.00e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 12r 0.0000000e+00 4.57e+04 2.79e+04 1.2 8.49e+01 - 1.00e+00 2.61e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 13r 0.0000000e+00 5.79e+04 9.55e+03 1.2 3.35e+01 - 1.00e+00 7.44e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 14r 0.0000000e+00 1.21e+05 1.45e+04 1.2 2.11e+01 - 1.00e+00 1.00e+00h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 15r 0.0000000e+00 2.24e+05 6.34e+02 1.2 7.86e+00 - 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 16r 0.0000000e+00 2.19e+05 4.22e+03 0.5 1.77e+00 - 1.00e+00 9.43e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 17r 0.0000000e+00 3.93e+05 6.53e+02 0.5 1.02e+02 - 5.02e-01 4.46e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 18r 0.0000000e+00 4.24e+05 4.17e+03 0.5 1.55e+01 - 1.00e+00 2.17e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 19r 0.0000000e+00 4.87e+05 1.47e+01 0.5 7.37e+00 - 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 20r 0.0000000e+00 5.23e+05 2.31e+03 -0.9 1.53e+00 - 9.40e-01 7.50e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 21r 0.0000000e+00 5.39e+05 7.30e+03 -0.9 2.08e+02 - 8.07e-01 3.86e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 22r 0.0000000e+00 5.39e+05 5.05e+03 -0.9 1.37e+02 - 1.00e+00 4.43e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 23r 0.0000000e+00 5.38e+05 7.93e+00 -0.9 7.27e+01 - 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 24r 0.0000000e+00 5.39e+05 1.75e-03 -0.9 2.41e-01 - 1.00e+00 1.00e+00h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 25r 0.0000000e+00 5.44e+05 2.59e+01 -3.6 3.79e+00 - 9.90e-01 9.73e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 26r 0.0000000e+00 4.44e+05 3.73e+02 -3.6 6.08e+03 - 7.62e-02 6.44e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 27r 0.0000000e+00 3.34e+05 7.09e+02 -3.6 2.85e+03 - 5.42e-02 9.37e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 28r 0.0000000e+00 2.87e+03 9.51e+02 -3.6 1.42e+03 - 1.73e-01 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 29r 0.0000000e+00 8.65e+04 2.35e+02 -3.6 1.10e+03 - 1.00e+00 1.00e+00H 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 30r 0.0000000e+00 8.28e+04 4.88e-01 -3.6 1.19e+02 - 1.00e+00 1.00e+00h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 31r 0.0000000e+00 8.28e+04 9.25e-05 -3.6 2.69e-01 - 1.00e+00 1.00e+00h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 32r 0.0000000e+00 8.28e+04 2.10e+00 -5.4 5.64e-02 - 1.00e+00 9.70e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 33r 0.0000000e+00 8.28e+04 2.49e+02 -5.4 1.00e-03 1.5 8.85e-01 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 34r 0.0000000e+00 8.27e+04 3.33e-02 -5.4 3.00e-03 1.0 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 35r 0.0000000e+00 8.27e+04 3.31e-02 -5.4 8.93e-03 0.6 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 36r 0.0000000e+00 8.26e+04 3.24e-02 -5.4 2.63e-02 0.1 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 37r 0.0000000e+00 8.23e+04 3.06e-02 -5.4 7.43e-02 -0.4 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 38r 0.0000000e+00 8.16e+04 2.59e-02 -5.4 1.89e-01 -0.9 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 39r 0.0000000e+00 8.02e+04 4.92e-02 -5.4 3.67e-01 -1.3 1.00e+00 1.00e+00h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 40r 0.0000000e+00 7.85e+04 6.76e-02 -5.4 1.01e+00 -1.8 1.00e+00 1.00e+00h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 41r 0.0000000e+00 7.76e+04 2.21e-02 -5.4 3.03e+00 -2.3 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 42r 0.0000000e+00 7.73e+04 1.54e-02 -5.4 9.07e+00 -2.8 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 43r 0.0000000e+00 7.69e+04 1.54e-02 -5.4 2.72e+01 -3.2 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 44r 0.0000000e+00 7.57e+04 9.45e-02 -5.4 8.16e+01 -3.7 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 45r 0.0000000e+00 7.21e+04 7.98e-01 -5.4 2.45e+02 -4.2 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 46r 0.0000000e+00 6.17e+04 5.91e+00 -5.4 7.40e+02 -4.7 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 47r 0.0000000e+00 3.69e+04 5.13e+01 -5.4 2.31e+03 -5.2 1.00e+00 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 48r 0.0000000e+00 7.15e+04 1.47e+02 -5.4 1.10e+04 -5.6 1.00e+00 2.17e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 49r 0.0000000e+00 7.15e+04 4.98e+02 -5.4 4.07e+03 -5.2 1.00e+00 5.56e-06h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 50r 0.0000000e+00 2.07e+05 4.58e+03 -5.4 2.01e+04 -5.7 4.61e-01 1.75e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 51r 0.0000000e+00 1.19e+06 4.31e+04 -5.4 9.31e+03 -5.3 2.11e-06 1.00e+00f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 52r 0.0000000e+00 1.16e+06 3.63e+04 -5.4 1.14e+02 -0.3 4.01e-01 1.23e-01f 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 53r 0.0000000e+00 1.16e+06 3.63e+04 -5.4 2.83e+01 0.1 7.36e-01 7.74e-07h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 54r 0.0000000e+00 1.16e+06 3.63e+04 -5.4 3.94e+03 - 1.59e-01 7.41e-06h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 55r 0.0000000e+00 7.95e+05 2.50e+04 -5.4 4.00e+03 - 7.84e-01 3.17e-01h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 56r 0.0000000e+00 3.83e+05 1.19e+04 -5.4 1.69e+03 - 1.35e-05 5.23e-01h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 57r 0.0000000e+00 2.95e+05 9.19e+03 -5.4 9.94e+00 -0.4 5.56e-01 2.31e-01h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 58r 0.0000000e+00 1.29e+04 7.45e+02 -5.4 1.55e+03 - 2.88e-06 1.00e+00h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 59r 0.0000000e+00 1.05e+04 3.57e+00 -5.4 8.95e-02 -0.8 1.00e+00 1.00e+00h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 60r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 7.60e-02 -1.3 1.00e+00 1.00e+00h 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 61r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 2.28e-01 -1.8 1.00e+00 2.50e-01h 3\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 62r 0.0000000e+00 1.05e+04 1.03e-02 -5.4 6.84e-01 -2.3 1.00e+00 1.56e-02h 7\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 63r 0.0000000e+00 1.05e+04 3.12e-02 -5.4 2.05e+00 -2.8 1.00e+00 9.77e-04h 11\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 64r 0.0000000e+00 1.05e+04 9.35e-02 -5.4 6.16e+00 -3.2 1.00e+00 1.22e-04h 14\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 65r 0.0000000e+00 1.05e+04 2.81e-01 -5.4 1.85e+01 -3.7 1.00e+00 7.45e-09h 28\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 66r 0.0000000e+00 1.05e+04 8.49e-01 -5.4 5.60e+01 -4.2 1.00e+00 1.86e-09h 30\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 67r 0.0000000e+00 1.05e+04 2.61e+00 -5.4 1.72e+02 -4.7 1.00e+00 1.16e-10h 34\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 68r 0.0000000e+00 1.05e+04 8.40e+00 -5.4 5.54e+02 -5.1 1.00e+00 3.64e-12h 39\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 69r 0.0000000e+00 1.05e+04 8.40e+00 -5.4 2.14e+03 -5.6 0.00e+00 3.59e-18R 58\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 70r 0.0000000e+00 1.05e+04 1.94e+01 -5.4 4.50e+04 -6.1 1.63e-02 1.43e-12f 35\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 71r 0.0000000e+00 1.05e+04 3.85e+01 -5.4 2.54e+03 -5.7 1.00e+00 1.27e-11f 36\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 72r 0.0000000e+00 1.05e+04 1.11e+01 -5.4 7.22e+02 -5.2 9.93e-01 2.91e-11f 36\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 73r 0.0000000e+00 1.05e+04 3.70e+01 -5.4 3.05e+03 -5.7 7.35e-01 1.32e-12f 39\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 74r 0.0000000e+00 1.05e+04 1.25e+01 -5.4 8.27e+02 -5.3 1.00e+00 3.64e-12f 39\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 75r 0.0000000e+00 1.05e+04 3.60e+01 -5.4 3.72e+03 -5.8 5.36e-01 1.35e-13f 42\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 76r 0.0000000e+00 1.05e+04 1.44e+01 -5.4 9.51e+02 -5.3 1.00e+00 1.14e-13f 44\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 77r 0.0000000e+00 1.05e+04 2.35e+01 -5.4 4.61e+03 -5.8 1.64e-01 1.36e-14f 45\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 78r 0.0000000e+00 1.05e+04 1.66e+01 -5.4 1.10e+03 -5.4 1.00e+00 3.55e-15f 49\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 79r 0.0000000e+00 1.05e+04 2.55e+01 -5.4 5.86e+03 -5.9 1.22e-01 3.35e-16f 50\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 80r 0.0000000e+00 2.67e+04 5.84e+01 -5.4 1.27e+03 -5.4 1.00e+00 8.72e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 81r 0.0000000e+00 2.67e+04 2.19e+03 -5.4 1.28e+03 - 4.11e-03 2.62e-05w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 82r 0.0000000e+00 4.42e+04 8.23e+02 -5.4 3.84e+03 -5.9 5.02e-01 4.78e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 83r 0.0000000e+00 1.05e+04 1.92e+01 -5.4 1.21e+04 - 1.00e+00 7.74e-16f 50\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 84r 0.0000000e+00 1.05e+04 2.07e+01 -5.4 1.47e+03 -5.5 4.87e-01 3.33e-16h 52\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 85r 0.0000000e+00 1.05e+04 5.09e+01 -5.4 1.08e+04 -6.0 2.11e-01 1.14e-17f 54\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 86r 0.0000000e+00 1.05e+04 6.78e+01 -5.4 1.72e+03 -5.5 1.00e+00 1.78e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 87r 0.0000000e+00 1.05e+04 1.11e+02 -5.4 1.65e+04 -6.0 4.54e-02 1.86e-18f 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 88r 0.0000000e+00 1.05e+04 2.03e+02 -5.4 2.02e+03 -5.6 1.00e+00 1.52e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 89r 0.0000000e+00 1.05e+04 3.30e+02 -5.4 3.06e+04 -6.1 2.34e-02 1.00e-18f 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 90r 0.0000000e+00 1.05e+04 7.12e+02 -5.4 2.38e+03 -5.7 1.00e+00 1.29e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 91r 0.0000000e+00 1.05e+04 7.29e+02 -5.4 9.01e+04 -6.1 3.00e-04 3.41e-19f 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 92r 0.0000000e+00 1.05e+04 3.99e+01 -5.4 2.95e+03 -5.7 3.70e-01 2.84e-18h 59\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 93r 0.0000000e+00 2.20e+04 3.07e+01 -5.4 7.91e+02 -5.3 1.00e+00 1.00e+00w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 94r 0.0000000e+00 3.01e+04 4.20e+01 -5.4 2.61e+03 -5.8 7.22e-01 2.55e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 95r 0.0000000e+00 3.01e+04 1.37e+03 -5.4 1.07e+03 - 1.99e-03 3.17e-05w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 96r 0.0000000e+00 1.05e+04 1.20e+01 -5.4 7.00e+03 -6.2 1.00e+00 1.78e-15h 49\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 97r 0.0000000e+00 1.05e+04 2.31e+01 -5.4 4.29e+03 -5.8 2.10e-01 6.00e-11f 33\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 98r 0.0000000e+00 1.05e+04 1.59e+01 -5.4 1.05e+03 -5.4 1.00e+00 7.28e-12f 38\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 99r 0.0000000e+00 1.05e+04 2.46e+01 -5.4 5.40e+03 -5.9 1.33e-01 4.76e-11f 33\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 100r 0.0000000e+00 1.05e+04 1.83e+01 -5.4 1.21e+03 -5.4 1.00e+00 1.07e-10f 34\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 101r 0.0000000e+00 1.05e+04 2.73e+01 -5.4 7.03e+03 -5.9 1.02e-01 3.66e-11f 33\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 102r 0.0000000e+00 1.05e+04 2.77e+01 -5.4 1.40e+03 -5.5 1.00e+00 1.43e-12f 40\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 103r 0.0000000e+00 1.05e+04 4.37e+01 -5.4 9.60e+03 -6.0 7.47e-02 5.24e-14f 42\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 104r 0.0000000e+00 1.05e+04 6.49e+01 -5.4 1.63e+03 -5.5 1.00e+00 7.69e-14f 44\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 105r 0.0000000e+00 1.05e+04 1.04e+02 -5.4 1.42e+04 -6.0 5.06e-02 1.11e-15f 47\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 106r 0.0000000e+00 2.67e+04 1.58e+01 -5.4 1.91e+03 -5.6 1.00e+00 5.77e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 107r 0.0000000e+00 2.67e+04 1.40e+03 -5.4 9.67e+02 - 2.90e-03 3.66e-04w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 108r 0.0000000e+00 4.39e+04 4.78e+02 -5.4 5.57e+03 -6.1 3.84e-01 3.25e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 109r 0.0000000e+00 1.05e+04 1.80e+02 -5.4 6.38e+03 - 1.00e+00 4.10e-15f 47\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 110r 0.0000000e+00 1.05e+04 2.40e+02 -5.4 2.26e+03 -5.6 3.17e-01 3.47e-15f 48\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 111r 0.0000000e+00 1.05e+04 5.44e+02 -5.4 6.90e+04 -6.1 2.06e-02 1.14e-16f 48\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 112r 0.0000000e+00 1.05e+04 4.95e+01 -5.4 2.79e+03 -5.7 2.55e-01 7.69e-16f 51\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 113r 0.0000000e+00 1.05e+04 1.15e+01 -5.4 7.57e+02 -5.3 1.00e+00 7.11e-15f 48\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 114r 0.0000000e+00 1.05e+04 2.06e+01 -5.4 3.26e+03 -5.7 2.41e-01 6.02e-16f 50\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 115r 0.0000000e+00 1.05e+04 1.32e+01 -5.4 8.68e+02 -5.3 1.00e+00 2.22e-16h 53\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 116r 0.0000000e+00 1.05e+04 2.17e+01 -5.4 3.99e+03 -5.8 1.79e-01 3.07e-17h 54\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 117r 0.0000000e+00 1.05e+04 1.51e+01 -5.4 9.98e+02 -5.4 1.00e+00 2.78e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 118r 0.0000000e+00 1.05e+04 2.38e+01 -5.4 4.99e+03 -5.8 1.44e-01 6.14e-18h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 119r 0.0000000e+00 2.67e+04 5.98e+01 -5.4 1.15e+03 -5.4 1.00e+00 9.60e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 120r 0.0000000e+00 2.67e+04 2.31e+03 -5.4 1.66e+03 - 4.25e-03 1.30e-05w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 121r 0.0000000e+00 4.43e+04 8.41e+02 -5.4 3.52e+03 -5.9 5.33e-01 5.24e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 122r 0.0000000e+00 1.05e+04 1.75e+01 -5.4 1.31e+04 - 1.00e+00 2.66e-17h 55\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 123r 0.0000000e+00 1.05e+04 1.89e+01 -5.4 1.33e+03 -5.5 5.38e-01 2.30e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 124r 0.0000000e+00 1.05e+04 4.92e+01 -5.4 8.61e+03 -5.9 2.71e-01 3.56e-18h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 125r 0.0000000e+00 1.05e+04 2.98e+01 -5.4 1.55e+03 -5.5 1.00e+00 1.98e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 126r 0.0000000e+00 1.05e+04 4.92e+01 -5.4 1.23e+04 -6.0 6.33e-02 2.48e-18h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 127r 0.0000000e+00 1.05e+04 8.12e+01 -5.4 1.82e+03 -5.6 1.00e+00 1.69e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 128r 0.0000000e+00 1.05e+04 1.31e+02 -5.4 2.00e+04 -6.0 3.59e-02 1.53e-18f 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 129r 0.0000000e+00 1.05e+04 2.54e+02 -5.4 2.14e+03 -5.6 1.00e+00 1.43e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 130r 0.0000000e+00 1.05e+04 4.15e+02 -5.4 4.32e+04 -6.1 1.66e-02 7.10e-19f 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 131r 0.0000000e+00 1.05e+04 9.52e+02 -5.4 2.53e+03 -5.7 1.00e+00 1.21e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 132r 0.0000000e+00 2.67e+04 2.24e+01 -5.4 4.51e+05 -6.1 1.18e-04 2.45e-03w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 133r 0.0000000e+00 4.32e+04 1.53e+02 -5.4 4.75e+04 -6.6 3.50e-02 3.68e-02w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 134r 0.0000000e+00 4.32e+04 3.80e+02 -5.4 3.44e+03 - 1.99e-02 3.86e-06w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 135r 0.0000000e+00 1.05e+04 9.98e+02 -5.4 8.04e+02 - 1.18e-04 6.81e-20f 55\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 136r 0.0000000e+00 1.05e+04 2.21e+01 -5.4 8.37e+02 -5.3 6.52e-01 5.55e-17h 55\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 137r 0.0000000e+00 1.05e+04 2.91e+01 -5.4 3.73e+03 -5.8 2.04e-01 8.22e-18h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 138r 0.0000000e+00 1.05e+04 1.45e+01 -5.4 9.53e+02 -5.3 1.00e+00 5.55e-17h 55\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 139r 0.0000000e+00 1.05e+04 2.31e+01 -5.4 4.63e+03 -5.8 1.55e-01 6.62e-18h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 140r 0.0000000e+00 1.05e+04 1.67e+01 -5.4 1.10e+03 -5.4 1.00e+00 2.78e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 141r 0.0000000e+00 1.05e+04 2.55e+01 -5.4 5.89e+03 -5.9 1.22e-01 5.20e-18h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 142r 0.0000000e+00 1.05e+04 1.93e+01 -5.4 1.27e+03 -5.4 1.00e+00 2.41e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 143r 0.0000000e+00 1.05e+04 2.84e+01 -5.4 7.78e+03 -5.9 9.22e-02 3.94e-18h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 144r 0.0000000e+00 1.05e+04 3.40e+01 -5.4 1.48e+03 -5.5 1.00e+00 2.08e-17h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 145r 0.0000000e+00 2.67e+04 4.04e+01 -5.4 1.09e+04 -6.0 6.60e-02 1.02e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 146r 0.0000000e+00 2.67e+04 1.47e+03 -5.4 1.02e+03 - 2.88e-03 1.10e-04w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 147r 0.0000000e+00 4.33e+04 7.00e+02 -5.4 1.97e+04 -6.5 1.24e-01 8.93e-02w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 148r 0.0000000e+00 1.05e+04 5.40e+01 -5.4 6.24e+03 - 6.60e-02 2.82e-18h 55\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 149r 0.0000000e+00 1.05e+04 1.51e+02 -5.4 1.68e+04 -6.0 1.26e-01 1.83e-18h 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 150r 0.0000000e+00 1.05e+04 5.58e+01 -5.4 2.10e+03 -5.6 1.51e-01 9.25e-19h 60\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 151r 0.0000000e+00 1.05e+04 6.31e+01 -5.4 3.28e+04 -6.1 1.66e-02 9.36e-19f 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 152r 0.0000000e+00 1.05e+04 6.32e+01 -5.4 3.63e+03 -5.7 8.61e-03 1.56e-18h 54\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 153r 0.0000000e+00 1.05e+04 6.33e+01 -5.4 2.10e+05 -6.1 1.98e-05 1.48e-19f 56\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 154r 0.0000000e+00 1.05e+04 8.87e-01 -5.4 1.46e-02 -0.3 1.00e+00 1.43e-06h 4\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 155r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 2.09e-02 -0.8 1.00e+00 5.00e-01f 2\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 156r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 6.26e-02 -1.2 1.00e+00 2.44e-04h 13\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 157r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 1.88e-01 -1.7 1.00e+00 1.53e-05h 17\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 158r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 5.64e-01 -2.2 1.00e+00 1.00e+00w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 159r 0.0000000e+00 1.05e+04 3.61e-03 -5.4 1.69e+00 -2.7 1.00e+00 1.00e+00w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 160r 0.0000000e+00 1.06e+04 3.62e-03 -5.4 5.08e+00 -3.1 1.00e+00 1.00e+00w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 161r 0.0000000e+00 1.05e+04 8.60e-03 -5.4 1.53e+01 -3.6 1.00e+00 7.45e-09h 27\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 162r 0.0000000e+00 1.05e+04 6.99e-01 -5.4 4.61e+01 -4.1 1.00e+00 1.14e-13h 44\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 163r 0.0000000e+00 1.05e+04 2.14e+00 -5.4 1.41e+02 -4.6 1.00e+00 2.84e-14h 46\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 164r 0.0000000e+00 1.05e+04 6.79e+00 -5.4 4.48e+02 -5.1 1.00e+00 4.66e-10f 32\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 165r 0.0000000e+00 1.05e+04 2.13e+01 -5.4 1.64e+03 -5.5 8.03e-01 1.96e-11f 36\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 166r 0.0000000e+00 1.05e+04 5.45e+01 -5.4 1.44e+04 -6.0 1.69e-01 5.60e-13f 38\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 167r 0.0000000e+00 1.05e+04 2.91e+01 -5.4 1.92e+03 -5.6 1.00e+00 1.31e-13f 43\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 168r 0.0000000e+00 1.05e+04 3.94e+01 -5.4 2.52e+04 -6.1 2.91e-02 3.11e-16f 48\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 169r 0.0000000e+00 1.05e+04 3.44e+01 -5.4 2.27e+03 -5.6 1.00e+00 3.46e-15h 48\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 170r 0.0000000e+00 1.05e+04 4.50e+01 -5.4 7.69e+04 -6.1 9.32e-03 1.28e-17f 51\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 171r 0.0000000e+00 2.67e+04 3.33e+01 -5.4 2.71e+03 -5.7 1.00e+00 4.08e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 172r 0.0000000e+00 2.67e+04 9.73e+02 -5.4 1.12e+03 - 1.93e-03 9.14e-05w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 173r 0.0000000e+00 4.37e+04 5.94e+02 -5.4 7.46e+03 -6.2 2.29e-01 2.40e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 174r 0.0000000e+00 1.05e+04 4.51e+01 -5.4 3.87e+03 - 1.00e+00 2.97e-12f 37\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 175r 0.0000000e+00 1.05e+04 6.47e+01 -5.4 3.27e+03 -5.7 2.19e-01 7.69e-14f 43\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 176r 0.0000000e+00 1.05e+04 5.10e+01 -5.4 8.69e+02 -5.3 1.00e+00 1.14e-13h 44\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 177r 0.0000000e+00 1.05e+04 7.51e+01 -5.4 4.00e+03 -5.8 1.79e-01 6.43e-11f 33\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 178r 0.0000000e+00 1.05e+04 6.82e+01 -5.4 1.00e+03 -5.4 1.00e+00 4.66e-10f 32\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 179r 0.0000000e+00 1.05e+04 1.03e+02 -5.4 5.00e+03 -5.8 1.43e-01 1.29e-11f 35\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 180r 0.0000000e+00 1.05e+04 1.08e+02 -5.4 1.15e+03 -5.4 1.00e+00 1.39e-11f 37\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 181r 0.0000000e+00 1.05e+04 1.65e+02 -5.4 6.42e+03 -5.9 1.12e-01 5.01e-12f 36\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 182r 0.0000000e+00 1.05e+04 2.00e+02 -5.4 1.34e+03 -5.5 1.00e+00 1.20e-11f 37\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 183r 0.0000000e+00 1.05e+04 3.13e+02 -5.4 8.54e+03 -5.9 8.39e-02 9.41e-13f 38\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 184r 0.0000000e+00 2.67e+04 6.63e+01 -5.4 1.55e+03 -5.5 1.00e+00 7.13e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 185r 0.0000000e+00 2.67e+04 8.09e+02 -5.4 1.01e+03 - 2.25e-03 8.90e-04w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 186r 0.0000000e+00 4.40e+04 1.17e+02 -5.4 4.65e+03 -6.0 4.39e-01 3.92e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 187r 0.0000000e+00 1.05e+04 4.40e+02 -5.4 8.89e+03 - 1.00e+00 2.07e-11f 35\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 188r 0.0000000e+00 1.05e+04 5.51e+02 -5.4 1.81e+03 -5.6 3.96e-01 8.88e-12f 37\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 189r 0.0000000e+00 1.05e+04 8.25e+02 -5.4 1.87e+04 -6.0 3.12e-02 1.08e-13f 40\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 190r 0.0000000e+00 1.05e+04 3.35e+01 -5.4 2.20e+03 -5.6 4.67e-01 2.27e-13f 43\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 191r 0.0000000e+00 1.05e+04 4.40e+01 -5.4 4.69e+04 -6.1 1.56e-02 5.36e-15f 43\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 192r 0.0000000e+00 1.05e+04 3.87e+01 -5.4 2.56e+03 -5.7 1.00e+00 2.46e-14f 45\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 193r 0.0000000e+00 1.05e+04 1.92e+01 -5.4 7.26e+02 -5.2 9.88e-01 1.14e-13h 44\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 194r 0.0000000e+00 1.05e+04 4.68e+01 -5.4 3.07e+03 -5.7 7.96e-01 1.68e-10f 32\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 195r 0.0000000e+00 1.05e+04 3.54e+01 -5.4 8.31e+02 -5.3 1.00e+00 5.82e-11f 35\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 196r 0.0000000e+00 1.05e+04 8.07e+01 -5.4 3.74e+03 -5.8 5.32e-01 6.87e-11f 33\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 197r 0.0000000e+00 2.44e+04 4.51e+01 -5.4 9.55e+02 -5.3 1.00e+00 1.00e+00w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 198r 0.0000000e+00 2.90e+04 1.83e+02 -5.4 3.03e+03 -5.8 6.02e-01 1.26e-01w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 199r 0.0000000e+00 2.90e+04 3.65e+02 -5.4 1.03e+03 - 1.58e-03 1.30e-03w 1\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: 200r 0.0000000e+00 1.05e+04 6.99e+01 -5.4 9.09e+03 -6.3 1.00e+00 2.91e-11f 35\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of Iterations....: 200\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: (scaled) (unscaled)\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Dual infeasibility......: 6.9908071367141474e+01 6.9908071367141474e+01\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Constraint violation....: 2.8645094423111342e-03 1.0458847092153306e+04\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Complementarity.........: 1.3579265591895737e-03 1.3579265591895737e-03\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Overall NLP error.......: 2.8645094423111342e-03 1.0458847092153306e+04\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of objective function evaluations = 5209\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of objective gradient evaluations = 6\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of equality constraint evaluations = 5210\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of inequality constraint evaluations = 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of equality constraint Jacobian evaluations = 203\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of inequality constraint Jacobian evaluations = 0\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Number of Lagrangian Hessian evaluations = 200\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Total CPU secs in IPOPT (w/o function evaluations) = 0.176\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: Total CPU secs in NLP function evaluations = 0.014\n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: \n", - "2026-04-29 17:11:55 [DEBUG] idaes.solve.fs.unit: EXIT: Maximum Number of Iterations Exceeded.\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit: Initialization Step 3 maxIterations - .\n", - "2026-04-29 17:11:55 [INFO] idaes.init.fs.unit: Initialization Complete: maxIterations - \n", - "Initialization failed.\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "import logging\n", + "import traceback\n", + "\n", "from pyomo.environ import (\n", " ComponentMap,\n", " ConcreteModel,\n", @@ -615,14 +111,19 @@ " return m\n", "\n", "\n", - "if __name__ == \"__main__\":\n", - " m = create_model()\n", - "\n", - " reboiler_init = m.fs.unit.default_initializer(always_estimate_states=True)\n", - " try:\n", - " reboiler_init.initialize(m.fs.unit, output_level=idaeslog.DEBUG)\n", - " except InitializationError:\n", - " print(\"Initialization failed.\")" + "m = create_model()\n", + "reboiler_init = m.fs.unit.default_initializer(always_estimate_states=True)\n", + "try:\n", + " reboiler_init.initialize(m.fs.unit, output_level=idaeslog.DEBUG)\n", + "except InitializationError:\n", + " traceback.print_exc()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here we see that initialization failed due to the unit model solve terminating after reaching the maximum number of iterations. However, when solution of a square problem reaches 200-300 iterations without converging, increasing the number of iterations usually does not help. In this case, it terminates with a `Restoration Failed` status after about 500 iterations. When confronted with a failing solve, we should first head to the `DiagnosticsToolbox`." ] }, { @@ -630,54 +131,58 @@ "metadata": {}, "source": [ "## Step 2: Run Model Diagnostics\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "While initialization fails in every version of Python supported presently (3.10, 3.11, 3.12 3.13), the model termination point(s) that Python 3.10 and 3.11 come to are different than the model termination point that 3.12 and 3.13 come to. In order to ensure that the diagnostic output is the same in every supported version, we load the model state from a `json` file." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "from idaes.core.util import from_json, StoreSpec\n", "\n", - "We see that the unit model failed to initialize. When confronted with a bad solution state, we should first use the `DiagnosticsToolbox` to check to see if there are structural issues with the model." + "from_json(m, fname=\"advanced_scaling_failed_solution.json\", wts=StoreSpec.value())" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "First, we will use the `DiagnosticsToolbox` to check to see if there are structural issues with the model. (More information about the `DiagnosticsToolbox` can be found in its [documentation](https://idaes-pse.readthedocs.io/en/stable/explanations/model_diagnostics/index.html) and [tutorial notebook](https://idaes-examples.readthedocs.io/en/latest/docs/diagnostics/diagnostics_toolbox_doc.html)" ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": { - "scrolled": true + "editable": true, + "scrolled": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "====================================================================================\n", - "Model Statistics\n", - "\n", - " Activated Blocks: 23 (Deactivated: 0)\n", - " Free Variables in Activated Constraints: 77 (External: 0)\n", - " Free Variables with only lower bounds: 15\n", - " Free Variables with only upper bounds: 0\n", - " Free Variables with upper and lower bounds: 50\n", - " Fixed Variables in Activated Constraints: 66 (External: 0)\n", - " Activated Equality Constraints: 77 (Deactivated: 0)\n", - " Activated Inequality Constraints: 0 (Deactivated: 0)\n", - " Activated Objectives: 0 (Deactivated: 0)\n", - "\n", - "------------------------------------------------------------------------------------\n", - "1 WARNINGS\n", - "\n", - " WARNING: Found 9 potential evaluation errors.\n", - "\n", - "------------------------------------------------------------------------------------\n", - "2 Cautions\n", - "\n", - " Caution: 11 variables fixed to 0\n", - " Caution: 82 unused variables (82 fixed)\n", - "\n", - "------------------------------------------------------------------------------------\n", - "Suggested next steps:\n", - "\n", - " display_potential_evaluation_errors()\n", - "\n", - "====================================================================================\n" - ] - } - ], + "outputs": [], "source": [ "from idaes.core.util import DiagnosticsToolbox\n", "\n", @@ -689,56 +194,16 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "The density relationship is being flagged for potential evaluation errors. The interval arithmetic used to identify potential evaluation errors can produce relatively loose bounds, especially for the sort of large polynomial expressions favored in the literature. Independent testing of the density relationship over a wide range of values has demonstrated that no evaluation errors occur, so we can ignore these warnings.\n", + "The density relationship is being flagged for potential evaluation errors. The interval arithmetic used to identify potential evaluation errors can produce relatively loose bounds, especially for the sort of large polynomial expressions favored in engineering literature. Independent testing of the density relationship over a wide range of values has demonstrated that no evaluation errors occur, so we can ignore these warnings.\n", "\n", "The next step is determining which numerical issues exist." ] }, { "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "====================================================================================\n", - "Model Statistics\n", - "\n", - " Jacobian Condition Number: 2.718E+13\n", - "\n", - "------------------------------------------------------------------------------------\n", - "3 WARNINGS\n", - "\n", - " WARNING: 3 Constraints with large residuals (>1.0E-05)\n", - " WARNING: 1 Variable with extreme Jacobian column norms (<1.0E-08 or >1.0E+08)\n", - " WARNING: 1 Constraint with extreme Jacobian row norms (<1.0E-08 or >1.0E+08)\n", - "\n", - "------------------------------------------------------------------------------------\n", - "8 Cautions\n", - "\n", - " Caution: 9 Variables with value close to their bounds (abs=1.0E-04, rel=1.0E-04)\n", - " Caution: 18 Variables with value close to zero (tol=1.0E-08)\n", - " Caution: 30 Variables with extreme value (<1.0E-04 or >1.0E+04)\n", - " Caution: 2 Constraints with mismatched terms\n", - " Caution: 1 Constraint with potential cancellation of terms\n", - " Caution: 27 Variables with extreme Jacobian column norms (<1.0E-04 or >1.0E+04)\n", - " Caution: 16 Constraints with extreme Jacobian row norms (<1.0E-04 or >1.0E+04)\n", - " Caution: 50 extreme Jacobian Entries (<1.0E-04 or >1.0E+04)\n", - "\n", - "------------------------------------------------------------------------------------\n", - "Suggested next steps:\n", - "\n", - " display_constraints_with_large_residuals()\n", - " compute_infeasibility_explanation()\n", - " display_variables_with_extreme_jacobians()\n", - " display_constraints_with_extreme_jacobians()\n", - "\n", - "====================================================================================\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "dt.report_numerical_issues()" ] @@ -788,43 +253,14 @@ "$$\n", "With a condition number on the order of $10^{13}$ and the default tolerance $\\varepsilon = 10^{-6}$, then the difference between the computed solution $x_f$ and the true solution $x$ could be on the order of $10^7$.\n", "\n", - "In practice, however, we frequently end up with much better results than those predicted by this worst-case bound. Frequently, we find that most constraints have residuals on the order of $10^{-10}$ or less, with a few problematic constraints having larger residuals. That is the case here." + "In practice, however, we frequently end up with much better results than those predicted by this worst-case bound. The condition number of the unscaled Jacobian does not taken into account that some variables are much bigger than others. For example, the liquid phase mole fraction of $\\text{CO}_2$ is on the order of $10^{-5}$, whereas the heat duty is on the order of $10^6$. Unless we scale the model, we have no way of determining which changes to the solution are significant and which are not. Additionally, we frequently find that most constraints have residuals on the order of $10^{-10}$ or less, with only a few problematic constraints having larger residuals. That is the case here." ] }, { "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Number of constraints: 77\n", - "====================================================================================\n", - "The following constraint(s) have large residuals (>1.0E-10):\n", - "\n", - " fs.unit.unit_material_balance[0.0,CO2]: 1.84866E-10\n", - " fs.unit.unit_material_balance[0.0,N2]: 1.89950E-10\n", - " fs.unit.unit_material_balance[0.0,O2]: 1.87656E-10\n", - " fs.unit.unit_phase_equilibrium[0.0,CO2]: 1.04588E+04\n", - " fs.unit.unit_phase_equilibrium[0.0,H2O]: 8.88278E-07\n", - " fs.unit.unit_enthalpy_balance[0.0]: 5.05679E-10\n", - " fs.unit.liquid_phase.material_balances[0.0,CO2]: 1.70459E-10\n", - " fs.unit.liquid_phase.enthalpy_balances[0.0]: 1.17285E-05\n", - " fs.unit.liquid_phase.properties_out[0.0].sum_mole_frac_out: 2.08134E-10\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-]: 8.83857E-06\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]: 1.54414E-07\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA_+]: 7.69821E-06\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,H2O]: 2.50511E-08\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA]: 4.55346E-06\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2]: 4.42749E-05\n", - " fs.unit.vapor_phase[0.0].sum_mole_frac_out: 1.71144E-10\n", - "\n", - "====================================================================================\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "import idaes.core.util.model_statistics as mstat\n", "\n", @@ -846,7 +282,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -1081,14 +517,12 @@ "\n", "## Step 3: Creating a New Scaler Class\n", "\n", - "To create a new scaling routine for the equilibrium reactor, we start by creating a new ``Scaler`` class which inherits from the ``CustomScalerBase`` class in ``idaes.core.scaling``. The ``CustomScalerBase`` class contains a number of useful methods to help us in developing our scaling routine, including some placeholder methods for implementing a standard scaling workflow and helper methods for doing common tasks.\n", - "\n", - "The cell below shows how to create our new class which we will name ``SolventReboilerScaler`` as well as two key methods we will fill out as part of this workshop." + "To create a new scaling routine for the solvent reboiler, we start by creating a new ``Scaler`` class which inherits from the ``CustomScalerBase`` class in ``idaes.core.scaling``." ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -1113,7 +547,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "As you know from the first scaling tutorial, the ``variable_scaling_routine`` and ``constraint_scaling_routine`` methods are used to implement subroutines for scaling the variables and constraints in the model respectively. Separately, there is a ``scale_model`` method that will call each of these in sequence in order to scale an entire model by applying the following steps:\n", + "As you know from the [first scaling tutorial](./scaler_workshop_usr.ipynb), the ``variable_scaling_routine`` and ``constraint_scaling_routine`` methods are used to implement subroutines for scaling the variables and constraints in the model respectively. Separately, there is a ``scale_model`` method that will call each of these in sequence in order to scale an entire model by applying the following steps:\n", "\n", "1. apply variable scaling routine,\n", "2. apply first stage scaling fill-in,\n", @@ -1129,7 +563,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -1182,7 +616,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -1199,30 +633,9 @@ }, { "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'flow_mol_phase': ,\n", - " 'mole_frac_phase_comp': 10,\n", - " 'temperature': 0.0033333333333333335,\n", - " 'pressure': 1e-05,\n", - " 'enth_mol_phase': ,\n", - " 'visc_d_phase': ,\n", - " 'therm_cond_phase': ,\n", - " 'mole_frac_phase_comp_true': 10,\n", - " 'mole_frac_phase_comp_apparent': 10,\n", - " 'dens_mol_phase': ,\n", - " 'vol_mol_phase': }" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "liquid_properties_scaler.default_scaling_factors" ] @@ -1235,14 +648,14 @@ "\n", "With an inlet flow of about 80 mol/s, a scaling factor of 1/80 is appropriate. We can ignore ``visc_d_phase`` and ``therm_cond_phase``, because this unit model does not require dynamic viscosity or thermal conductivity. Molar enthalpy is a tougher quantity to scale.\n", "\n", - "By convention, the molar enthalpy of each element in its pure form at $25^\\circ\\text{C}$ and $1\\:\\text{atm}$ is set equal to zero. In some property packages, enthalpy of formation is taken into account for compounds, while in some property packages it is not. However, the scaling factor for enthalpy should not depend on this convention---only enthalpy *differences* are meaningful. So we need to determine how to determine what constitutes a \"significant\" enthalpy difference for this property package. The way the modular property scaler object estimates this is through the temperature scaling factor, which determines what a \"significant\" temperature difference is, and the observation that a wide range of substances have a specific heat capacity around $2\\:\\frac{\\text{J}}{\\text{g K}}$.\n", + "By convention, the molar enthalpy of each element in its pure form at $25^\\circ\\text{C}$ and $1\\:\\text{atm}$ is set equal to zero. In some property packages, enthalpy of formation is taken into account for compounds, while in some property packages it is not. However, the scaling factor for enthalpy should not depend on this convention\u2014only enthalpy *differences* are meaningful. So we need to determine how to determine what constitutes a \"significant\" enthalpy difference for this property package. The way the modular property scaler object estimates this is through the temperature scaling factor, which determines what a \"significant\" temperature difference is, and the observation that a wide range of substances have a specific heat capacity around $2\\:\\frac{\\text{J}}{\\text{g K}}$.\n", "\n", "This default method is good enough for our purposes now. We can revisit it later, if necessary." ] }, { "cell_type": "code", - "execution_count": 12, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -1262,45 +675,9 @@ }, { "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "====================================================================================\n", - "Model Statistics\n", - "\n", - " Jacobian Condition Number: 7.165E+10\n", - "\n", - "------------------------------------------------------------------------------------\n", - "1 WARNINGS\n", - "\n", - " WARNING: 1 Constraint with large residuals (>1.0E-05)\n", - "\n", - "------------------------------------------------------------------------------------\n", - "8 Cautions\n", - "\n", - " Caution: 9 Variables with value close to their bounds (abs=1.0E-04, rel=1.0E-04)\n", - " Caution: 14 Variables with value close to zero (tol=1.0E-08)\n", - " Caution: 27 Variables with extreme value (<1.0E-04 or >1.0E+04)\n", - " Caution: 2 Constraints with mismatched terms\n", - " Caution: 1 Constraint with potential cancellation of terms\n", - " Caution: 10 Variables with extreme Jacobian column norms (<1.0E-04 or >1.0E+04)\n", - " Caution: 4 Constraints with extreme Jacobian row norms (<1.0E-04 or >1.0E+04)\n", - " Caution: 33 extreme Jacobian Entries (<1.0E-04 or >1.0E+04)\n", - "\n", - "------------------------------------------------------------------------------------\n", - "Suggested next steps:\n", - "\n", - " display_constraints_with_large_residuals()\n", - " compute_infeasibility_explanation()\n", - "\n", - "====================================================================================\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "reboiler_scaler = SolventReboilerScaler()\n", "reboiler_scaler.scale_model(m.fs.unit)\n", @@ -1318,7 +695,7 @@ "$$\n", "\\max\\left(\\frac{||\\mathbf{r}_\\text{max}||_2}{||\\mathbf{r}_\\text{min}||_2}, \\frac{||\\mathbf{c}_\\text{max}||_2}{||\\mathbf{c}_\\text{min}||_2}\\right) \\leq \\kappa(\\mathbf{J}(\\mathbf{x}))\n", "$$\n", - "Consequently, Jacobian rows or columns with extremely large or extremely small norms indicate that the Jacobian is ill-conditioned. Each row is associated with a constraint and each column is associated with a variable. So the extreme Jacobian rows and columns give us a list of variables and constraints to investigate for scaling.\n", + "Consequently, Jacobian rows or columns with extremely large or extremely small norms indicate that the Jacobian is ill-conditioned. Each row is associated with a constraint and each column is associated with a variable. Thus, the extreme Jacobian rows and columns give us a list of variables and constraints to investigate for scaling.\n", "\n", "
\n", "Just because a variable or constraint has a Jacobian column or row with an extreme norm does not mean it is badly-scaled. Frequently, either a constraint containing the variable or a variable present in a constraint is the actual problem. \n", @@ -1337,40 +714,9 @@ }, { "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "====================================================================================\n", - "The following variable(s) correspond to Jacobian columns with extreme norms(<1.0E-04 or>1.0E+04):\n", - "\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,CO2]: 3.450E+07\n", - " fs.unit.liquid_phase.enthalpy_transfer[0.0]: 1.970E+06\n", - " fs.unit.liquid_phase.properties_out[0.0].temperature: 1.586E+06\n", - " fs.unit.vapor_phase[0.0].pressure: 1.353E+05\n", - " fs.unit.vapor_phase[0.0].temperature: 1.014E+05\n", - " fs.unit.liquid_phase.properties_out[0.0].pressure: 1.000E+05\n", - " fs.unit.vapor_phase[0.0].flow_mol_phase[Vap]: 3.256E+04\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,H2O]: 1.954E+04\n", - " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]: 1.873E+04\n", - " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]: 1.863E+04\n", - "\n", - "====================================================================================\n", - "====================================================================================\n", - "The following constraint(s) correspond to Jacobian rows with extreme norms (<1.0E-04 or>1.0E+04):\n", - "\n", - " fs.unit.unit_phase_equilibrium[0.0,CO2]: 3.450E+07\n", - " fs.unit.unit_enthalpy_balance[0.0]: 1.973E+06\n", - " fs.unit.unit_phase_equilibrium[0.0,H2O]: 1.589E+06\n", - " fs.unit.unit_pressure_balance[0.0]: 1.414E+05\n", - "\n", - "====================================================================================\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "dt.display_variables_with_extreme_jacobians()\n", "dt.display_constraints_with_extreme_jacobians()" @@ -1384,22 +730,14 @@ "\n", "## Step 5: Unit Model Level Scaling\n", "\n", - "We should take a look at the constraints before determining their scaling factors. However, Pyomo's `pprint` method often prints out multiple terminal pages' worth of thermodynamic expressions, which are extremely difficult to parse. The output is so verbose because it descends into named `Expressions` and recursively subsititutes them into the constraint expression. Since IDAES makes heavy use of named `Expressions` to decrease the number of `Constraints` in a model, the output becomes unmanangable for all but the most simple constraints. The `print_compact_form` utility function usually results in much more readable output." + "We should take a look at the constraints before determining their scaling factors. However, Pyomo's `pprint` method often prints out multiple terminal pages' worth of thermodynamic expressions, which are extremely difficult to parse. The output is so verbose because it descends into named `Expressions` and recursively subsititutes them into the constraint expression. Since IDAES makes heavy use of named `Expressions` to reduce the number of `Constraints` in a model, the output becomes unmanangable for all but the most simple constraints. The `print_compact_form` utility function usually results in much more readable output." ] }, { "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "- fs.unit.liquid_phase.enthalpy_transfer[0.0] == (kg*m**2/J/s**2)*fs.unit.vapor_phase[0.0]._enthalpy_flow_term[Vap]\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "from idaes.core.util.misc import print_compact_form\n", "\n", @@ -1418,20 +756,9 @@ }, { "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "5.076760620583219e-07" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "get_scaling_factor(m.fs.unit.liquid_phase.enthalpy_transfer[0.0])" ] @@ -1447,17 +774,9 @@ }, { "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "None\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "print(get_scaling_factor(m.fs.unit.vapor_phase[0.0]._enthalpy_flow_term[\"Vap\"]))" ] @@ -1471,17 +790,9 @@ }, { "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "fs.unit.vapor_phase[0.0].flow_mol_phase[Vap]*fs.unit.vapor_phase[0.0].enth_mol_phase[Vap]\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "print_compact_form(m.fs.unit.vapor_phase[0.0]._enthalpy_flow_term[\"Vap\"])" ] @@ -1495,20 +806,9 @@ }, { "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0.1" - ] - }, - "execution_count": 20, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "get_scaling_factor(m.fs.unit.vapor_phase[0.0].flow_mol_phase[\"Vap\"])" ] @@ -1522,20 +822,9 @@ }, { "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "5.46268982847154e-05" - ] - }, - "execution_count": 21, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "get_scaling_factor(m.fs.unit.vapor_phase[0.0].enth_mol_phase[\"Vap\"])" ] @@ -1549,20 +838,9 @@ }, { "cell_type": "code", - "execution_count": 22, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0.0125" - ] - }, - "execution_count": 22, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "get_scaling_factor(m.fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase[\"Liq\"])" ] @@ -1577,7 +855,7 @@ "$$\n", "Let $\\sigma(v)$ denote the scaling factor of the variable $v$. Then `get_sum_terms_nominal_values` substitutes the inverse of the variable scaling factor into each term in the sum and returns it as a list:\n", "$$\n", - "\\left[\\frac{1}{\\sigma(a)},\\; \\frac{1}{\\sigma(b) \\cdot \\sigma(c)}, \\frac{\\left(\\frac{1}{\\sigma(e)} - \\frac{1}{\\sigma(f)}\\right)}{\\sigma(d)} \\right]\n", + "\\left[\\frac{1}{\\sigma(a)},\\; \\frac{1}{\\sigma(b) \\cdot \\sigma(c)}, \\frac{-\\left(\\frac{1}{\\sigma(e)} - \\frac{1}{\\sigma(f)}\\right)}{\\sigma(d)} \\right]\n", "$$\n", "\n", "This process can produce reliable estimates of expression magnitude for certain operations:\n", @@ -1605,20 +883,9 @@ }, { "cell_type": "code", - "execution_count": 23, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[1969759.9999999995, 183060.0]" - ] - }, - "execution_count": 23, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "reboiler_scaler.get_sum_terms_nominal_values(m.fs.unit.unit_enthalpy_balance[0.0])" ] @@ -1627,7 +894,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "The inverse of either of these numbers would be reasonable scaling factors. The `scale_constraint_by_nominal value` function automatically scales a constraint by using one of these numbers. Which number we use is selected using the `ConstraintScalingScheme` `Enum` If we take the inverse of the larger number, we are saying that the constraint needs to be satisfied with the same precision as the largest term in the sum. This corresponds to `ConstraintScalingScheme.inverseMaximum`. If we take the inverse of the smaller number, we are saying that the constraint needs to be satisfied with the same precision as the smallest term in the sum. This corresponds to `ConstraintScalingScheme.inverseMinimum`.\n", + "The inverse of either of these numbers would be reasonable scaling factors. The `scale_constraint_by_nominal value` function automatically scales a constraint by using one of these numbers. Which number we use is selected using the `ConstraintScalingScheme` `Enum`. If we take the inverse of the larger number, we are saying that the constraint needs to be satisfied with the same precision as the largest term in the sum. This corresponds to `ConstraintScalingScheme.inverseMaximum`. If we take the inverse of the smaller number, we are saying that the constraint needs to be satisfied with the same precision as the smallest term in the sum. This corresponds to `ConstraintScalingScheme.inverseMinimum`.\n", "\n", "In general, the `inverseMinimum` scheme is the safest to use, because it demands the most precision. Let's use the `inverseMinimum` method for this constraint in order to more precisely determine the vapor phase's temperature.\n", "\n", @@ -1636,23 +903,11 @@ }, { "cell_type": "code", - "execution_count": 24, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[Liq,CO2] == fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,CO2]\n", - "\n", - "\n", - "fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[Liq,H2O] == fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,H2O]\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "print_compact_form(m.fs.unit.unit_phase_equilibrium[0.0, \"CO2\"])\n", - "print(\"\\n\")\n", "print_compact_form(m.fs.unit.unit_phase_equilibrium[0.0, \"H2O\"])" ] }, @@ -1665,18 +920,9 @@ }, { "cell_type": "code", - "execution_count": 26, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[7623092.433711249, 10000.0]\n", - "[355.3596511053128, 10000.0]\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "print(\n", " reboiler_scaler.get_sum_terms_nominal_values(\n", @@ -1694,22 +940,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Here, we see that, while the vapor phase fugacities are associated with a nominal value of 10000, the liquid phase fugacities have wildly different nominal values. We do expect the vapor phase to be enriched in $\\text{CO}_2$, but not by a factor of $2\\cdot 10^4$. Let's unpack these values. We are using the ideal gas law for the vapor phase, so the fugacity is simply the product of the mole fraction and vapor pressure:" + "Here, we see that, while the vapor phase fugacities are associated with a nominal value of `10000`, the liquid phase fugacities have wildly different nominal values. We do expect the vapor phase to be enriched in $\\text{CO}_2$, but not by a factor of $2\\cdot 10^4$. Let's unpack these values. We are using the ideal gas law for the vapor phase, so the fugacity is simply the product of the mole fraction and vapor pressure:" ] }, { "cell_type": "code", - "execution_count": 27, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]*fs.unit.vapor_phase[0.0].pressure\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "print_compact_form(m.fs.unit.vapor_phase[0.0].fug_phase_comp[\"Vap\", \"CO2\"])" ] @@ -1723,17 +961,9 @@ }, { "cell_type": "code", - "execution_count": 28, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,CO2]*(exp(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O])*log(244800.0*exp(-1348*K/fs.unit.liquid_phase.properties_out[0.0].temperature)*(3520000.0*exp(-2113*K/fs.unit.liquid_phase.properties_out[0.0].temperature)/(8449000.0*exp(-2283*K/fs.unit.liquid_phase.properties_out[0.0].temperature)))) + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O])*log(3520000.0*exp(-2113*K/fs.unit.liquid_phase.properties_out[0.0].temperature)) + fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O])*(fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]))*(fs.liquid_properties.CO2.lwm_coeff_1 + K**(-1)*fs.liquid_properties.CO2.lwm_coeff_2*(fs.unit.liquid_phase.properties_out[0.0].temperature - 273.15*K) + K**(-2)*fs.liquid_properties.CO2.lwm_coeff_3*(fs.unit.liquid_phase.properties_out[0.0].temperature - 273.15*K)**2 + fs.liquid_properties.CO2.lwm_coeff_4*(fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]/(fs.liquid_properties.MEA.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] + fs.liquid_properties.H2O.mw*fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]))))*Pa*m**3*mol**(-1))\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "print_compact_form(\n", " m.fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[\"Liq\", \"CO2\"]\n", @@ -1744,25 +974,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Parsing the entire pile of thermodynamic gibberish is unnecessary to plan our next move. We can plainly see that the liquid phase fugacity expression is rife with subtraction and exponentiation, both of which are dangerous for the nominal value expression walker. Even worse, we are scaling based on a failed solution, so the values may be off anyway. It is far better to base the scaling factor on the vapor phase fugacity. The `get_expression_nominal_value` function allows the user to get the nominal value of a single expression." + "Parsing the entire pile of thermodynamic gibberish is unnecessary to plan our next move. We can see that the liquid phase fugacity expression is rife with subtraction and exponentiation, both of which are dangerous for the nominal value expression walker. Even worse, we are scaling based on a failed solution, so the values may be off anyway. It is far better to base the scaling factor on the vapor phase fugacity. The `get_expression_nominal_value` function allows the user to get the nominal value of a single expression." ] }, { "cell_type": "code", - "execution_count": 29, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "10000.0" - ] - }, - "execution_count": 29, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "reboiler_scaler.get_expression_nominal_value(\n", " m.fs.unit.vapor_phase[0.0].fug_phase_comp[\"Vap\", \"CO2\"]\n", @@ -1780,17 +999,9 @@ }, { "cell_type": "code", - "execution_count": 30, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "fs.unit.liquid_phase.properties_out[0.0].pressure == fs.unit.vapor_phase[0.0].pressure\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "print_compact_form(m.fs.unit.unit_pressure_balance[0.0])" ] @@ -1806,51 +1017,9 @@ }, { "cell_type": "code", - "execution_count": 31, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Scaling Factors for block fs.unit\n", - "\n", - "Variable Scaling Factor Value Scaled Value\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol 1.250E-02 8.389E+01 1.049E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[H2O] 1.000E+01 8.589E-01 8.589E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[MEA] 1.000E+01 1.085E-01 1.085E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[CO2] 1.000E+01 3.260E-02 3.260E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].temperature 3.333E-03 3.925E+02 1.308E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol 1.250E-02 7.424E+01 9.279E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O] 1.000E+01 8.527E-01 8.527E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] 1.000E+01 1.226E-01 1.226E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[CO2] 1.000E+01 2.471E-02 2.471E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].temperature 3.333E-03 3.926E+02 1.309E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", - "fs.unit.vapor_phase[0.0].flow_mol 1.000E-01 9.654E+00 9.654E-01\n", - "fs.unit.vapor_phase[0.0].mole_frac_comp[CO2] 1.000E+01 9.329E-02 9.329E-01\n", - "fs.unit.vapor_phase[0.0].mole_frac_comp[H2O] 1.000E+01 9.067E-01 9.067E+00\n", - "fs.unit.vapor_phase[0.0].mole_frac_comp[N2] 1.000E+01 1.055E-09 1.055E-08\n", - "fs.unit.vapor_phase[0.0].mole_frac_comp[O2] 1.000E+01 1.055E-09 1.055E-08\n", - "fs.unit.vapor_phase[0.0].temperature 3.333E-03 3.926E+02 1.309E+00\n", - "fs.unit.vapor_phase[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", - "fs.unit.liquid_phase.heat[0.0] 5.077E-07 4.306E+05 2.186E-01\n", - "\n", - "Constraint Scaling Factor\n", - "fs.unit.unit_material_balance[0.0,CO2] None\n", - "fs.unit.unit_material_balance[0.0,H2O] None\n", - "fs.unit.unit_material_balance[0.0,N2] None\n", - "fs.unit.unit_material_balance[0.0,O2] None\n", - "fs.unit.unit_material_balance[0.0,MEA] None\n", - "fs.unit.unit_phase_equilibrium[0.0,CO2] None\n", - "fs.unit.unit_phase_equilibrium[0.0,H2O] None\n", - "fs.unit.unit_temperature_equality[0.0] None\n", - "fs.unit.unit_enthalpy_balance[0.0] None\n", - "fs.unit.unit_pressure_balance[0.0] None\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "from idaes.core.scaling.util import report_scaling_factors\n", "\n", @@ -1866,17 +1035,9 @@ }, { "cell_type": "code", - "execution_count": 32, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "fs.unit.liquid_phase.properties_out[0.0].temperature == fs.unit.vapor_phase[0.0].temperature\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "print_compact_form(m.fs.unit.unit_temperature_equality[0.0])" ] @@ -1892,28 +1053,12 @@ }, { "cell_type": "code", - "execution_count": 33, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "- fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,CO2] == fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,CO2]\n", - "\n", - "\n", - "fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,MEA] == 0*(mol*s**(-1))\n", - "\n", - "\n", - "fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,N2] == fs.unit.zero_flow_param\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "print_compact_form(m.fs.unit.unit_material_balance[0.0, \"CO2\"])\n", - "print(\"\\n\")\n", "print_compact_form(m.fs.unit.unit_material_balance[0.0, \"MEA\"])\n", - "print(\"\\n\")\n", "print_compact_form(m.fs.unit.unit_material_balance[0.0, \"N2\"])" ] }, @@ -1937,7 +1082,7 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -2019,53 +1164,26 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Now we can see how this works on the model. We'll pass `overwrite=True` config option when creating the scaler object to ensure we have up-to-date scaling factors." + "Now we can see how this works on the model. We will create a new instance of the model to demonstrate that the improved scaling is sufficient to allow the model to initialize without a custom-tailored initial guess." ] }, { "cell_type": "code", - "execution_count": 35, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Starting initialization routine\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Bubble, dew, and critical point initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Equilibrium temperature initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: State variable initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Phase equilibrium initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Property initialization routine finished.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Starting initialization routine\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Bubble, dew, and critical point initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Equilibrium temperature initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: State variable initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Phase equilibrium initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Property initialization routine finished.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: Starting initialization routine\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: Bubble, dew, and critical point initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: Equilibrium temperature initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: State variable initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: Phase equilibrium initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.vapor_phase: Property initialization routine finished.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit: Initialization Complete: optimal - \n" - ] - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 35, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ - "scaler_obj = SolventReboilerScaler(overwrite=True)\n", + "m = create_model()\n", + "\n", + "# Since this is a new instance of the model, we need to set the default\n", + "# scaler objects again.\n", + "m.fs.liquid_properties.default_state_scaler_object = liquid_properties_scaler\n", + "m.fs.vapor_properties.default_state_scaler_object = vapor_properties_scaler\n", + "\n", + "scaler_obj = SolventReboilerScaler()\n", "scaler_obj.scale_model(m.fs.unit)\n", + "\n", + "reboiler_init = m.fs.unit.default_initializer(always_estimate_states=True)\n", "reboiler_init.initialize(m.fs.unit)" ] }, @@ -2073,50 +1191,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "We see that scaling improved the model enough so that initialization could succeed. Now let's look at the numerical issues." + "We see that scaling improved the robustness of the model enough so that initialization could succeed. Now let's look at the numerical issues." ] }, { "cell_type": "code", - "execution_count": 36, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "====================================================================================\n", - "Model Statistics\n", - "\n", - " Jacobian Condition Number: 5.400E+06\n", - "\n", - "------------------------------------------------------------------------------------\n", - "0 WARNINGS\n", - "\n", - " No warnings found!\n", - "\n", - "------------------------------------------------------------------------------------\n", - "6 Cautions\n", - "\n", - " Caution: 9 Variables with value close to their bounds (abs=1.0E-04, rel=1.0E-04)\n", - " Caution: 14 Variables with value close to zero (tol=1.0E-08)\n", - " Caution: 27 Variables with extreme value (<1.0E-04 or >1.0E+04)\n", - " Caution: 2 Constraints with mismatched terms\n", - " Caution: 1 Constraint with potential cancellation of terms\n", - " Caution: 20 extreme Jacobian Entries (<1.0E-04 or >1.0E+04)\n", - "\n", - "------------------------------------------------------------------------------------\n", - "Suggested next steps:\n", - "\n", - " If you still have issues converging your model consider:\n", - "\n", - " prepare_degeneracy_hunter()\n", - " prepare_svd_toolbox()\n", - "\n", - "====================================================================================\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "dt = DiagnosticsToolbox(m)\n", "dt.report_numerical_issues()" @@ -2159,7 +1241,7 @@ "\n", "Because $\\mathbf{U}$ and $\\mathbf{V}$ are orthogonal and $\\mathbf{\\Sigma}$ is diagonal, computing a Newton step is easy once the SVD is calculated.\n", "$$\n", - "\\mathbf{\\delta x}_k = -\\mathbf{V \\Sigma^{-1} U}^T \\cdot \\mathbf{f}(\\mathbf{x}_k)\n", + "\\mathbf{\\delta x}_k = -\\mathbf{V \\Sigma}^{-1} \\mathbf{U}^T \\cdot \\mathbf{f}(\\mathbf{x}_k)\n", "$$\n", "Since we have to refactorize $\\mathbf{J}$ at each iteration, the SVD is not an efficient method to calculate a Newton step. However, this process has a geometric interpretation that is useful for model diagnostics and scaling. First, the constraint residual is decomposed into orthogonal components by $\\mathbf{U}$:\n", "$$\n", @@ -2167,7 +1249,7 @@ "$$\n", "Next, these orthogonal components are scaled by the inverse of the associated singular value:\n", "$$\n", - "\\mathbf{\\tilde{s}} = \\Sigma^{-1} \\cdot \\mathbf{s}\n", + "\\mathbf{\\tilde{s}} = \\mathbf{\\Sigma}^{-1} \\cdot \\mathbf{s}\n", "$$\n", "Finally, these independent components are translated into the variable space by $\\mathbf{V}$:\n", "$$\n", @@ -2178,163 +1260,20 @@ "
\n", "NOTE\n", "\n", - "The singular vectors $\\mathbf{u}_j$ and $\\mathbf{v}_j$ are typically dense. In order to link them with specific variables and constraints, a thresholding scheme is applied. The `size_cutoff_in_singular_vector` config option for the `SVDToolbox` controls the magnitude of an entry in $\\mathbf{u}_j$ and $\\mathbf{v}_j$ that is sufficient to link a variable or constraint to the $\\sigma_j$. It is `0.1` by default, but can take on values between about `0.05` and `0.3`. Decrease it to show fewer variables and constraints, increase it to show more variables and constraints.\n", + "The singular vectors $\\mathbf{u}_j$ and $\\mathbf{v}_j$ are typically dense. In order to link them with specific variables and constraints, a thresholding scheme is applied. The `size_cutoff_in_singular_vector` config option for the `SVDToolbox` controls the magnitude of an entry in $\\mathbf{u}_j$ and $\\mathbf{v}_j$ that is sufficient to link a variable or constraint to the $\\sigma_j$. It is `0.1` by default, but typically has a value between `0.05` and `0.3`. Decrease it to show fewer variables and constraints, increase it to show more variables and constraints.\n", "\n", "
\n", "\n", - "So let's create an instance of the `SVDToolbox` and display the variables and constraints associated with the 5 smallest singular values.\n" + "So let's create an instance of the `SVDToolbox` and display the variables and constraints associated with the 5 smallest singular values. (For a full description of all the methods available, look at the [SVD toolbox documentation](https://idaes-pse.readthedocs.io/en/latest/reference_guides/core/util/diagnostics/svd_toolbox.html#svd-toolbox).)\n" ] }, { "cell_type": "code", - "execution_count": 38, + "execution_count": null, "metadata": { "scrolled": true }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "====================================================================================\n", - "Constraints and Variables associated with smallest singular values\n", - "\n", - " 1st Smallest Singular Value: 6.356e-04\n", - "\n", - " Variables:\n", - "\n", - " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_comp[CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_comp[H2O]\n", - "\n", - " Constraints:\n", - "\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2]\n", - "\n", - " 2nd Smallest Singular Value: 2.781e-02\n", - "\n", - " Variables:\n", - "\n", - " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_comp[CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_comp[H2O]\n", - "\n", - " Constraints:\n", - "\n", - " fs.unit.unit_material_balance[0.0,CO2]\n", - " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", - "\n", - " 3rd Smallest Singular Value: 3.679e-02\n", - "\n", - " Variables:\n", - "\n", - " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_comp[CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_comp[H2O]\n", - "\n", - " Constraints:\n", - "\n", - " fs.unit.unit_material_balance[0.0,CO2]\n", - " fs.unit.liquid_phase.material_balances[0.0,MEA]\n", - " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", - " fs.unit.liquid_phase.enthalpy_balances[0.0]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", - " fs.unit.unit_material_balance[0.0,MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,HCO3_-]\n", - " fs.unit.vapor_phase[0.0].sum_mole_frac_out\n", - "\n", - " 4th Smallest Singular Value: 6.842e-02\n", - "\n", - " Variables:\n", - "\n", - " fs.unit.vapor_phase[0.0].flow_mol_phase[Vap]\n", - " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,H2O]\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]\n", - " fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,H2O]\n", - " fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,H2O]\n", - " fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,H2O]\n", - " fs.unit.vapor_phase[0.0].mole_frac_comp[H2O]\n", - " fs.unit.vapor_phase[0.0].flow_mol\n", - "\n", - " Constraints:\n", - "\n", - " fs.unit.unit_material_balance[0.0,CO2]\n", - " fs.unit.liquid_phase.material_balances[0.0,MEA]\n", - " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", - " fs.unit.liquid_phase.enthalpy_balances[0.0]\n", - " fs.unit.unit_material_balance[0.0,MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].total_flow_balance\n", - " fs.unit.vapor_phase[0.0].sum_mole_frac_out\n", - "\n", - " 5th Smallest Singular Value: 7.703e-02\n", - "\n", - " Variables:\n", - "\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,H2O]\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]\n", - " fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,H2O]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_k_eq[bicarbonate]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_k_eq[carbamate]\n", - "\n", - " Constraints:\n", - "\n", - " fs.unit.liquid_phase.material_balances[0.0,MEA]\n", - " fs.unit.unit_material_balance[0.0,MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].total_flow_balance\n", - " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[MEA]\n", - " fs.unit.liquid_phase.properties_out[0.0].sum_mole_frac_out\n", - "\n", - "====================================================================================\n" - ] - } - ], + "outputs": [], "source": [ "st = dt.prepare_svd_toolbox()\n", "# The SVD toolbox displays 10 singular values by default, but we are going to\n", @@ -2351,17 +1290,9 @@ }, { "cell_type": "code", - "execution_count": 40, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "exp(fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]) == fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,CO2]/(mol/m**3)\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "print_compact_form(\n", " m.fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[\n", @@ -2381,29 +1312,9 @@ }, { "cell_type": "code", - "execution_count": 41, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "====================================================================================\n", - "The following variables are involved in fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2]:\n", - "\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,H2O]: 4.333e-05\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,MEA]: 1.441e-04\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,CO2]: 6.126e-05\n", - " fs.unit.liquid_phase.properties_out[0.0].temperature: 1.576e-04\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O]: -5.255e-07\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA]: 5.123e-06\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,CO2]: -1.648e+00\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]: 5.621e-04\n", - "\n", - "====================================================================================\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "st.display_variables_in_constraint(\n", " m.fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[\n", @@ -2419,7 +1330,7 @@ "
\n", "NOTE\n", "\n", - "At this point of the process, the original author found a shortcoming in the `ModularPropertiesScaler`. No scaling hint was set for the molar density expression, so the expression walker descended into it and came back with an inappropriate nominal value. Revising the scaler to estimate the phase density resulted in a condition number improvement of 1-2 orders of magnitude.\n", + "At this point of the process, the author of this notebook found a shortcoming in the `ModularPropertiesScaler`. No scaling hint was set for the molar density expression, so the expression walker descended into it and came back with an inappropriate nominal value. Revising the scaler to estimate the phase density resulted in a condition number improvement of 1-2 orders of magnitude.\n", "\n", "Remember:\n", "1. Scaling is an iterative process.\n", @@ -2434,24 +1345,15 @@ }, { "cell_type": "code", - "execution_count": 42, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Left hand side value: 1.3698e+00\n", - "CO2 true concentration value: 1.3698e+00\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "print(\n", - " f\"Left hand side value: {value(exp(m.fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[\"Liq\",\"CO2\"])):.4e}\"\n", + " f\"Left hand side value: {value(exp(m.fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true['Liq','CO2'])):.4e}\"\n", ")\n", "print(\n", - " f\"CO2 true concentration value: {value(m.fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[\"Liq\",\"CO2\"]):.4e}\"\n", + " f\"CO2 true concentration value: {value(m.fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true['Liq','CO2']):.4e}\"\n", ")" ] }, @@ -2464,17 +1366,9 @@ }, { "cell_type": "code", - "execution_count": 44, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0.0004103666666666667\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "print(\n", " get_scaling_factor(\n", @@ -2498,24 +1392,15 @@ }, { "cell_type": "code", - "execution_count": 45, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True CO2 mole fraction: 3.410357e-05\n", - "True MEACOO- mole fraction: 2.796223e-02\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "print(\n", - " f\"True CO2 mole fraction: {m.fs.unit.liquid_phase.properties_out[0].mole_frac_phase_comp_true[\"Liq\",\"CO2\"].value:4e}\"\n", + " f\"True CO2 mole fraction: {m.fs.unit.liquid_phase.properties_out[0].mole_frac_phase_comp_true['Liq','CO2'].value:4e}\"\n", ")\n", "print(\n", - " f\"True MEACOO- mole fraction: {m.fs.unit.liquid_phase.properties_out[0].mole_frac_phase_comp_true[\"Liq\",\"MEACOO_-\"].value:4e}\"\n", + " f\"True MEACOO- mole fraction: {m.fs.unit.liquid_phase.properties_out[0].mole_frac_phase_comp_true['Liq','MEACOO_-'].value:4e}\"\n", ")" ] }, @@ -2528,7 +1413,7 @@ }, { "cell_type": "code", - "execution_count": 46, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -2558,66 +1443,11 @@ }, { "cell_type": "code", - "execution_count": 47, + "execution_count": null, "metadata": { "scrolled": true }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Starting initialization routine\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Bubble, dew, and critical point initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Equilibrium temperature initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: State variable initialization completed.\n", - "2026-04-29 17:11:57 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Phase equilibrium initialization completed.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_in: Property initialization routine finished.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Starting initialization routine\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Bubble, dew, and critical point initialization completed.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Equilibrium temperature initialization completed.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: State variable initialization completed.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Phase equilibrium initialization completed.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.liquid_phase.properties_out: Property initialization routine finished.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: Starting initialization routine\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: Bubble, dew, and critical point initialization completed.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: Equilibrium temperature initialization completed.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: State variable initialization completed.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: Phase equilibrium initialization completed.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit.vapor_phase: Property initialization routine finished.\n", - "2026-04-29 17:11:58 [INFO] idaes.init.fs.unit: Initialization Complete: optimal - \n", - "====================================================================================\n", - "Model Statistics\n", - "\n", - " Jacobian Condition Number: 2.945E+05\n", - "\n", - "------------------------------------------------------------------------------------\n", - "0 WARNINGS\n", - "\n", - " No warnings found!\n", - "\n", - "------------------------------------------------------------------------------------\n", - "6 Cautions\n", - "\n", - " Caution: 9 Variables with value close to their bounds (abs=1.0E-04, rel=1.0E-04)\n", - " Caution: 14 Variables with value close to zero (tol=1.0E-08)\n", - " Caution: 27 Variables with extreme value (<1.0E-04 or >1.0E+04)\n", - " Caution: 2 Constraints with mismatched terms\n", - " Caution: 1 Constraint with potential cancellation of terms\n", - " Caution: 16 extreme Jacobian Entries (<1.0E-04 or >1.0E+04)\n", - "\n", - "------------------------------------------------------------------------------------\n", - "Suggested next steps:\n", - "\n", - " If you still have issues converging your model consider:\n", - "\n", - " prepare_degeneracy_hunter()\n", - " prepare_svd_toolbox()\n", - "\n", - "====================================================================================\n" - ] - } - ], + "outputs": [], "source": [ "scaler_obj = SolventReboilerScaler(overwrite=True)\n", "scaler_obj.scale_model(m.fs.unit)\n", @@ -2635,173 +1465,16 @@ }, { "cell_type": "code", - "execution_count": 49, + "execution_count": null, "metadata": { "scrolled": true }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "====================================================================================\n", - "Constraints and Variables associated with smallest singular values\n", - "\n", - " 1st Smallest Singular Value: 6.965e-04\n", - "\n", - " Variables:\n", - "\n", - " fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[bicarbonate]\n", - " fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[carbamate]\n", - " fs.unit.liquid_phase.properties_out[0.0].apparent_inherent_reaction_extent[carbamate]\n", - "\n", - " Constraints:\n", - "\n", - " fs.unit.unit_material_balance[0.0,CO2]\n", - " fs.unit.unit_material_balance[0.0,H2O]\n", - " fs.unit.liquid_phase.material_balances[0.0,H2O]\n", - " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].total_flow_balance\n", - " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", - "\n", - " 2nd Smallest Singular Value: 1.047e-03\n", - "\n", - " Variables:\n", - "\n", - " fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[carbamate]\n", - " fs.unit.liquid_phase.properties_out[0.0].apparent_inherent_reaction_extent[carbamate]\n", - "\n", - " Constraints:\n", - "\n", - " fs.unit.unit_material_balance[0.0,CO2]\n", - " fs.unit.unit_material_balance[0.0,H2O]\n", - " fs.unit.liquid_phase.material_balances[0.0,H2O]\n", - " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEA_+]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA_+]\n", - "\n", - " 3rd Smallest Singular Value: 4.024e-03\n", - "\n", - " Variables:\n", - "\n", - " fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[bicarbonate]\n", - " fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[carbamate]\n", - "\n", - " Constraints:\n", - "\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,H2O]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,H2O]\n", - " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,H2O]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", - "\n", - " 4th Smallest Singular Value: 5.218e-03\n", - "\n", - " Variables:\n", - "\n", - " fs.unit.liquid_phase.properties_out[0.0].apparent_inherent_reaction_extent[bicarbonate]\n", - "\n", - " Constraints:\n", - "\n", - " fs.unit.unit_material_balance[0.0,CO2]\n", - " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,HCO3_-]\n", - "\n", - " 5th Smallest Singular Value: 5.115e-02\n", - "\n", - " Variables:\n", - "\n", - " fs.unit.vapor_phase[0.0].flow_mol_phase[Vap]\n", - " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O]\n", - " fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_comp[CO2]\n", - " fs.unit.vapor_phase[0.0].mole_frac_comp[H2O]\n", - " fs.unit.vapor_phase[0.0].flow_mol\n", - "\n", - " Constraints:\n", - "\n", - " fs.unit.unit_material_balance[0.0,CO2]\n", - " fs.unit.unit_material_balance[0.0,H2O]\n", - " fs.unit.liquid_phase.material_balances[0.0,H2O]\n", - " fs.unit.liquid_phase.material_balances[0.0,MEA]\n", - " fs.unit.liquid_phase.material_balances[0.0,CO2]\n", - " fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEA_+]\n", - " fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEA]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA_+]\n", - " fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA]\n", - " fs.unit.unit_material_balance[0.0,MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_in[0.0].total_flow_balance\n", - " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[MEA]\n", - " fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEACOO_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,HCO3_-]\n", - " fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA_+]\n", - " fs.unit.liquid_phase.properties_out[0.0].sum_mole_frac_out\n", - " fs.unit.vapor_phase[0.0].sum_mole_frac_out\n", - "\n", - "====================================================================================\n" - ] - } - ], + "outputs": [], "source": [ "st = dt.prepare_svd_toolbox()\n", "st.display_underdetermined_variables_and_constraints([1, 2, 3, 4, 5])" ] }, - { - "cell_type": "code", - "execution_count": 50, - "metadata": {}, - "outputs": [], - "source": [ - "assert st.s[0] == pytest.approx(6.965e-04, rel=1e-2)\n", - "assert st.s[3] == pytest.approx(5.218e-03, rel=1e-2)\n", - "assert st.s[4] == pytest.approx(5.115e-02, rel=1e-2)" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -2815,243 +1488,11 @@ }, { "cell_type": "code", - "execution_count": 51, + "execution_count": null, "metadata": { "scrolled": true }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Scaling Factors for block fs.unit\n", - "\n", - "Variable Scaling Factor Value Scaled Value\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol 1.250E-02 8.389E+01 1.049E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[H2O] 1.000E+00 8.589E-01 8.589E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[MEA] 1.000E+01 1.085E-01 1.085E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_comp[CO2] 1.000E+01 3.260E-02 3.260E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].temperature 3.333E-03 3.925E+02 1.308E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol 1.250E-02 7.410E+01 9.263E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[H2O] 1.000E+00 8.487E-01 8.487E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[MEA] 1.000E+01 1.228E-01 1.228E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_comp[CO2] 1.000E+01 2.851E-02 2.851E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].temperature 3.333E-03 3.938E+02 1.313E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", - "fs.unit.vapor_phase[0.0].flow_mol 1.000E-01 9.785E+00 9.785E-01\n", - "fs.unit.vapor_phase[0.0].mole_frac_comp[CO2] 1.000E+01 6.361E-02 6.361E-01\n", - "fs.unit.vapor_phase[0.0].mole_frac_comp[H2O] 1.000E+01 9.364E-01 9.364E+00\n", - "fs.unit.vapor_phase[0.0].mole_frac_comp[N2] 1.000E+01 1.022E-09 1.022E-08\n", - "fs.unit.vapor_phase[0.0].mole_frac_comp[O2] 1.000E+01 1.022E-09 1.022E-08\n", - "fs.unit.vapor_phase[0.0].temperature 3.333E-03 3.938E+02 1.313E+00\n", - "fs.unit.vapor_phase[0.0].pressure 1.000E-05 1.837E+05 1.837E+00\n", - "fs.unit.liquid_phase.heat[0.0] 8.763E-07 4.306E+05 3.773E-01\n", - "fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,H2O] 1.250E-02 -9.163E+00 -1.145E-01\n", - "fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,MEA] 1.250E-01 0.000E+00 0.000E+00\n", - "fs.unit.liquid_phase.mass_transfer_term[0.0,Liq,CO2] 1.250E-01 -6.224E-01 -7.780E-02\n", - "fs.unit.liquid_phase.enthalpy_transfer[0.0] 8.763E-07 -3.209E+04 -2.812E-02\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase[Liq] 1.250E-02 8.389E+01 1.049E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp[Liq,H2O] 1.000E+00 8.589E-01 8.589E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp[Liq,MEA] 1.000E+01 1.085E-01 1.085E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp[Liq,CO2] 1.000E+01 3.260E-02 3.260E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].phase_frac[Liq] 1.000E+00 1.000E+00 1.000E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,MEACOO_-] 1.250E-01 2.550E+00 3.187E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,HCO3_-] 1.250E+00 1.785E-01 2.231E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,MEA_+] 1.250E-01 2.728E+00 3.410E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,H2O] 1.250E-02 7.187E+01 8.984E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,MEA] 1.250E-01 3.825E+00 4.781E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp_true[Liq,CO2] 1.250E+02 6.803E-03 8.504E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,MEACOO_-] 1.000E+01 3.141E-02 3.141E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,HCO3_-] 1.000E+02 2.199E-03 2.199E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,MEA_+] 1.000E+01 3.361E-02 3.361E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,H2O] 1.000E+00 8.856E-01 8.856E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,MEA] 1.000E+01 4.712E-02 4.712E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].mole_frac_phase_comp_true[Liq,CO2] 1.000E+04 8.383E-05 8.383E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[bicarbonate] 1.250E+02 1.785E-01 2.231E+01\n", - "fs.unit.liquid_phase.properties_in[0.0].apparent_inherent_reaction_extent[carbamate] 1.250E+02 2.550E+00 3.187E+02\n", - "fs.unit.liquid_phase.properties_in[0.0].log_k_eq[bicarbonate] None -7.578E+00 -7.578E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].log_k_eq[carbamate] None -1.985E+00 -1.985E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-] 1.000E+00 7.168E+00 7.168E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-] 1.000E+00 4.509E+00 4.509E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+] 1.000E+00 7.236E+00 7.236E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,H2O] 1.000E+00 1.051E+01 1.051E+01\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,MEA] 1.000E+00 7.573E+00 7.573E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true[Liq,CO2] 1.000E+00 1.242E+00 1.242E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase[Liq] 1.250E-02 7.410E+01 9.263E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,H2O] 1.000E+00 8.487E-01 8.487E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,MEA] 1.000E+01 1.228E-01 1.228E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp[Liq,CO2] 1.000E+01 2.851E-02 2.851E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].phase_frac[Liq] 1.000E+00 1.000E+00 1.000E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,MEACOO_-] 1.250E-01 2.013E+00 2.516E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,HCO3_-] 1.250E+00 9.684E-02 1.210E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,MEA_+] 1.250E-01 2.110E+00 2.637E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,H2O] 1.250E-02 6.279E+01 7.849E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,MEA] 1.250E-01 4.979E+00 6.224E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp_true[Liq,CO2] 1.250E+02 2.455E-03 3.069E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,MEACOO_-] 1.000E+01 2.796E-02 2.796E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,HCO3_-] 1.000E+02 1.345E-03 1.345E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,MEA_+] 1.000E+01 2.931E-02 2.931E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,H2O] 1.000E+00 8.722E-01 8.722E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,MEA] 1.000E+01 6.916E-02 6.916E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].mole_frac_phase_comp_true[Liq,CO2] 1.000E+04 3.410E-05 3.410E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].apparent_inherent_reaction_extent[bicarbonate] 1.250E+02 9.684E-02 1.210E+01\n", - "fs.unit.liquid_phase.properties_out[0.0].apparent_inherent_reaction_extent[carbamate] 1.250E+02 2.013E+00 2.516E+02\n", - "fs.unit.liquid_phase.properties_out[0.0].log_k_eq[bicarbonate] None -7.648E+00 -7.648E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].log_k_eq[carbamate] None -2.079E+00 -2.079E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEACOO_-] 1.000E+00 7.024E+00 7.024E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,HCO3_-] 1.000E+00 3.989E+00 3.989E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA_+] 1.000E+00 7.071E+00 7.071E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,H2O] 1.000E+00 1.046E+01 1.046E+01\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,MEA] 1.000E+00 7.929E+00 7.929E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true[Liq,CO2] 1.000E+00 3.147E-01 3.147E-01\n", - "fs.unit.vapor_phase[0.0].flow_mol_phase[Vap] 1.000E-01 9.785E+00 9.785E-01\n", - "fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,CO2] 1.000E+01 6.361E-02 6.361E-01\n", - "fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,H2O] 1.000E+01 9.364E-01 9.364E+00\n", - "fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,N2] 1.000E+01 1.022E-09 1.022E-08\n", - "fs.unit.vapor_phase[0.0].mole_frac_phase_comp[Vap,O2] 1.000E+01 1.022E-09 1.022E-08\n", - "fs.unit.vapor_phase[0.0].phase_frac[Vap] 1.000E+00 1.000E+00 1.000E+00\n", - "\n", - "Constraint Scaling Factor\n", - "fs.unit.unit_material_balance[0.0,CO2] 1.250E-01\n", - "fs.unit.unit_material_balance[0.0,H2O] 1.250E-02\n", - "fs.unit.unit_material_balance[0.0,N2] 1.000E+00\n", - "fs.unit.unit_material_balance[0.0,O2] 1.000E+00\n", - "fs.unit.unit_material_balance[0.0,MEA] 1.250E-01\n", - "fs.unit.unit_phase_equilibrium[0.0,CO2] 1.000E-04\n", - "fs.unit.unit_phase_equilibrium[0.0,H2O] 1.000E-04\n", - "fs.unit.unit_temperature_equality[0.0] 3.333E-03\n", - "fs.unit.unit_enthalpy_balance[0.0] 5.463E-06\n", - "fs.unit.unit_pressure_balance[0.0] 1.000E-05\n", - "fs.unit.liquid_phase.material_balances[0.0,H2O] 1.250E-02\n", - "fs.unit.liquid_phase.material_balances[0.0,MEA] 1.250E-01\n", - "fs.unit.liquid_phase.material_balances[0.0,CO2] 1.250E-01\n", - "fs.unit.liquid_phase.enthalpy_balances[0.0] 8.763E-07\n", - "fs.unit.liquid_phase.pressure_balance[0.0] 1.000E-05\n", - "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEACOO_-] 1.250E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,HCO3_-] 1.250E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEA_+] 1.250E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,H2O] 1.250E-02\n", - "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,MEA] 1.250E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].appr_to_true_species[Liq,CO2] 1.250E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEACOO_-] 1.250E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,HCO3_-] 1.250E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEA_+] 1.250E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,H2O] 1.250E-02\n", - "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,MEA] 1.250E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].true_mole_frac_constraint[Liq,CO2] 1.250E+02\n", - "fs.unit.liquid_phase.properties_in[0.0].total_flow_balance 1.250E-02\n", - "fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[H2O] 1.000E+01\n", - "fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[MEA] 1.000E+01\n", - "fs.unit.liquid_phase.properties_in[0.0].component_flow_balances[CO2] 1.000E+01\n", - "fs.unit.liquid_phase.properties_in[0.0].phase_fraction_constraint[Liq] 1.000E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].log_k_eq_constraint[bicarbonate] None\n", - "fs.unit.liquid_phase.properties_in[0.0].log_k_eq_constraint[carbamate] None\n", - "fs.unit.liquid_phase.properties_in[0.0].inherent_equilibrium_constraint[bicarbonate] 1.000E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].inherent_equilibrium_constraint[carbamate] 1.000E+00\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-] 2.377E-04\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-] 2.377E-03\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA_+] 2.377E-04\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,H2O] 2.377E-05\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA] 2.377E-04\n", - "fs.unit.liquid_phase.properties_in[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2] 2.377E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEACOO_-] 1.250E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,HCO3_-] 1.250E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA_+] 1.250E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,H2O] 1.250E-02\n", - "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,MEA] 1.250E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].appr_to_true_species[Liq,CO2] 1.250E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEACOO_-] 1.250E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,HCO3_-] 1.250E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEA_+] 1.250E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,H2O] 1.250E-02\n", - "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,MEA] 1.250E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].true_mole_frac_constraint[Liq,CO2] 1.250E+02\n", - "fs.unit.liquid_phase.properties_out[0.0].sum_mole_frac_out 1.000E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].total_flow_balance 1.250E-02\n", - "fs.unit.liquid_phase.properties_out[0.0].component_flow_balances[H2O] 1.000E+01\n", - "fs.unit.liquid_phase.properties_out[0.0].component_flow_balances[MEA] 1.000E+01\n", - "fs.unit.liquid_phase.properties_out[0.0].component_flow_balances[CO2] 1.000E+01\n", - "fs.unit.liquid_phase.properties_out[0.0].phase_fraction_constraint[Liq] 1.000E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].log_k_eq_constraint[bicarbonate] None\n", - "fs.unit.liquid_phase.properties_out[0.0].log_k_eq_constraint[carbamate] None\n", - "fs.unit.liquid_phase.properties_out[0.0].inherent_equilibrium_constraint[bicarbonate] 1.000E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].inherent_equilibrium_constraint[carbamate] 1.000E+00\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEACOO_-] 2.377E-04\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,HCO3_-] 2.377E-03\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA_+] 2.377E-04\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,H2O] 2.377E-05\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,MEA] 2.377E-04\n", - "fs.unit.liquid_phase.properties_out[0.0].log_conc_mol_phase_comp_true_eq[Liq,CO2] 2.377E-01\n", - "fs.unit.vapor_phase[0.0].sum_mole_frac_out 1.000E+00\n", - "fs.unit.vapor_phase[0.0].total_flow_balance 1.000E-01\n", - "fs.unit.vapor_phase[0.0].component_flow_balances[CO2] 1.000E+01\n", - "fs.unit.vapor_phase[0.0].component_flow_balances[H2O] 1.000E+01\n", - "fs.unit.vapor_phase[0.0].component_flow_balances[N2] 1.000E+01\n", - "fs.unit.vapor_phase[0.0].component_flow_balances[O2] 1.000E+01\n", - "fs.unit.vapor_phase[0.0].phase_fraction_constraint[Vap] 1.000E+00\n", - "\n", - "Expression Scaling Hint\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp[Liq,H2O] 1.250E-02\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp[Liq,MEA] 1.250E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_phase_comp[Liq,CO2] 1.250E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].k_eq[bicarbonate] None\n", - "fs.unit.liquid_phase.properties_in[0.0].k_eq[carbamate] None\n", - "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,MEACOO_-] None\n", - "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,HCO3_-] None\n", - "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,MEA_+] None\n", - "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,H2O] None\n", - "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,MEA] None\n", - "fs.unit.liquid_phase.properties_in[0.0].conc_mol_phase_comp_true[Liq,CO2] None\n", - "fs.unit.liquid_phase.properties_in[0.0].dens_mol_phase[Liq] 2.377E-05\n", - "fs.unit.liquid_phase.properties_in[0.0].vol_mol_phase[Liq] 4.206E+04\n", - "fs.unit.liquid_phase.properties_in[0.0]._enthalpy_flow_term[Liq] None\n", - "fs.unit.liquid_phase.properties_in[0.0].enth_mol_phase[Liq] 7.010E-05\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_comp[H2O] 1.250E-02\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_comp[MEA] 1.250E-01\n", - "fs.unit.liquid_phase.properties_in[0.0].flow_mol_comp[CO2] 1.250E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp[Liq,H2O] 1.250E-02\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp[Liq,MEA] 1.250E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_phase_comp[Liq,CO2] 1.250E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].k_eq[bicarbonate] None\n", - "fs.unit.liquid_phase.properties_out[0.0].k_eq[carbamate] None\n", - "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,MEACOO_-] None\n", - "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,HCO3_-] None\n", - "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,MEA_+] None\n", - "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,H2O] None\n", - "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,MEA] None\n", - "fs.unit.liquid_phase.properties_out[0.0].conc_mol_phase_comp_true[Liq,CO2] None\n", - "fs.unit.liquid_phase.properties_out[0.0].dens_mol_phase[Liq] 2.377E-05\n", - "fs.unit.liquid_phase.properties_out[0.0].vol_mol_phase[Liq] 4.206E+04\n", - "fs.unit.liquid_phase.properties_out[0.0]._enthalpy_flow_term[Liq] None\n", - "fs.unit.liquid_phase.properties_out[0.0].enth_mol_phase[Liq] 7.010E-05\n", - "fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[Liq,H2O] None\n", - "fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[Liq,MEA] None\n", - "fs.unit.liquid_phase.properties_out[0.0].fug_phase_comp[Liq,CO2] None\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_comp[H2O] 1.250E-02\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_comp[MEA] 1.250E-01\n", - "fs.unit.liquid_phase.properties_out[0.0].flow_mol_comp[CO2] 1.250E-01\n", - "fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,CO2] 1.000E+00\n", - "fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,H2O] 1.000E+00\n", - "fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,N2] 1.000E+00\n", - "fs.unit.vapor_phase[0.0].flow_mol_phase_comp[Vap,O2] 1.000E+00\n", - "fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,CO2] None\n", - "fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,H2O] None\n", - "fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,N2] None\n", - "fs.unit.vapor_phase[0.0].fug_phase_comp[Vap,O2] None\n", - "fs.unit.vapor_phase[0.0]._enthalpy_flow_term[Vap] None\n", - "fs.unit.vapor_phase[0.0].enth_mol_phase[Vap] 5.463E-05\n", - "fs.unit.vapor_phase[0.0].enth_mol_phase_comp[Vap,CO2] 3.787E-05\n", - "fs.unit.vapor_phase[0.0].enth_mol_phase_comp[Vap,H2O] 9.249E-05\n", - "fs.unit.vapor_phase[0.0].enth_mol_phase_comp[Vap,N2] 5.950E-05\n", - "fs.unit.vapor_phase[0.0].enth_mol_phase_comp[Vap,O2] 5.208E-05\n", - "fs.unit.vapor_phase[0.0].flow_mol_comp[CO2] 1.000E+00\n", - "fs.unit.vapor_phase[0.0].flow_mol_comp[H2O] 1.000E+00\n", - "fs.unit.vapor_phase[0.0].flow_mol_comp[N2] 1.000E+00\n", - "fs.unit.vapor_phase[0.0].flow_mol_comp[O2] 1.000E+00\n" - ] - } - ], + "outputs": [], "source": [ "from idaes.core.scaling.util import report_scaling_factors\n", "\n", @@ -3062,7 +1503,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Most variable values have scaled values within a couple orders of magnitude of one, which is what we like. The outliers are inherent reaction extents, which we already know are a bit problematic, and variables corresponding to the components $\\text{N}_2$ and $\\text{O}_2$, which are present in the vapor property package but not the vapor stream.\n", + "Most variable values have scaled values within a couple orders of magnitude of one, which is what we like. The outliers are inherent reaction extents, which we already know are a bit problematic, and variables corresponding to the components $\\text{N}_2$ and $\\text{O}_2$. Because those components are present in the vapor property package but not the vapor stream, they should not be scaled to order one, and their current scaling factors are fine.\n", "\n", "We have reduced the condition number to $3 \\cdot 10^5$, which is not quite as low as we would have liked, but is a vast improvement over the value $3 \\cdot 10^{13}$, which we started out with. " ] @@ -3102,7 +1543,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.12" + "version": "3.10.20" } }, "nbformat": 4, From 5c97d47f994376f38fd03e8f7e4f91eda582dcf2 Mon Sep 17 00:00:00 2001 From: Doug A Date: Thu, 30 Apr 2026 14:07:01 -0400 Subject: [PATCH 7/7] commit json --- .../advanced_scaling_failed_solution.json | 4777 +++++++++++++++++ 1 file changed, 4777 insertions(+) create mode 100644 idaes_examples/notebooks/docs/scaling/advanced_scaling_failed_solution.json diff --git a/idaes_examples/notebooks/docs/scaling/advanced_scaling_failed_solution.json b/idaes_examples/notebooks/docs/scaling/advanced_scaling_failed_solution.json new file mode 100644 index 00000000..0492c327 --- /dev/null +++ b/idaes_examples/notebooks/docs/scaling/advanced_scaling_failed_solution.json @@ -0,0 +1,4777 @@ +{ + "__metadata__": { + "format_version": 4, + "date": "2026-04-30", + "time": "11:38:52.226640", + "other": {}, + "__performance__": { + "n_components": 686, + "etime_make_dict": 0.0 + } + }, + "unknown": { + "__type__": "", + "__id__": 0, + "active": true, + "data": { + "None": { + "__type__": "", + "__id__": 1, + "active": true, + "__pyomo_components__": { + "fs": { + "__type__": "", + "__id__": 2, + "active": true, + "data": { + "None": { + "__type__": "", + "__id__": 3, + "active": true, + "__pyomo_components__": { + "liquid_properties": { + "__type__": "", + "__id__": 4, + "active": true, + "data": { + "None": { + "__type__": "", + "__id__": 5, + "active": true, + "__pyomo_components__": { + "Liq": { + "__type__": "", + "__id__": 6, + "active": true, + "data": { + "None": { + "__type__": "", + "__id__": 7, + "active": true, + "__pyomo_components__": { + "surf_tens_H2O_coeff_1": { + "__type__": "", + "__id__": 8, + "data": { + "None": { + "__type__": "", + "__id__": 9, + "fixed": true, + "stale": true, + "value": 0.18548, + "lb": null, + "ub": null + } + } + }, + "surf_tens_H2O_coeff_2": { + "__type__": "", + "__id__": 10, + "data": { + "None": { + "__type__": "", + "__id__": 11, + "fixed": true, + "stale": true, + "value": 2.717, + "lb": null, + "ub": null + } + } + }, + "surf_tens_H2O_coeff_3": { + "__type__": "", + "__id__": 12, + "data": { + "None": { + "__type__": "", + "__id__": 13, + "fixed": true, + "stale": true, + "value": -3.554, + "lb": null, + "ub": null + } + } + }, + "surf_tens_H2O_coeff_4": { + "__type__": "", + "__id__": 14, + "data": { + "None": { + "__type__": "", + "__id__": 15, + "fixed": true, + "stale": true, + "value": 2.047, + "lb": null, + "ub": null + } + } + }, + "surf_tens_MEA_coeff_1": { + "__type__": "", + "__id__": 16, + "data": { + "None": { + "__type__": "", + "__id__": 17, + "fixed": true, + "stale": true, + "value": 0.09945, + "lb": null, + "ub": null + } + } + }, + "surf_tens_MEA_coeff_2": { + "__type__": "", + "__id__": 18, + "data": { + "None": { + "__type__": "", + "__id__": 19, + "fixed": true, + "stale": true, + "value": 1.067, + "lb": null, + "ub": null + } + } + }, + "surf_tens_MEA_coeff_3": { + "__type__": "", + "__id__": 20, + "data": { + "None": { + "__type__": "", + "__id__": 21, + "fixed": true, + "stale": true, + "value": 0.0, + "lb": null, + "ub": null + } + } + }, + "surf_tens_MEA_coeff_4": { + "__type__": "", + "__id__": 22, + "data": { + "None": { + "__type__": "", + "__id__": 23, + "fixed": true, + "stale": true, + "value": 0.0, + "lb": null, + "ub": null + } + } + }, + "surf_tens_CO2_coeff_1": { + "__type__": "", + "__id__": 24, + "data": { + "None": { + "__type__": "", + "__id__": 25, + "fixed": true, + "stale": true, + "value": -5.987, + "lb": null, + "ub": null + } + } + }, + "surf_tens_CO2_coeff_2": { + "__type__": "", + "__id__": 26, + "data": { + "None": { + "__type__": "", + "__id__": 27, + "fixed": true, + "stale": true, + "value": 3.7699, + "lb": null, + "ub": null + } + } + }, + "surf_tens_CO2_coeff_3": { + "__type__": "", + "__id__": 28, + "data": { + "None": { + "__type__": "", + "__id__": 29, + "fixed": true, + "stale": true, + "value": -0.43164, + "lb": null, + "ub": null + } + } + }, + "surf_tens_CO2_coeff_4": { + "__type__": "", + "__id__": 30, + "data": { + "None": { + "__type__": "", + "__id__": 31, + "fixed": true, + "stale": true, + "value": 0.018155, + "lb": null, + "ub": null + } + } + }, + "surf_tens_CO2_coeff_5": { + "__type__": "", + "__id__": 32, + "data": { + "None": { + "__type__": "", + "__id__": 33, + "fixed": true, + "stale": true, + "value": -0.01207, + "lb": null, + "ub": null + } + } + }, + "surf_tens_CO2_coeff_6": { + "__type__": "", + "__id__": 34, + "data": { + "None": { + "__type__": "", + "__id__": 35, + "fixed": true, + "stale": true, + "value": 0.002119, + "lb": null, + "ub": null + } + } + }, + "surf_tens_F_coeff_a": { + "__type__": "", + "__id__": 36, + "data": { + "None": { + "__type__": "", + "__id__": 37, + "fixed": true, + "stale": true, + "value": 2.4558, + "lb": null, + "ub": null + } + } + }, + "surf_tens_F_coeff_b": { + "__type__": "", + "__id__": 38, + "data": { + "None": { + "__type__": "", + "__id__": 39, + "fixed": true, + "stale": true, + "value": -1.5311, + "lb": null, + "ub": null + } + } + }, + "surf_tens_F_coeff_c": { + "__type__": "", + "__id__": 40, + "data": { + "None": { + "__type__": "", + "__id__": 41, + "fixed": true, + "stale": true, + "value": 3.4994, + "lb": null, + "ub": null + } + } + }, + "surf_tens_F_coeff_d": { + "__type__": "", + "__id__": 42, + "data": { + "None": { + "__type__": "", + "__id__": 43, + "fixed": true, + "stale": true, + "value": -5.6398, + "lb": null, + "ub": null + } + } + }, + "surf_tens_F_coeff_e": { + "__type__": "", + "__id__": 44, + "data": { + "None": { + "__type__": "", + "__id__": 45, + "fixed": true, + "stale": true, + "value": 10.2109, + "lb": null, + "ub": null + } + } + }, + "surf_tens_F_coeff_f": { + "__type__": "", + "__id__": 46, + "data": { + "None": { + "__type__": "", + "__id__": 47, + "fixed": true, + "stale": true, + "value": 2.3122, + "lb": null, + "ub": null + } + } + }, + "surf_tens_F_coeff_g": { + "__type__": "", + "__id__": 48, + "data": { + "None": { + "__type__": "", + "__id__": 49, + "fixed": true, + "stale": true, + "value": 4.5608, + "lb": null, + "ub": null + } + } + }, + "surf_tens_F_coeff_h": { + "__type__": "", + "__id__": 50, + "data": { + "None": { + "__type__": "", + "__id__": 51, + "fixed": true, + "stale": true, + "value": -2.3924, + "lb": null, + "ub": null + } + } + }, + "surf_tens_F_coeff_i": { + "__type__": "", + "__id__": 52, + "data": { + "None": { + "__type__": "", + "__id__": 53, + "fixed": true, + "stale": true, + "value": 5.3324, + "lb": null, + "ub": null + } + } + }, + "surf_tens_F_coeff_j": { + "__type__": "", + "__id__": 54, + "data": { + "None": { + "__type__": "", + "__id__": 55, + "fixed": true, + "stale": true, + "value": -12.0494, + "lb": null, + "ub": null + } + } + }, + "visc_d_coeff_a": { + "__type__": "", + "__id__": 56, + "data": { + "None": { + "__type__": "", + "__id__": 57, + "fixed": true, + "stale": true, + "value": -0.0838, + "lb": null, + "ub": null + } + } + }, + "visc_d_coeff_b": { + "__type__": "", + "__id__": 58, + "data": { + "None": { + "__type__": "", + "__id__": 59, + "fixed": true, + "stale": true, + "value": 2.8817, + "lb": null, + "ub": null + } + } + }, + "visc_d_coeff_c": { + "__type__": "", + "__id__": 60, + "data": { + "None": { + "__type__": "", + "__id__": 61, + "fixed": true, + "stale": true, + "value": 33.651, + "lb": null, + "ub": null + } + } + }, + "visc_d_coeff_d": { + "__type__": "", + "__id__": 62, + "data": { + "None": { + "__type__": "", + "__id__": 63, + "fixed": true, + "stale": true, + "value": 1817.0, + "lb": null, + "ub": null + } + } + }, + "visc_d_coeff_e": { + "__type__": "", + "__id__": 64, + "data": { + "None": { + "__type__": "", + "__id__": 65, + "fixed": true, + "stale": true, + "value": 0.00847, + "lb": null, + "ub": null + } + } + }, + "visc_d_coeff_f": { + "__type__": "", + "__id__": 66, + "data": { + "None": { + "__type__": "", + "__id__": 67, + "fixed": true, + "stale": true, + "value": 0.0103, + "lb": null, + "ub": null + } + } + }, + "visc_d_coeff_g": { + "__type__": "", + "__id__": 68, + "data": { + "None": { + "__type__": "", + "__id__": 69, + "fixed": true, + "stale": true, + "value": -2.389, + "lb": null, + "ub": null + } + } + } + } + } + } + }, + "H2O": { + "__type__": "", + "__id__": 70, + "active": true, + "data": { + "None": { + "__type__": "", + "__id__": 71, + "active": true, + "__pyomo_components__": { + "mw": { + "__type__": "", + "__id__": 72, + "_mutable": true, + "data": { + "None": { + "__type__": "", + "__id__": 73, + "value": 0.01802 + } + } + }, + "temperature_crit": { + "__type__": "", + "__id__": 74, + "data": { + "None": { + "__type__": "", + "__id__": 75, + "fixed": true, + "stale": true, + "value": 647.13, + "lb": null, + "ub": null + } + } + }, + "dens_mol_liq_comp_coeff_1": { + "__type__": "", + "__id__": 76, + "data": { + "None": { + "__type__": "", + "__id__": 77, + "fixed": true, + "stale": true, + "value": -3.2484e-06, + "lb": null, + "ub": null + } + } + }, + "dens_mol_liq_comp_coeff_2": { + "__type__": "", + "__id__": 78, + "data": { + "None": { + "__type__": "", + "__id__": 79, + "fixed": true, + "stale": true, + "value": 0.00165, + "lb": null, + "ub": null + } + } + }, + "dens_mol_liq_comp_coeff_3": { + "__type__": "", + "__id__": 80, + "data": { + "None": { + "__type__": "", + "__id__": 81, + "fixed": true, + "stale": true, + "value": 0.793, + "lb": null, + "ub": null + } + } + }, + "cp_mass_liq_comp_coeff_1": { + "__type__": "", + "__id__": 82, + "data": { + "None": { + "__type__": "", + "__id__": 83, + "fixed": true, + "stale": true, + "value": 4.2107, + "lb": null, + "ub": null + } + } + }, + "cp_mass_liq_comp_coeff_2": { + "__type__": "", + "__id__": 84, + "data": { + "None": { + "__type__": "", + "__id__": 85, + "fixed": true, + "stale": true, + "value": -0.001696, + "lb": null, + "ub": null + } + } + }, + "cp_mass_liq_comp_coeff_3": { + "__type__": "", + "__id__": 86, + "data": { + "None": { + "__type__": "", + "__id__": 87, + "fixed": true, + "stale": true, + "value": 2.568e-05, + "lb": null, + "ub": null + } + } + }, + "cp_mass_liq_comp_coeff_4": { + "__type__": "", + "__id__": 88, + "data": { + "None": { + "__type__": "", + "__id__": 89, + "fixed": true, + "stale": true, + "value": -1.095e-07, + "lb": null, + "ub": null + } + } + }, + "cp_mass_liq_comp_coeff_5": { + "__type__": "", + "__id__": 90, + "data": { + "None": { + "__type__": "", + "__id__": 91, + "fixed": true, + "stale": true, + "value": 3.038e-10, + "lb": null, + "ub": null + } + } + }, + "dh_vap": { + "__type__": "", + "__id__": 92, + "data": { + "None": { + "__type__": "", + "__id__": 93, + "fixed": true, + "stale": true, + "value": 43990.0, + "lb": null, + "ub": null + } + } + }, + "pressure_sat_comp_coeff_1": { + "__type__": "", + "__id__": 94, + "data": { + "None": { + "__type__": "", + "__id__": 95, + "fixed": true, + "stale": true, + "value": 72.55, + "lb": null, + "ub": null + } + } + }, + "pressure_sat_comp_coeff_2": { + "__type__": "", + "__id__": 96, + "data": { + "None": { + "__type__": "", + "__id__": 97, + "fixed": true, + "stale": true, + "value": -7206.7, + "lb": null, + "ub": null + } + } + }, + "pressure_sat_comp_coeff_3": { + "__type__": "", + "__id__": 98, + "data": { + "None": { + "__type__": "", + "__id__": 99, + "fixed": true, + "stale": true, + "value": -7.1385, + "lb": null, + "ub": null + } + } + }, + "pressure_sat_comp_coeff_4": { + "__type__": "", + "__id__": 100, + "data": { + "None": { + "__type__": "", + "__id__": 101, + "fixed": true, + "stale": true, + "value": 4.05e-06, + "lb": null, + "ub": null + } + } + } + } + } + } + }, + "MEA": { + "__type__": "", + "__id__": 102, + "active": true, + "data": { + "None": { + "__type__": "", + "__id__": 103, + "active": true, + "__pyomo_components__": { + "mw": { + "__type__": "", + "__id__": 104, + "_mutable": true, + "data": { + "None": { + "__type__": "", + "__id__": 105, + "value": 0.06108 + } + } + }, + "temperature_crit": { + "__type__": "", + "__id__": 106, + "data": { + "None": { + "__type__": "", + "__id__": 107, + "fixed": true, + "stale": true, + "value": 614.45, + "lb": null, + "ub": null + } + } + }, + "dens_mol_liq_comp_coeff_1": { + "__type__": "", + "__id__": 108, + "data": { + "None": { + "__type__": "", + "__id__": 109, + "fixed": true, + "stale": true, + "value": -5.35162e-07, + "lb": null, + "ub": null + } + } + }, + "dens_mol_liq_comp_coeff_2": { + "__type__": "", + "__id__": 110, + "data": { + "None": { + "__type__": "", + "__id__": 111, + "fixed": true, + "stale": true, + "value": -0.000451417, + "lb": null, + "ub": null + } + } + }, + "dens_mol_liq_comp_coeff_3": { + "__type__": "", + "__id__": 112, + "data": { + "None": { + "__type__": "", + "__id__": 113, + "fixed": true, + "stale": true, + "value": 1.19451, + "lb": null, + "ub": null + } + } + }, + "vol_mol_liq_comp_coeff_b": { + "__type__": "", + "__id__": 114, + "data": { + "None": { + "__type__": "", + "__id__": 115, + "fixed": true, + "stale": true, + "value": -2.2642, + "lb": null, + "ub": null + } + } + }, + "vol_mol_liq_comp_coeff_c": { + "__type__": "", + "__id__": 116, + "data": { + "None": { + "__type__": "", + "__id__": 117, + "fixed": true, + "stale": true, + "value": 3.0059, + "lb": null, + "ub": null + } + } + }, + "cp_mass_liq_comp_coeff_1": { + "__type__": "", + "__id__": 118, + "data": { + "None": { + "__type__": "", + "__id__": 119, + "fixed": true, + "stale": true, + "value": 2.6161, + "lb": null, + "ub": null + } + } + }, + "cp_mass_liq_comp_coeff_2": { + "__type__": "", + "__id__": 120, + "data": { + "None": { + "__type__": "", + "__id__": 121, + "fixed": true, + "stale": true, + "value": 0.003706, + "lb": null, + "ub": null + } + } + }, + "cp_mass_liq_comp_coeff_3": { + "__type__": "", + "__id__": 122, + "data": { + "None": { + "__type__": "", + "__id__": 123, + "fixed": true, + "stale": true, + "value": 3.787e-06, + "lb": null, + "ub": null + } + } + }, + "cp_mass_liq_comp_coeff_4": { + "__type__": "", + "__id__": 124, + "data": { + "None": { + "__type__": "", + "__id__": 125, + "fixed": true, + "stale": true, + "value": 0.0, + "lb": null, + "ub": null + } + } + }, + "cp_mass_liq_comp_coeff_5": { + "__type__": "", + "__id__": 126, + "data": { + "None": { + "__type__": "", + "__id__": 127, + "fixed": true, + "stale": true, + "value": 0.0, + "lb": null, + "ub": null + } + } + }, + "dh_vap": { + "__type__": "", + "__id__": 128, + "data": { + "None": { + "__type__": "", + "__id__": 129, + "fixed": true, + "stale": true, + "value": 58000, + "lb": null, + "ub": null + } + } + }, + "pressure_sat_comp_coeff_1": { + "__type__": "", + "__id__": 130, + "data": { + "None": { + "__type__": "", + "__id__": 131, + "fixed": true, + "stale": true, + "value": 172.78, + "lb": null, + "ub": null + } + } + }, + "pressure_sat_comp_coeff_2": { + "__type__": "", + "__id__": 132, + "data": { + "None": { + "__type__": "", + "__id__": 133, + "fixed": true, + "stale": true, + "value": -13492, + "lb": null, + "ub": null + } + } + }, + "pressure_sat_comp_coeff_3": { + "__type__": "", + "__id__": 134, + "data": { + "None": { + "__type__": "", + "__id__": 135, + "fixed": true, + "stale": true, + "value": -21.914, + "lb": null, + "ub": null + } + } + }, + "pressure_sat_comp_coeff_4": { + "__type__": "", + "__id__": 136, + "data": { + "None": { + "__type__": "", + "__id__": 137, + "fixed": true, + "stale": true, + "value": 1.38e-05, + "lb": null, + "ub": null + } + } + }, + "diffus_phase_comp_coeff_1": { + "__type__": "", + "__id__": 138, + "data": { + "None": { + "__type__": "", + "__id__": 139, + "fixed": true, + "stale": true, + "value": -13.275, + "lb": null, + "ub": null + } + } + }, + "diffus_phase_comp_coeff_2": { + "__type__": "", + "__id__": 140, + "data": { + "None": { + "__type__": "", + "__id__": 141, + "fixed": true, + "stale": true, + "value": -2198.3, + "lb": null, + "ub": null + } + } + }, + "diffus_phase_comp_coeff_3": { + "__type__": "", + "__id__": 142, + "data": { + "None": { + "__type__": "", + "__id__": 143, + "fixed": true, + "stale": true, + "value": -7.8142e-05, + "lb": null, + "ub": null + } + } + } + } + } + } + }, + "CO2": { + "__type__": "", + "__id__": 144, + "active": true, + "data": { + "None": { + "__type__": "", + "__id__": 145, + "active": true, + "__pyomo_components__": { + "mw": { + "__type__": "", + "__id__": 146, + "_mutable": true, + "data": { + "None": { + "__type__": "", + "__id__": 147, + "value": 0.04401 + } + } + }, + "vol_mol_liq_comp_coeff_a": { + "__type__": "", + "__id__": 148, + "data": { + "None": { + "__type__": "", + "__id__": 149, + "fixed": true, + "stale": true, + "value": 10.2074, + "lb": null, + "ub": null + } + } + }, + "vol_mol_liq_comp_coeff_d": { + "__type__": "", + "__id__": 150, + "data": { + "None": { + "__type__": "", + "__id__": 151, + "fixed": true, + "stale": true, + "value": 207.0, + "lb": null, + "ub": null + } + } + }, + "vol_mol_liq_comp_coeff_e": { + "__type__": "", + "__id__": 152, + "data": { + "None": { + "__type__": "", + "__id__": 153, + "fixed": true, + "stale": true, + "value": -563.3701, + "lb": null, + "ub": null + } + } + }, + "dh_abs_co2": { + "__type__": "", + "__id__": 154, + "data": { + "None": { + "__type__": "", + "__id__": 155, + "fixed": true, + "stale": true, + "value": -84000, + "lb": null, + "ub": null + } + } + }, + "lwm_coeff_1": { + "__type__": "", + "__id__": 156, + "data": { + "None": { + "__type__": "", + "__id__": 157, + "fixed": true, + "stale": true, + "value": 1.70981, + "lb": null, + "ub": null + } + } + }, + "lwm_coeff_2": { + "__type__": "", + "__id__": 158, + "data": { + "None": { + "__type__": "", + "__id__": 159, + "fixed": true, + "stale": true, + "value": 0.03972, + "lb": null, + "ub": null + } + } + }, + "lwm_coeff_3": { + "__type__": "", + "__id__": 160, + "data": { + "None": { + "__type__": "", + "__id__": 161, + "fixed": true, + "stale": true, + "value": -0.00043, + "lb": null, + "ub": null + } + } + }, + "lwm_coeff_4": { + "__type__": "", + "__id__": 162, + "data": { + "None": { + "__type__": "", + "__id__": 163, + "fixed": true, + "stale": true, + "value": -2.20377, + "lb": null, + "ub": null + } + } + }, + "diffus_phase_comp_coeff_1": { + "__type__": "", + "__id__": 164, + "data": { + "None": { + "__type__": "", + "__id__": 165, + "fixed": true, + "stale": true, + "value": 2.35e-06, + "lb": null, + "ub": null + } + } + }, + "diffus_phase_comp_coeff_2": { + "__type__": "", + "__id__": 166, + "data": { + "None": { + "__type__": "", + "__id__": 167, + "fixed": true, + "stale": true, + "value": 2.9837e-08, + "lb": null, + "ub": null + } + } + }, + "diffus_phase_comp_coeff_3": { + "__type__": "", + "__id__": 168, + "data": { + "None": { + "__type__": "", + "__id__": 169, + "fixed": true, + "stale": true, + "value": -9.7078e-09, + "lb": null, + "ub": null + } + } + }, + "diffus_phase_comp_coeff_4": { + "__type__": "", + "__id__": 170, + "data": { + "None": { + "__type__": "", + "__id__": 171, + "fixed": true, + "stale": true, + "value": -2119, + "lb": null, + "ub": null + } + } + }, + "diffus_phase_comp_coeff_5": { + "__type__": "", + "__id__": 172, + "data": { + "None": { + "__type__": "", + "__id__": 173, + "fixed": true, + "stale": true, + "value": -20.132, + "lb": null, + "ub": null + } + } + } + } + } + } + }, + "MEA_+": { + "__type__": "", + "__id__": 174, + "active": true, + "data": { + "None": { + "__type__": "", + "__id__": 175, + "active": true, + "__pyomo_components__": { + "diffus_phase_comp_coeff_1": { + "__type__": "", + "__id__": 176, + "data": { + "None": { + "__type__": "", + "__id__": 177, + "fixed": true, + "stale": true, + "value": -22.64, + "lb": null, + "ub": null + } + } + }, + "diffus_phase_comp_coeff_2": { + "__type__": "", + "__id__": 178, + "data": { + "None": { + "__type__": "", + "__id__": 179, + "fixed": true, + "stale": true, + "value": -1000.0, + "lb": null, + "ub": null + } + } + }, + "diffus_phase_comp_coeff_3": { + "__type__": "", + "__id__": 180, + "data": { + "None": { + "__type__": "", + "__id__": 181, + "fixed": true, + "stale": true, + "value": -0.7, + "lb": null, + "ub": null + } + } + } + } + } + } + }, + "MEACOO_-": { + "__type__": "", + "__id__": 182, + "active": true, + "data": { + "None": { + "__type__": "", + "__id__": 183, + "active": true, + "__pyomo_components__": { + "diffus_phase_comp_coeff_1": { + "__type__": "", + "__id__": 184, + "data": { + "None": { + "__type__": "", + "__id__": 185, + "fixed": true, + "stale": true, + "value": -22.64, + "lb": null, + "ub": null + } + } + }, + "diffus_phase_comp_coeff_2": { + "__type__": "", + "__id__": 186, + "data": { + "None": { + "__type__": "", + "__id__": 187, + "fixed": true, + "stale": true, + "value": -1000.0, + "lb": null, + "ub": null + } + } + }, + "diffus_phase_comp_coeff_3": { + "__type__": "", + "__id__": 188, + "data": { + "None": { + "__type__": "", + "__id__": 189, + "fixed": true, + "stale": true, + "value": -0.7, + "lb": null, + "ub": null + } + } + } + } + } + } + }, + "HCO3_-": { + "__type__": "", + "__id__": 190, + "active": true, + "data": { + "None": { + "__type__": "", + "__id__": 191, + "active": true + } + } + }, + "pressure_ref": { + "__type__": "", + "__id__": 192, + "_mutable": true, + "data": { + "None": { + "__type__": "", + "__id__": 193, + "value": 101325.0 + } + } + }, + "temperature_ref": { + "__type__": "", + "__id__": 194, + "_mutable": true, + "data": { + "None": { + "__type__": "", + "__id__": 195, + "value": 298.15 + } + } + }, + "reaction_bicarbonate": { + "__type__": "", + "__id__": 196, + "active": true, + "data": { + "None": { + "__type__": "", + "__id__": 197, + "active": true, + "__pyomo_components__": { + "reaction_order": { + "__type__": "", + "__id__": 198, + "data": { + "('Liq', 'MEACOO_-')": { + "__type__": "", + "__id__": 199, + "fixed": true, + "stale": true, + "value": 0, + "lb": null, + "ub": null + }, + "('Liq', 'HCO3_-')": { + "__type__": "", + "__id__": 200, + "fixed": true, + "stale": true, + "value": 1, + "lb": null, + "ub": null + }, + "('Liq', 'MEA_+')": { + "__type__": "", + "__id__": 201, + "fixed": true, + "stale": true, + "value": 1, + "lb": null, + "ub": null + }, + "('Liq', 'H2O')": { + "__type__": "", + "__id__": 202, + "fixed": true, + "stale": true, + "value": -1, + "lb": null, + "ub": null + }, + "('Liq', 'MEA')": { + "__type__": "", + "__id__": 203, + "fixed": true, + "stale": true, + "value": -1, + "lb": null, + "ub": null + }, + "('Liq', 'CO2')": { + "__type__": "", + "__id__": 204, + "fixed": true, + "stale": true, + "value": -1, + "lb": null, + "ub": null + } + } + }, + "k_eq_coeff_1": { + "__type__": "", + "__id__": 205, + "data": { + "None": { + "__type__": "", + "__id__": 206, + "fixed": true, + "stale": true, + "value": 176.72, + "lb": null, + "ub": null + } + } + }, + "k_eq_coeff_2": { + "__type__": "", + "__id__": 207, + "data": { + "None": { + "__type__": "", + "__id__": 208, + "fixed": true, + "stale": true, + "value": -2909, + "lb": null, + "ub": null + } + } + }, + "k_eq_coeff_3": { + "__type__": "", + "__id__": 209, + "data": { + "None": { + "__type__": "", + "__id__": 210, + "fixed": true, + "stale": true, + "value": -28.46, + "lb": null, + "ub": null + } + } + } + } + } + } + }, + "reaction_carbamate": { + "__type__": "", + "__id__": 211, + "active": true, + "data": { + "None": { + "__type__": "", + "__id__": 212, + "active": true, + "__pyomo_components__": { + "reaction_order": { + "__type__": "", + "__id__": 213, + "data": { + "('Liq', 'MEACOO_-')": { + "__type__": "", + "__id__": 214, + "fixed": true, + "stale": true, + "value": 1, + "lb": null, + "ub": null + }, + "('Liq', 'HCO3_-')": { + "__type__": "", + "__id__": 215, + "fixed": true, + "stale": true, + "value": 0, + "lb": null, + "ub": null + }, + "('Liq', 'MEA_+')": { + "__type__": "", + "__id__": 216, + "fixed": true, + "stale": true, + "value": 1, + "lb": null, + "ub": null + }, + "('Liq', 'H2O')": { + "__type__": "", + "__id__": 217, + "fixed": true, + "stale": true, + "value": 0, + "lb": null, + "ub": null + }, + "('Liq', 'MEA')": { + "__type__": "", + "__id__": 218, + "fixed": true, + "stale": true, + "value": -2, + "lb": null, + "ub": null + }, + "('Liq', 'CO2')": { + "__type__": "", + "__id__": 219, + "fixed": true, + "stale": true, + "value": -1, + "lb": null, + "ub": null + } + } + }, + "k_eq_coeff_1": { + "__type__": "", + "__id__": 220, + "data": { + "None": { + "__type__": "", + "__id__": 221, + "fixed": true, + "stale": true, + "value": 233.4, + "lb": null, + "ub": null + } + } + }, + "k_eq_coeff_2": { + "__type__": "", + "__id__": 222, + "data": { + "None": { + "__type__": "", + "__id__": 223, + "fixed": true, + "stale": true, + "value": -3410, + "lb": null, + "ub": null + } + } + }, + "k_eq_coeff_3": { + "__type__": "", + "__id__": 224, + "data": { + "None": { + "__type__": "", + "__id__": 225, + "fixed": true, + "stale": true, + "value": -36.8, + "lb": null, + "ub": null + } + } + } + } + } + } + } + } + } + } + }, + "vapor_properties": { + "__type__": "", + "__id__": 226, + "active": true, + "data": { + "None": { + "__type__": "", + "__id__": 227, + "active": true, + "__pyomo_components__": { + "Vap": { + "__type__": "", + "__id__": 228, + "active": true, + "data": { + "None": { + "__type__": "", + "__id__": 229, + "active": true, + "__pyomo_components__": { + "visc_d_h2o_coeff_1": { + "__type__": "", + "__id__": 230, + "data": { + "None": { + "__type__": "", + "__id__": 231, + "fixed": true, + "stale": true, + "value": 1.7096e-08, + "lb": null, + "ub": null + } + } + }, + "visc_d_h2o_coeff_2": { + "__type__": "", + "__id__": 232, + "data": { + "None": { + "__type__": "", + "__id__": 233, + "fixed": true, + "stale": true, + "value": 1.1146, + "lb": null, + "ub": null + } + } + }, + "visc_d_h2o_coeff_3": { + "__type__": "", + "__id__": 234, + "data": { + "None": { + "__type__": "", + "__id__": 235, + "fixed": true, + "stale": true, + "value": 0.0, + "lb": null, + "ub": null + } + } + }, + "visc_d_co2_coeff_1": { + "__type__": "", + "__id__": 236, + "data": { + "None": { + "__type__": "", + "__id__": 237, + "fixed": true, + "stale": true, + "value": 2.148e-06, + "lb": null, + "ub": null + } + } + }, + "visc_d_co2_coeff_2": { + "__type__": "", + "__id__": 238, + "data": { + "None": { + "__type__": "", + "__id__": 239, + "fixed": true, + "stale": true, + "value": 0.46, + "lb": null, + "ub": null + } + } + }, + "visc_d_co2_coeff_3": { + "__type__": "", + "__id__": 240, + "data": { + "None": { + "__type__": "", + "__id__": 241, + "fixed": true, + "stale": true, + "value": 290, + "lb": null, + "ub": null + } + } + }, + "visc_d_n2_coeff_1": { + "__type__": "", + "__id__": 242, + "data": { + "None": { + "__type__": "", + "__id__": 243, + "fixed": true, + "stale": true, + "value": 1.781e-05, + "lb": null, + "ub": null + } + } + }, + "visc_d_n2_coeff_2": { + "__type__": "", + "__id__": 244, + "data": { + "None": { + "__type__": "", + "__id__": 245, + "fixed": true, + "stale": true, + "value": 300.55, + "lb": null, + "ub": null + } + } + }, + "visc_d_n2_coeff_3": { + "__type__": "", + "__id__": 246, + "data": { + "None": { + "__type__": "", + "__id__": 247, + "fixed": true, + "stale": true, + "value": 111, + "lb": null, + "ub": null + } + } + }, + "visc_d_o2_coeff_1": { + "__type__": "", + "__id__": 248, + "data": { + "None": { + "__type__": "", + "__id__": 249, + "fixed": true, + "stale": true, + "value": 2.018e-05, + "lb": null, + "ub": null + } + } + }, + "visc_d_o2_coeff_2": { + "__type__": "", + "__id__": 250, + "data": { + "None": { + "__type__": "", + "__id__": 251, + "fixed": true, + "stale": true, + "value": 292.25, + "lb": null, + "ub": null + } + } + }, + "visc_d_o2_coeff_3": { + "__type__": "", + "__id__": 252, + "data": { + "None": { + "__type__": "", + "__id__": 253, + "fixed": true, + "stale": true, + "value": 127, + "lb": null, + "ub": null + } + } + }, + "therm_cond_h2o_coeff_1": { + "__type__": "", + "__id__": 254, + "data": { + "None": { + "__type__": "", + "__id__": 255, + "fixed": true, + "stale": true, + "value": 6.204e-06, + "lb": null, + "ub": null + } + } + }, + "therm_cond_h2o_coeff_2": { + "__type__": "", + "__id__": 256, + "data": { + "None": { + "__type__": "", + "__id__": 257, + "fixed": true, + "stale": true, + "value": 1.3973, + "lb": null, + "ub": null + } + } + }, + "therm_cond_h2o_coeff_3": { + "__type__": "", + "__id__": 258, + "data": { + "None": { + "__type__": "", + "__id__": 259, + "fixed": true, + "stale": true, + "value": 0.0, + "lb": null, + "ub": null + } + } + }, + "therm_cond_h2o_coeff_4": { + "__type__": "", + "__id__": 260, + "data": { + "None": { + "__type__": "", + "__id__": 261, + "fixed": true, + "stale": true, + "value": 0, + "lb": null, + "ub": null + } + } + }, + "therm_cond_co2_coeff_1": { + "__type__": "", + "__id__": 262, + "data": { + "None": { + "__type__": "", + "__id__": 263, + "fixed": true, + "stale": true, + "value": 3.69, + "lb": null, + "ub": null + } + } + }, + "therm_cond_co2_coeff_2": { + "__type__": "", + "__id__": 264, + "data": { + "None": { + "__type__": "", + "__id__": 265, + "fixed": true, + "stale": true, + "value": -0.3838, + "lb": null, + "ub": null + } + } + }, + "therm_cond_co2_coeff_3": { + "__type__": "", + "__id__": 266, + "data": { + "None": { + "__type__": "", + "__id__": 267, + "fixed": true, + "stale": true, + "value": 964, + "lb": null, + "ub": null + } + } + }, + "therm_cond_co2_coeff_4": { + "__type__": "", + "__id__": 268, + "data": { + "None": { + "__type__": "", + "__id__": 269, + "fixed": true, + "stale": true, + "value": 1860000.0, + "lb": null, + "ub": null + } + } + }, + "therm_cond_n2_coeff_1": { + "__type__": "", + "__id__": 270, + "data": { + "None": { + "__type__": "", + "__id__": 271, + "fixed": true, + "stale": true, + "value": 0.000331, + "lb": null, + "ub": null + } + } + }, + "therm_cond_n2_coeff_2": { + "__type__": "", + "__id__": 272, + "data": { + "None": { + "__type__": "", + "__id__": 273, + "fixed": true, + "stale": true, + "value": 0.7722, + "lb": null, + "ub": null + } + } + }, + "therm_cond_n2_coeff_3": { + "__type__": "", + "__id__": 274, + "data": { + "None": { + "__type__": "", + "__id__": 275, + "fixed": true, + "stale": true, + "value": 16.323, + "lb": null, + "ub": null + } + } + }, + "therm_cond_n2_coeff_4": { + "__type__": "", + "__id__": 276, + "data": { + "None": { + "__type__": "", + "__id__": 277, + "fixed": true, + "stale": true, + "value": 373.72, + "lb": null, + "ub": null + } + } + }, + "therm_cond_o2_coeff_1": { + "__type__": "", + "__id__": 278, + "data": { + "None": { + "__type__": "", + "__id__": 279, + "fixed": true, + "stale": true, + "value": 0.00045, + "lb": null, + "ub": null + } + } + }, + "therm_cond_o2_coeff_2": { + "__type__": "", + "__id__": 280, + "data": { + "None": { + "__type__": "", + "__id__": 281, + "fixed": true, + "stale": true, + "value": 0.7456, + "lb": null, + "ub": null + } + } + }, + "therm_cond_o2_coeff_3": { + "__type__": "", + "__id__": 282, + "data": { + "None": { + "__type__": "", + "__id__": 283, + "fixed": true, + "stale": true, + "value": 56.699, + "lb": null, + "ub": null + } + } + }, + "therm_cond_o2_coeff_4": { + "__type__": "", + "__id__": 284, + "data": { + "None": { + "__type__": "", + "__id__": 285, + "fixed": true, + "stale": true, + "value": 0, + "lb": null, + "ub": null + } + } + } + } + } + } + }, + "CO2": { + "__type__": "", + "__id__": 286, + "active": true, + "data": { + "None": { + "__type__": "", + "__id__": 287, + "active": true, + "__pyomo_components__": { + "mw": { + "__type__": "", + "__id__": 288, + "_mutable": true, + "data": { + "None": { + "__type__": "", + "__id__": 289, + "value": 0.04401 + } + } + }, + "cp_mol_vap_comp_coeff_1": { + "__type__": "", + "__id__": 290, + "data": { + "None": { + "__type__": "", + "__id__": 291, + "fixed": true, + "stale": true, + "value": 5.457, + "lb": null, + "ub": null + } + } + }, + "cp_mol_vap_comp_coeff_2": { + "__type__": "", + "__id__": 292, + "data": { + "None": { + "__type__": "", + "__id__": 293, + "fixed": true, + "stale": true, + "value": 0.001045, + "lb": null, + "ub": null + } + } + }, + "cp_mol_vap_comp_coeff_3": { + "__type__": "", + "__id__": 294, + "data": { + "None": { + "__type__": "", + "__id__": 295, + "fixed": true, + "stale": true, + "value": -115700.0, + "lb": null, + "ub": null + } + } + } + } + } + } + }, + "H2O": { + "__type__": "", + "__id__": 296, + "active": true, + "data": { + "None": { + "__type__": "", + "__id__": 297, + "active": true, + "__pyomo_components__": { + "mw": { + "__type__": "", + "__id__": 298, + "_mutable": true, + "data": { + "None": { + "__type__": "", + "__id__": 299, + "value": 0.01802 + } + } + }, + "cp_mol_vap_comp_coeff_1": { + "__type__": "", + "__id__": 300, + "data": { + "None": { + "__type__": "", + "__id__": 301, + "fixed": true, + "stale": true, + "value": 3.47, + "lb": null, + "ub": null + } + } + }, + "cp_mol_vap_comp_coeff_2": { + "__type__": "", + "__id__": 302, + "data": { + "None": { + "__type__": "", + "__id__": 303, + "fixed": true, + "stale": true, + "value": 0.00145, + "lb": null, + "ub": null + } + } + }, + "cp_mol_vap_comp_coeff_3": { + "__type__": "", + "__id__": 304, + "data": { + "None": { + "__type__": "", + "__id__": 305, + "fixed": true, + "stale": true, + "value": 12100.0, + "lb": null, + "ub": null + } + } + } + } + } + } + }, + "N2": { + "__type__": "", + "__id__": 306, + "active": true, + "data": { + "None": { + "__type__": "", + "__id__": 307, + "active": true, + "__pyomo_components__": { + "mw": { + "__type__": "", + "__id__": 308, + "_mutable": true, + "data": { + "None": { + "__type__": "", + "__id__": 309, + "value": 0.02801 + } + } + }, + "cp_mol_vap_comp_coeff_1": { + "__type__": "", + "__id__": 310, + "data": { + "None": { + "__type__": "", + "__id__": 311, + "fixed": true, + "stale": true, + "value": 3.28, + "lb": null, + "ub": null + } + } + }, + "cp_mol_vap_comp_coeff_2": { + "__type__": "", + "__id__": 312, + "data": { + "None": { + "__type__": "", + "__id__": 313, + "fixed": true, + "stale": true, + "value": 0.000593, + "lb": null, + "ub": null + } + } + }, + "cp_mol_vap_comp_coeff_3": { + "__type__": "", + "__id__": 314, + "data": { + "None": { + "__type__": "", + "__id__": 315, + "fixed": true, + "stale": true, + "value": 4000.0, + "lb": null, + "ub": null + } + } + } + } + } + } + }, + "O2": { + "__type__": "", + "__id__": 316, + "active": true, + "data": { + "None": { + "__type__": "", + "__id__": 317, + "active": true, + "__pyomo_components__": { + "mw": { + "__type__": "", + "__id__": 318, + "_mutable": true, + "data": { + "None": { + "__type__": "", + "__id__": 319, + "value": 0.032 + } + } + }, + "cp_mol_vap_comp_coeff_1": { + "__type__": "", + "__id__": 320, + "data": { + "None": { + "__type__": "", + "__id__": 321, + "fixed": true, + "stale": true, + "value": 3.639, + "lb": null, + "ub": null + } + } + }, + "cp_mol_vap_comp_coeff_2": { + "__type__": "", + "__id__": 322, + "data": { + "None": { + "__type__": "", + "__id__": 323, + "fixed": true, + "stale": true, + "value": 0.000506, + "lb": null, + "ub": null + } + } + }, + "cp_mol_vap_comp_coeff_3": { + "__type__": "", + "__id__": 324, + "data": { + "None": { + "__type__": "", + "__id__": 325, + "fixed": true, + "stale": true, + "value": -22700.0, + "lb": null, + "ub": null + } + } + } + } + } + } + }, + "pressure_ref": { + "__type__": "", + "__id__": 326, + "_mutable": true, + "data": { + "None": { + "__type__": "", + "__id__": 327, + "value": 101325.0 + } + } + }, + "temperature_ref": { + "__type__": "", + "__id__": 328, + "_mutable": true, + "data": { + "None": { + "__type__": "", + "__id__": 329, + "value": 298.15 + } + } + } + } + } + } + }, + "unit": { + "__type__": "", + "__id__": 330, + "active": true, + "data": { + "None": { + "__type__": "", + "__id__": 331, + "active": true, + "__pyomo_components__": { + "liquid_phase": { + "__type__": "", + "__id__": 332, + "active": true, + "data": { + "None": { + "__type__": "", + "__id__": 333, + "active": true, + "__pyomo_components__": { + "properties_in": { + "__type__": "", + "__id__": 334, + "active": true, + "data": { + "0.0": { + "__type__": "", + "__id__": 335, + "active": true, + "__pyomo_components__": { + "flow_mol": { + "__type__": "", + "__id__": 336, + "data": { + "None": { + "__type__": "", + "__id__": 337, + "fixed": true, + "stale": false, + "value": 83.89, + "lb": 0, + "ub": 1000 + } + } + }, + "mole_frac_comp": { + "__type__": "", + "__id__": 338, + "data": { + "'H2O'": { + "__type__": "", + "__id__": 339, + "fixed": true, + "stale": false, + "value": 0.8589, + "lb": 1e-20, + "ub": 1.001 + }, + "'MEA'": { + "__type__": "", + "__id__": 340, + "fixed": true, + "stale": false, + "value": 0.1085, + "lb": 1e-20, + "ub": 1.001 + }, + "'CO2'": { + "__type__": "", + "__id__": 341, + "fixed": true, + "stale": false, + "value": 0.0326, + "lb": 1e-20, + "ub": 1.001 + } + } + }, + "pressure": { + "__type__": "", + "__id__": 342, + "data": { + "None": { + "__type__": "", + "__id__": 343, + "fixed": true, + "stale": false, + "value": 183700, + "lb": 50000.0, + "ub": 1000000.0 + } + } + }, + "temperature": { + "__type__": "", + "__id__": 344, + "data": { + "None": { + "__type__": "", + "__id__": 345, + "fixed": true, + "stale": false, + "value": 392.5, + "lb": 273.15, + "ub": 450 + } + } + }, + "flow_mol_phase": { + "__type__": "", + "__id__": 346, + "data": { + "'Liq'": { + "__type__": "", + "__id__": 347, + "fixed": false, + "stale": true, + "value": 83.89, + "lb": 0, + "ub": 1000 + } + } + }, + "mole_frac_phase_comp": { + "__type__": "", + "__id__": 348, + "data": { + "('Liq', 'H2O')": { + "__type__": "", + "__id__": 349, + "fixed": false, + "stale": true, + "value": 0.8589, + "lb": 1e-20, + "ub": 1.001 + }, + "('Liq', 'MEA')": { + "__type__": "", + "__id__": 350, + "fixed": false, + "stale": true, + "value": 0.1085, + "lb": 1e-20, + "ub": 1.001 + }, + "('Liq', 'CO2')": { + "__type__": "", + "__id__": 351, + "fixed": false, + "stale": true, + "value": 0.0326, + "lb": 1e-20, + "ub": 1.001 + } + } + }, + "flow_mol_phase_comp": { + "__type__": "", + "__id__": 352, + "data": { + "('Liq', 'H2O')": { + "__type__": "", + "__id__": 353 + }, + "('Liq', 'MEA')": { + "__type__": "", + "__id__": 354 + }, + "('Liq', 'CO2')": { + "__type__": "", + "__id__": 355 + } + } + }, + "phase_frac": { + "__type__": "", + "__id__": 356, + "data": { + "'Liq'": { + "__type__": "", + "__id__": 357, + "fixed": false, + "stale": true, + "value": 1.0, + "lb": 0, + "ub": null + } + } + }, + "flow_mol_phase_apparent": { + "__type__": "", + "__id__": 358, + "data": { + "'Liq'": { + "__type__": "", + "__id__": 359, + "fixed": false, + "stale": true, + "value": 83.89, + "lb": 0, + "ub": 1000 + } + } + }, + "flow_mol_phase_comp_apparent": { + "__type__": "", + "__id__": 360, + "data": { + "('Liq', 'H2O')": { + "__type__": "", + "__id__": 361 + }, + "('Liq', 'MEA')": { + "__type__": "", + "__id__": 362 + }, + "('Liq', 'CO2')": { + "__type__": "", + "__id__": 363 + } + } + }, + "mole_frac_phase_comp_apparent": { + "__type__": "", + "__id__": 364, + "data": { + "('Liq', 'H2O')": { + "__type__": "", + "__id__": 365, + "fixed": false, + "stale": true, + "value": 0.8589, + "lb": 1e-20, + "ub": 1.001 + }, + "('Liq', 'MEA')": { + "__type__": "", + "__id__": 366, + "fixed": false, + "stale": true, + "value": 0.1085, + "lb": 1e-20, + "ub": 1.001 + }, + "('Liq', 'CO2')": { + "__type__": "", + "__id__": 367, + "fixed": false, + "stale": true, + "value": 0.0326, + "lb": 1e-20, + "ub": 1.001 + } + } + }, + "flow_mol_phase_comp_true": { + "__type__": "", + "__id__": 368, + "data": { + "('Liq', 'MEACOO_-')": { + "__type__": "", + "__id__": 369, + "fixed": false, + "stale": true, + "value": 2.549520147776267, + "lb": 0, + "ub": 1000 + }, + "('Liq', 'HCO3_-')": { + "__type__": "", + "__id__": 370, + "fixed": false, + "stale": true, + "value": 0.1784904217604413, + "lb": 0, + "ub": 1000 + }, + "('Liq', 'MEA_+')": { + "__type__": "", + "__id__": 371, + "fixed": false, + "stale": true, + "value": 2.7280105695367083, + "lb": 0, + "ub": 1000 + }, + "('Liq', 'H2O')": { + "__type__": "", + "__id__": 372, + "fixed": false, + "stale": true, + "value": 71.87463057823956, + "lb": 0, + "ub": 1000 + }, + "('Liq', 'MEA')": { + "__type__": "", + "__id__": 373, + "fixed": false, + "stale": true, + "value": 3.8245342826870243, + "lb": 0, + "ub": 1000 + }, + "('Liq', 'CO2')": { + "__type__": "", + "__id__": 374, + "fixed": false, + "stale": true, + "value": 0.0068034304632915215, + "lb": 0, + "ub": 1000 + } + } + }, + "mole_frac_phase_comp_true": { + "__type__": "", + "__id__": 375, + "data": { + "('Liq', 'MEACOO_-')": { + "__type__": "", + "__id__": 376, + "fixed": false, + "stale": true, + "value": 0.03141273600692853, + "lb": 1e-20, + "ub": 1.001 + }, + "('Liq', 'HCO3_-')": { + "__type__": "", + "__id__": 377, + "fixed": false, + "stale": true, + "value": 0.0021991873660682686, + "lb": 1e-20, + "ub": 1.001 + }, + "('Liq', 'MEA_+')": { + "__type__": "", + "__id__": 378, + "fixed": false, + "stale": true, + "value": 0.0336119233729968, + "lb": 1e-20, + "ub": 1.001 + }, + "('Liq', 'H2O')": { + "__type__": "", + "__id__": 379, + "fixed": false, + "stale": true, + "value": 0.8855700936189987, + "lb": 1e-20, + "ub": 1.001 + }, + "('Liq', 'MEA')": { + "__type__": "", + "__id__": 380, + "fixed": false, + "stale": true, + "value": 0.04712223430604482, + "lb": 1e-20, + "ub": 1.001 + }, + "('Liq', 'CO2')": { + "__type__": "", + "__id__": 381, + "fixed": false, + "stale": true, + "value": 8.382532896284006e-05, + "lb": 1e-20, + "ub": 1.001 + } + } + }, + "apparent_inherent_reaction_extent": { + "__type__": "", + "__id__": 382, + "data": { + "'bicarbonate'": { + "__type__": "", + "__id__": 383, + "fixed": false, + "stale": true, + "value": 0.1784904217604413, + "lb": null, + "ub": null + }, + "'carbamate'": { + "__type__": "", + "__id__": 384, + "fixed": false, + "stale": true, + "value": 2.549520147776267, + "lb": null, + "ub": null + } + } + }, + "appr_to_true_species": { + "__type__": "", + "__id__": 385, + "active": true, + "data": { + "('Liq', 'MEACOO_-')": { + "__type__": "", + "__id__": 386, + "active": true + }, + "('Liq', 'HCO3_-')": { + "__type__": "", + "__id__": 387, + "active": true + }, + "('Liq', 'MEA_+')": { + "__type__": "", + "__id__": 388, + "active": true + }, + "('Liq', 'H2O')": { + "__type__": "", + "__id__": 389, + "active": true + }, + "('Liq', 'MEA')": { + "__type__": "", + "__id__": 390, + "active": true + }, + "('Liq', 'CO2')": { + "__type__": "", + "__id__": 391, + "active": true + } + } + }, + "true_mole_frac_constraint": { + "__type__": "", + "__id__": 392, + "active": true, + "data": { + "('Liq', 'MEACOO_-')": { + "__type__": "", + "__id__": 393, + "active": true + }, + "('Liq', 'HCO3_-')": { + "__type__": "", + "__id__": 394, + "active": true + }, + "('Liq', 'MEA_+')": { + "__type__": "", + "__id__": 395, + "active": true + }, + "('Liq', 'H2O')": { + "__type__": "", + "__id__": 396, + "active": true + }, + "('Liq', 'MEA')": { + "__type__": "", + "__id__": 397, + "active": true + }, + "('Liq', 'CO2')": { + "__type__": "", + "__id__": 398, + "active": true + } + } + }, + "total_flow_balance": { + "__type__": "", + "__id__": 399, + "active": true, + "data": { + "None": { + "__type__": "", + "__id__": 400, + "active": true + } + } + }, + "component_flow_balances": { + "__type__": "", + "__id__": 401, + "active": true, + "data": { + "'H2O'": { + "__type__": "", + "__id__": 402, + "active": true + }, + "'MEA'": { + "__type__": "", + "__id__": 403, + "active": true + }, + "'CO2'": { + "__type__": "", + "__id__": 404, + "active": true + } + } + }, + "phase_fraction_constraint": { + "__type__": "", + "__id__": 405, + "active": true, + "data": { + "'Liq'": { + "__type__": "", + "__id__": 406, + "active": true + } + } + }, + "k_eq": { + "__type__": "", + "__id__": 407, + "data": { + "'bicarbonate'": { + "__type__": "", + "__id__": 408 + }, + "'carbamate'": { + "__type__": "", + "__id__": 409 + } + } + }, + "log_k_eq": { + "__type__": "", + "__id__": 410, + "data": { + "'bicarbonate'": { + "__type__": "", + "__id__": 411, + "fixed": false, + "stale": true, + "value": -7.577610096486296, + "lb": null, + "ub": null + }, + "'carbamate'": { + "__type__": "", + "__id__": 412, + "fixed": false, + "stale": true, + "value": -1.9849979379407046, + "lb": null, + "ub": null + } + } + }, + "log_k_eq_constraint": { + "__type__": "", + "__id__": 413, + "active": true, + "data": { + "'bicarbonate'": { + "__type__": "", + "__id__": 414, + "active": true + }, + "'carbamate'": { + "__type__": "", + "__id__": 415, + "active": true + } + } + }, + "inherent_equilibrium_constraint": { + "__type__": "", + "__id__": 416, + "active": true, + "data": { + "'bicarbonate'": { + "__type__": "", + "__id__": 417, + "active": true + }, + "'carbamate'": { + "__type__": "", + "__id__": 418, + "active": true + } + } + }, + "log_conc_mol_phase_comp_true": { + "__type__": "", + "__id__": 419, + "data": { + "('Liq', 'MEACOO_-')": { + "__type__": "", + "__id__": 420, + "fixed": false, + "stale": true, + "value": 7.167835787320503, + "lb": -50, + "ub": null + }, + "('Liq', 'HCO3_-')": { + "__type__": "", + "__id__": 421, + "fixed": false, + "stale": true, + "value": 4.508710284392842, + "lb": -50, + "ub": null + }, + "('Liq', 'MEA_+')": { + "__type__": "", + "__id__": 422, + "fixed": false, + "stale": true, + "value": 7.235503237637699, + "lb": -50, + "ub": null + }, + "('Liq', 'H2O')": { + "__type__": "", + "__id__": 423, + "fixed": false, + "stale": true, + "value": 10.506853982523678, + "lb": -50, + "ub": null + }, + "('Liq', 'MEA')": { + "__type__": "", + "__id__": 424, + "fixed": false, + "stale": true, + "value": 7.573367326905747, + "lb": -50, + "ub": null + }, + "('Liq', 'CO2')": { + "__type__": "", + "__id__": 425, + "fixed": false, + "stale": true, + "value": 1.241602309087413, + "lb": -50, + "ub": null + } + } + }, + "log_conc_mol_phase_comp_true_eq": { + "__type__": "", + "__id__": 426, + "active": true, + "data": { + "('Liq', 'MEACOO_-')": { + "__type__": "", + "__id__": 427, + "active": true + }, + "('Liq', 'HCO3_-')": { + "__type__": "", + "__id__": 428, + "active": true + }, + "('Liq', 'MEA_+')": { + "__type__": "", + "__id__": 429, + "active": true + }, + "('Liq', 'H2O')": { + "__type__": "", + "__id__": 430, + "active": true + }, + "('Liq', 'MEA')": { + "__type__": "", + "__id__": 431, + "active": true + }, + "('Liq', 'CO2')": { + "__type__": "", + "__id__": 432, + "active": true + } + } + }, + "conc_mol_phase_comp_true": { + "__type__": "", + "__id__": 433, + "data": { + "('Liq', 'MEACOO_-')": { + "__type__": "", + "__id__": 434 + }, + "('Liq', 'HCO3_-')": { + "__type__": "", + "__id__": 435 + }, + "('Liq', 'MEA_+')": { + "__type__": "", + "__id__": 436 + }, + "('Liq', 'H2O')": { + "__type__": "", + "__id__": 437 + }, + "('Liq', 'MEA')": { + "__type__": "", + "__id__": 438 + }, + "('Liq', 'CO2')": { + "__type__": "", + "__id__": 439 + } + } + }, + "dens_mol_phase": { + "__type__": "", + "__id__": 440, + "data": { + "'Liq'": { + "__type__": "", + "__id__": 441 + } + } + }, + "vol_mol_phase": { + "__type__": "", + "__id__": 442, + "data": { + "'Liq'": { + "__type__": "", + "__id__": 443 + } + } + }, + "_enthalpy_flow_term": { + "__type__": "", + "__id__": 444, + "data": { + "'Liq'": { + "__type__": "", + "__id__": 445 + } + } + }, + "enth_mol_phase": { + "__type__": "", + "__id__": 446, + "data": { + "'Liq'": { + "__type__": "", + "__id__": 447 + } + } + } + } + } + } + }, + "properties_out": { + "__type__": "", + "__id__": 448, + "active": true, + "data": { + "0.0": { + "__type__": "", + "__id__": 449, + "active": true, + "__pyomo_components__": { + "flow_mol": { + "__type__": "", + "__id__": 450, + "data": { + "None": { + "__type__": "", + "__id__": 451, + "fixed": false, + "stale": true, + "value": 74.23575715286673, + "lb": 0, + "ub": 1000 + } + } + }, + "mole_frac_comp": { + "__type__": "", + "__id__": 452, + "data": { + "'H2O'": { + "__type__": "", + "__id__": 453, + "fixed": false, + "stale": true, + "value": 0.8526828636361445, + "lb": 1e-20, + "ub": 1.001 + }, + "'MEA'": { + "__type__": "", + "__id__": 454, + "fixed": false, + "stale": true, + "value": 0.12261025345451311, + "lb": 1e-20, + "ub": 1.001 + }, + "'CO2'": { + "__type__": "", + "__id__": 455, + "fixed": false, + "stale": true, + "value": 0.024706882701208462, + "lb": 1e-20, + "ub": 1.001 + } + } + }, + "pressure": { + "__type__": "", + "__id__": 456, + "data": { + "None": { + "__type__": "", + "__id__": 457, + "fixed": false, + "stale": true, + "value": 183700.0, + "lb": 50000.0, + "ub": 1000000.0 + } + } + }, + "temperature": { + "__type__": "", + "__id__": 458, + "data": { + "None": { + "__type__": "", + "__id__": 459, + "fixed": false, + "stale": true, + "value": 392.64275063606675, + "lb": 273.15, + "ub": 450 + } + } + }, + "flow_mol_phase": { + "__type__": "", + "__id__": 460, + "data": { + "'Liq'": { + "__type__": "", + "__id__": 461, + "fixed": false, + "stale": true, + "value": 74.23575715286673, + "lb": 0, + "ub": 1000 + } + } + }, + "mole_frac_phase_comp": { + "__type__": "", + "__id__": 462, + "data": { + "('Liq', 'H2O')": { + "__type__": "", + "__id__": 463, + "fixed": false, + "stale": true, + "value": 0.8526828636361445, + "lb": 1e-20, + "ub": 1.001 + }, + "('Liq', 'MEA')": { + "__type__": "", + "__id__": 464, + "fixed": false, + "stale": true, + "value": 0.12261025345451311, + "lb": 1e-20, + "ub": 1.001 + }, + "('Liq', 'CO2')": { + "__type__": "", + "__id__": 465, + "fixed": false, + "stale": true, + "value": 0.024706882701208462, + "lb": 1e-20, + "ub": 1.001 + } + } + }, + "flow_mol_phase_comp": { + "__type__": "", + "__id__": 466, + "data": { + "('Liq', 'H2O')": { + "__type__": "", + "__id__": 467 + }, + "('Liq', 'MEA')": { + "__type__": "", + "__id__": 468 + }, + "('Liq', 'CO2')": { + "__type__": "", + "__id__": 469 + } + } + }, + "phase_frac": { + "__type__": "", + "__id__": 470, + "data": { + "'Liq'": { + "__type__": "", + "__id__": 471, + "fixed": false, + "stale": true, + "value": 1.0, + "lb": 0, + "ub": null + } + } + }, + "flow_mol_phase_apparent": { + "__type__": "", + "__id__": 472, + "data": { + "'Liq'": { + "__type__": "", + "__id__": 473, + "fixed": false, + "stale": true, + "value": 74.23575715286673, + "lb": 0, + "ub": 1000 + } + } + }, + "flow_mol_phase_comp_apparent": { + "__type__": "", + "__id__": 474, + "data": { + "('Liq', 'H2O')": { + "__type__": "", + "__id__": 475 + }, + "('Liq', 'MEA')": { + "__type__": "", + "__id__": 476 + }, + "('Liq', 'CO2')": { + "__type__": "", + "__id__": 477 + } + } + }, + "mole_frac_phase_comp_apparent": { + "__type__": "", + "__id__": 478, + "data": { + "('Liq', 'H2O')": { + "__type__": "", + "__id__": 479, + "fixed": false, + "stale": true, + "value": 0.8526828636361445, + "lb": 1e-20, + "ub": 1.001 + }, + "('Liq', 'MEA')": { + "__type__": "", + "__id__": 480, + "fixed": false, + "stale": true, + "value": 0.12261025345451311, + "lb": 1e-20, + "ub": 1.001 + }, + "('Liq', 'CO2')": { + "__type__": "", + "__id__": 481, + "fixed": false, + "stale": true, + "value": 0.024706882701208462, + "lb": 1e-20, + "ub": 1.001 + } + } + }, + "flow_mol_phase_comp_true": { + "__type__": "", + "__id__": 482, + "data": { + "('Liq', 'MEACOO_-')": { + "__type__": "", + "__id__": 483, + "fixed": false, + "stale": true, + "value": 1.7574422018796485, + "lb": 0, + "ub": 1000 + }, + "('Liq', 'HCO3_-')": { + "__type__": "", + "__id__": 484, + "fixed": false, + "stale": true, + "value": 0.07529033507451455, + "lb": 0, + "ub": 1000 + }, + "('Liq', 'MEA_+')": { + "__type__": "", + "__id__": 485, + "fixed": false, + "stale": true, + "value": 1.8327325369619798, + "lb": 0, + "ub": 1000 + }, + "('Liq', 'H2O')": { + "__type__": "", + "__id__": 486, + "fixed": false, + "stale": true, + "value": 63.2242676582273, + "lb": 0, + "ub": 1000 + }, + "('Liq', 'MEA')": { + "__type__": "", + "__id__": 487, + "fixed": false, + "stale": true, + "value": 5.511890261061947, + "lb": 0, + "ub": 1000 + }, + "('Liq', 'CO2')": { + "__type__": "", + "__id__": 488, + "fixed": false, + "stale": true, + "value": 0.0014016072844848968, + "lb": 0, + "ub": 1000 + } + } + }, + "mole_frac_phase_comp_true": { + "__type__": "", + "__id__": 489, + "data": { + "('Liq', 'MEACOO_-')": { + "__type__": "", + "__id__": 490, + "fixed": false, + "stale": true, + "value": 0.024273049524897807, + "lb": 1e-20, + "ub": 1.001 + }, + "('Liq', 'HCO3_-')": { + "__type__": "", + "__id__": 491, + "fixed": false, + "stale": true, + "value": 0.0010398783131191267, + "lb": 1e-20, + "ub": 1.001 + }, + "('Liq', 'MEA_+')": { + "__type__": "", + "__id__": 492, + "fixed": false, + "stale": true, + "value": 0.025312927837953244, + "lb": 1e-20, + "ub": 1.001 + }, + "('Liq', 'H2O')": { + "__type__": "", + "__id__": 493, + "fixed": false, + "stale": true, + "value": 0.873226885300614, + "lb": 1e-20, + "ub": 1.001 + }, + "('Liq', 'MEA')": { + "__type__": "", + "__id__": 494, + "fixed": false, + "stale": true, + "value": 0.07612790061581895, + "lb": 1e-20, + "ub": 1.001 + }, + "('Liq', 'CO2')": { + "__type__": "", + "__id__": 495, + "fixed": false, + "stale": true, + "value": 1.9358408266309665e-05, + "lb": 1e-20, + "ub": 1.001 + } + } + }, + "apparent_inherent_reaction_extent": { + "__type__": "", + "__id__": 496, + "data": { + "'bicarbonate'": { + "__type__": "", + "__id__": 497, + "fixed": false, + "stale": true, + "value": 0.07529033507451455, + "lb": null, + "ub": null + }, + "'carbamate'": { + "__type__": "", + "__id__": 498, + "fixed": false, + "stale": true, + "value": 1.7574422018796485, + "lb": null, + "ub": null + } + } + }, + "appr_to_true_species": { + "__type__": "", + "__id__": 499, + "active": true, + "data": { + "('Liq', 'MEACOO_-')": { + "__type__": "", + "__id__": 500, + "active": true + }, + "('Liq', 'HCO3_-')": { + "__type__": "", + "__id__": 501, + "active": true + }, + "('Liq', 'MEA_+')": { + "__type__": "", + "__id__": 502, + "active": true + }, + "('Liq', 'H2O')": { + "__type__": "", + "__id__": 503, + "active": true + }, + "('Liq', 'MEA')": { + "__type__": "", + "__id__": 504, + "active": true + }, + "('Liq', 'CO2')": { + "__type__": "", + "__id__": 505, + "active": true + } + } + }, + "true_mole_frac_constraint": { + "__type__": "", + "__id__": 506, + "active": true, + "data": { + "('Liq', 'MEACOO_-')": { + "__type__": "", + "__id__": 507, + "active": true + }, + "('Liq', 'HCO3_-')": { + "__type__": "", + "__id__": 508, + "active": true + }, + "('Liq', 'MEA_+')": { + "__type__": "", + "__id__": 509, + "active": true + }, + "('Liq', 'H2O')": { + "__type__": "", + "__id__": 510, + "active": true + }, + "('Liq', 'MEA')": { + "__type__": "", + "__id__": 511, + "active": true + }, + "('Liq', 'CO2')": { + "__type__": "", + "__id__": 512, + "active": true + } + } + }, + "sum_mole_frac_out": { + "__type__": "", + "__id__": 513, + "active": true, + "data": { + "None": { + "__type__": "", + "__id__": 514, + "active": true + } + } + }, + "total_flow_balance": { + "__type__": "", + "__id__": 515, + "active": true, + "data": { + "None": { + "__type__": "", + "__id__": 516, + "active": true + } + } + }, + "component_flow_balances": { + "__type__": "", + "__id__": 517, + "active": true, + "data": { + "'H2O'": { + "__type__": "", + "__id__": 518, + "active": true + }, + "'MEA'": { + "__type__": "", + "__id__": 519, + "active": true + }, + "'CO2'": { + "__type__": "", + "__id__": 520, + "active": true + } + } + }, + "phase_fraction_constraint": { + "__type__": "", + "__id__": 521, + "active": true, + "data": { + "'Liq'": { + "__type__": "", + "__id__": 522, + "active": true + } + } + }, + "k_eq": { + "__type__": "", + "__id__": 523, + "data": { + "'bicarbonate'": { + "__type__": "", + "__id__": 524 + }, + "'carbamate'": { + "__type__": "", + "__id__": 525 + } + } + }, + "log_k_eq": { + "__type__": "", + "__id__": 526, + "data": { + "'bicarbonate'": { + "__type__": "", + "__id__": 527, + "fixed": false, + "stale": true, + "value": -7.585264460309064, + "lb": null, + "ub": null + }, + "'carbamate'": { + "__type__": "", + "__id__": 528, + "fixed": false, + "stale": true, + "value": -1.9952209093318234, + "lb": null, + "ub": null + } + } + }, + "log_k_eq_constraint": { + "__type__": "", + "__id__": 529, + "active": true, + "data": { + "'bicarbonate'": { + "__type__": "", + "__id__": 530, + "active": true + }, + "'carbamate'": { + "__type__": "", + "__id__": 531, + "active": true + } + } + }, + "inherent_equilibrium_constraint": { + "__type__": "", + "__id__": 532, + "active": true, + "data": { + "'bicarbonate'": { + "__type__": "", + "__id__": 533, + "active": true + }, + "'carbamate'": { + "__type__": "", + "__id__": 534, + "active": true + } + } + }, + "log_conc_mol_phase_comp_true": { + "__type__": "", + "__id__": 535, + "data": { + "('Liq', 'MEACOO_-')": { + "__type__": "", + "__id__": 536, + "fixed": false, + "stale": true, + "value": 6.885125051047207, + "lb": -50, + "ub": null + }, + "('Liq', 'HCO3_-')": { + "__type__": "", + "__id__": 537, + "fixed": false, + "stale": true, + "value": 3.7348620835640363, + "lb": -50, + "ub": null + }, + "('Liq', 'MEA_+')": { + "__type__": "", + "__id__": 538, + "fixed": false, + "stale": true, + "value": 6.927073634700902, + "lb": -50, + "ub": null + }, + "('Liq', 'H2O')": { + "__type__": "", + "__id__": 539, + "fixed": false, + "stale": true, + "value": 10.467953793784487, + "lb": -50, + "ub": null + }, + "('Liq', 'MEA')": { + "__type__": "", + "__id__": 540, + "fixed": false, + "stale": true, + "value": 8.028173210302837, + "lb": -50, + "ub": null + }, + "('Liq', 'CO2')": { + "__type__": "", + "__id__": 541, + "fixed": false, + "stale": true, + "value": -0.24892682551237147, + "lb": -50, + "ub": null + } + } + }, + "log_conc_mol_phase_comp_true_eq": { + "__type__": "", + "__id__": 542, + "active": true, + "data": { + "('Liq', 'MEACOO_-')": { + "__type__": "", + "__id__": 543, + "active": true + }, + "('Liq', 'HCO3_-')": { + "__type__": "", + "__id__": 544, + "active": true + }, + "('Liq', 'MEA_+')": { + "__type__": "", + "__id__": 545, + "active": true + }, + "('Liq', 'H2O')": { + "__type__": "", + "__id__": 546, + "active": true + }, + "('Liq', 'MEA')": { + "__type__": "", + "__id__": 547, + "active": true + }, + "('Liq', 'CO2')": { + "__type__": "", + "__id__": 548, + "active": true + } + } + }, + "conc_mol_phase_comp_true": { + "__type__": "", + "__id__": 549, + "data": { + "('Liq', 'MEACOO_-')": { + "__type__": "", + "__id__": 550 + }, + "('Liq', 'HCO3_-')": { + "__type__": "", + "__id__": 551 + }, + "('Liq', 'MEA_+')": { + "__type__": "", + "__id__": 552 + }, + "('Liq', 'H2O')": { + "__type__": "", + "__id__": 553 + }, + "('Liq', 'MEA')": { + "__type__": "", + "__id__": 554 + }, + "('Liq', 'CO2')": { + "__type__": "", + "__id__": 555 + } + } + }, + "dens_mol_phase": { + "__type__": "", + "__id__": 556, + "data": { + "'Liq'": { + "__type__": "", + "__id__": 557 + } + } + }, + "vol_mol_phase": { + "__type__": "", + "__id__": 558, + "data": { + "'Liq'": { + "__type__": "", + "__id__": 559 + } + } + }, + "_enthalpy_flow_term": { + "__type__": "", + "__id__": 560, + "data": { + "'Liq'": { + "__type__": "", + "__id__": 561 + } + } + }, + "enth_mol_phase": { + "__type__": "", + "__id__": 562, + "data": { + "'Liq'": { + "__type__": "", + "__id__": 563 + } + } + }, + "fug_phase_comp": { + "__type__": "", + "__id__": 564, + "data": { + "('Liq', 'H2O')": { + "__type__": "", + "__id__": 565 + }, + "('Liq', 'MEA')": { + "__type__": "", + "__id__": 566 + }, + "('Liq', 'CO2')": { + "__type__": "", + "__id__": 567 + } + } + } + } + } + } + }, + "mass_transfer_term": { + "__type__": "", + "__id__": 568, + "data": { + "(0.0, 'Liq', 'H2O')": { + "__type__": "", + "__id__": 569, + "fixed": false, + "stale": true, + "value": -8.753563006611406, + "lb": null, + "ub": null + }, + "(0.0, 'Liq', 'MEA')": { + "__type__": "", + "__id__": 570, + "fixed": false, + "stale": true, + "value": 0.0, + "lb": null, + "ub": null + }, + "(0.0, 'Liq', 'CO2')": { + "__type__": "", + "__id__": 571, + "fixed": false, + "stale": true, + "value": -0.9006798556182657, + "lb": null, + "ub": null + } + } + }, + "material_balances": { + "__type__": "", + "__id__": 572, + "active": true, + "data": { + "(0.0, 'H2O')": { + "__type__": "", + "__id__": 573, + "active": true + }, + "(0.0, 'MEA')": { + "__type__": "", + "__id__": 574, + "active": true + }, + "(0.0, 'CO2')": { + "__type__": "", + "__id__": 575, + "active": true + } + } + }, + "heat": { + "__type__": "", + "__id__": 576, + "data": { + "0.0": { + "__type__": "", + "__id__": 577, + "fixed": true, + "stale": false, + "value": 430610.0, + "lb": null, + "ub": null + } + } + }, + "enthalpy_transfer": { + "__type__": "", + "__id__": 578, + "data": { + "0.0": { + "__type__": "", + "__id__": 579, + "fixed": false, + "stale": true, + "value": -31436.917285009382, + "lb": null, + "ub": null + } + } + }, + "enthalpy_balances": { + "__type__": "", + "__id__": 580, + "active": true, + "data": { + "0.0": { + "__type__": "", + "__id__": 581, + "active": true + } + } + }, + "pressure_balance": { + "__type__": "", + "__id__": 582, + "active": true, + "data": { + "0.0": { + "__type__": "", + "__id__": 583, + "active": true + } + } + } + } + } + } + }, + "vapor_phase": { + "__type__": "", + "__id__": 584, + "active": true, + "data": { + "0.0": { + "__type__": "", + "__id__": 585, + "active": true, + "__pyomo_components__": { + "flow_mol": { + "__type__": "", + "__id__": 586, + "data": { + "None": { + "__type__": "", + "__id__": 587, + "fixed": false, + "stale": true, + "value": 9.654242880699712, + "lb": 0, + "ub": 1000 + } + } + }, + "mole_frac_comp": { + "__type__": "", + "__id__": 588, + "data": { + "'CO2'": { + "__type__": "", + "__id__": 589, + "fixed": false, + "stale": true, + "value": 0.09329368098186078, + "lb": 1e-20, + "ub": 1.001 + }, + "'H2O'": { + "__type__": "", + "__id__": 590, + "fixed": false, + "stale": true, + "value": 0.9067063170785427, + "lb": 1e-20, + "ub": 1.001 + }, + "'N2'": { + "__type__": "", + "__id__": 591, + "fixed": false, + "stale": true, + "value": 1.055489275565956e-09, + "lb": 1e-20, + "ub": 1.001 + }, + "'O2'": { + "__type__": "", + "__id__": 592, + "fixed": false, + "stale": true, + "value": 1.0552516627768548e-09, + "lb": 1e-20, + "ub": 1.001 + } + } + }, + "pressure": { + "__type__": "", + "__id__": 593, + "data": { + "None": { + "__type__": "", + "__id__": 594, + "fixed": false, + "stale": true, + "value": 183700.0, + "lb": 50000.0, + "ub": 1000000.0 + } + } + }, + "temperature": { + "__type__": "", + "__id__": 595, + "data": { + "None": { + "__type__": "", + "__id__": 596, + "fixed": false, + "stale": true, + "value": 392.64275063606675, + "lb": 273.15, + "ub": 450 + } + } + }, + "flow_mol_phase": { + "__type__": "", + "__id__": 597, + "data": { + "'Vap'": { + "__type__": "", + "__id__": 598, + "fixed": false, + "stale": true, + "value": 9.654242880699712, + "lb": 0, + "ub": 1000 + } + } + }, + "mole_frac_phase_comp": { + "__type__": "", + "__id__": 599, + "data": { + "('Vap', 'CO2')": { + "__type__": "", + "__id__": 600, + "fixed": false, + "stale": true, + "value": 0.09329368098186078, + "lb": 1e-20, + "ub": 1.001 + }, + "('Vap', 'H2O')": { + "__type__": "", + "__id__": 601, + "fixed": false, + "stale": true, + "value": 0.9067063170785427, + "lb": 1e-20, + "ub": 1.001 + }, + "('Vap', 'N2')": { + "__type__": "", + "__id__": 602, + "fixed": false, + "stale": true, + "value": 1.055489275565956e-09, + "lb": 1e-20, + "ub": 1.001 + }, + "('Vap', 'O2')": { + "__type__": "", + "__id__": 603, + "fixed": false, + "stale": true, + "value": 1.0552516627768548e-09, + "lb": 1e-20, + "ub": 1.001 + } + } + }, + "flow_mol_phase_comp": { + "__type__": "", + "__id__": 604, + "data": { + "('Vap', 'CO2')": { + "__type__": "", + "__id__": 605 + }, + "('Vap', 'H2O')": { + "__type__": "", + "__id__": 606 + }, + "('Vap', 'N2')": { + "__type__": "", + "__id__": 607 + }, + "('Vap', 'O2')": { + "__type__": "", + "__id__": 608 + } + } + }, + "phase_frac": { + "__type__": "", + "__id__": 609, + "data": { + "'Vap'": { + "__type__": "", + "__id__": 610, + "fixed": false, + "stale": true, + "value": 1.0, + "lb": 0, + "ub": null + } + } + }, + "sum_mole_frac_out": { + "__type__": "", + "__id__": 611, + "active": true, + "data": { + "None": { + "__type__": "", + "__id__": 612, + "active": true + } + } + }, + "total_flow_balance": { + "__type__": "", + "__id__": 613, + "active": true, + "data": { + "None": { + "__type__": "", + "__id__": 614, + "active": true + } + } + }, + "component_flow_balances": { + "__type__": "", + "__id__": 615, + "active": true, + "data": { + "'CO2'": { + "__type__": "", + "__id__": 616, + "active": true + }, + "'H2O'": { + "__type__": "", + "__id__": 617, + "active": true + }, + "'N2'": { + "__type__": "", + "__id__": 618, + "active": true + }, + "'O2'": { + "__type__": "", + "__id__": 619, + "active": true + } + } + }, + "phase_fraction_constraint": { + "__type__": "", + "__id__": 620, + "active": true, + "data": { + "'Vap'": { + "__type__": "", + "__id__": 621, + "active": true + } + } + }, + "fug_phase_comp": { + "__type__": "", + "__id__": 622, + "data": { + "('Vap', 'CO2')": { + "__type__": "", + "__id__": 623 + }, + "('Vap', 'H2O')": { + "__type__": "", + "__id__": 624 + }, + "('Vap', 'N2')": { + "__type__": "", + "__id__": 625 + }, + "('Vap', 'O2')": { + "__type__": "", + "__id__": 626 + } + } + }, + "_enthalpy_flow_term": { + "__type__": "", + "__id__": 627, + "data": { + "'Vap'": { + "__type__": "", + "__id__": 628 + } + } + }, + "enth_mol_phase": { + "__type__": "", + "__id__": 629, + "data": { + "'Vap'": { + "__type__": "", + "__id__": 630 + } + } + }, + "enth_mol_phase_comp": { + "__type__": "", + "__id__": 631, + "data": { + "('Vap', 'CO2')": { + "__type__": "", + "__id__": 632 + }, + "('Vap', 'H2O')": { + "__type__": "", + "__id__": 633 + }, + "('Vap', 'N2')": { + "__type__": "", + "__id__": 634 + }, + "('Vap', 'O2')": { + "__type__": "", + "__id__": 635 + } + } + } + } + } + } + }, + "_flow_mol_inlet_ref": { + "__type__": "", + "__id__": 636, + "data": { + "0.0": { + "__type__": "", + "__id__": 637, + "fixed": true, + "stale": false, + "value": 83.89, + "lb": 0, + "ub": 1000 + } + } + }, + "_mole_frac_comp_inlet_ref": { + "__type__": "", + "__id__": 638, + "data": { + "(0.0, 'H2O')": { + "__type__": "", + "__id__": 639, + "fixed": true, + "stale": false, + "value": 0.8589, + "lb": 1e-20, + "ub": 1.001 + }, + "(0.0, 'MEA')": { + "__type__": "", + "__id__": 640, + "fixed": true, + "stale": false, + "value": 0.1085, + "lb": 1e-20, + "ub": 1.001 + }, + "(0.0, 'CO2')": { + "__type__": "", + "__id__": 641, + "fixed": true, + "stale": false, + "value": 0.0326, + "lb": 1e-20, + "ub": 1.001 + } + } + }, + "_temperature_inlet_ref": { + "__type__": "", + "__id__": 642, + "data": { + "0.0": { + "__type__": "", + "__id__": 643, + "fixed": true, + "stale": false, + "value": 392.5, + "lb": 273.15, + "ub": 450 + } + } + }, + "_pressure_inlet_ref": { + "__type__": "", + "__id__": 644, + "data": { + "0.0": { + "__type__": "", + "__id__": 645, + "fixed": true, + "stale": false, + "value": 183700, + "lb": 50000.0, + "ub": 1000000.0 + } + } + }, + "_flow_mol_bottoms_ref": { + "__type__": "", + "__id__": 646, + "data": { + "0.0": { + "__type__": "", + "__id__": 647, + "fixed": false, + "stale": true, + "value": 74.23575715286673, + "lb": 0, + "ub": 1000 + } + } + }, + "_mole_frac_comp_bottoms_ref": { + "__type__": "", + "__id__": 648, + "data": { + "(0.0, 'H2O')": { + "__type__": "", + "__id__": 649, + "fixed": false, + "stale": true, + "value": 0.8526828636361445, + "lb": 1e-20, + "ub": 1.001 + }, + "(0.0, 'MEA')": { + "__type__": "", + "__id__": 650, + "fixed": false, + "stale": true, + "value": 0.12261025345451311, + "lb": 1e-20, + "ub": 1.001 + }, + "(0.0, 'CO2')": { + "__type__": "", + "__id__": 651, + "fixed": false, + "stale": true, + "value": 0.024706882701208462, + "lb": 1e-20, + "ub": 1.001 + } + } + }, + "_temperature_bottoms_ref": { + "__type__": "", + "__id__": 652, + "data": { + "0.0": { + "__type__": "", + "__id__": 653, + "fixed": false, + "stale": true, + "value": 392.64275063606675, + "lb": 273.15, + "ub": 450 + } + } + }, + "_pressure_bottoms_ref": { + "__type__": "", + "__id__": 654, + "data": { + "0.0": { + "__type__": "", + "__id__": 655, + "fixed": false, + "stale": true, + "value": 183700.0, + "lb": 50000.0, + "ub": 1000000.0 + } + } + }, + "_flow_mol_vapor_reboil_ref": { + "__type__": "", + "__id__": 656, + "data": { + "0.0": { + "__type__": "", + "__id__": 657, + "fixed": false, + "stale": true, + "value": 9.654242880699712, + "lb": 0, + "ub": 1000 + } + } + }, + "_mole_frac_comp_vapor_reboil_ref": { + "__type__": "", + "__id__": 658, + "data": { + "(0.0, 'CO2')": { + "__type__": "", + "__id__": 659, + "fixed": false, + "stale": true, + "value": 0.09329368098186078, + "lb": 1e-20, + "ub": 1.001 + }, + "(0.0, 'H2O')": { + "__type__": "", + "__id__": 660, + "fixed": false, + "stale": true, + "value": 0.9067063170785427, + "lb": 1e-20, + "ub": 1.001 + }, + "(0.0, 'N2')": { + "__type__": "", + "__id__": 661, + "fixed": false, + "stale": true, + "value": 1.055489275565956e-09, + "lb": 1e-20, + "ub": 1.001 + }, + "(0.0, 'O2')": { + "__type__": "", + "__id__": 662, + "fixed": false, + "stale": true, + "value": 1.0552516627768548e-09, + "lb": 1e-20, + "ub": 1.001 + } + } + }, + "_temperature_vapor_reboil_ref": { + "__type__": "", + "__id__": 663, + "data": { + "0.0": { + "__type__": "", + "__id__": 664, + "fixed": false, + "stale": true, + "value": 392.64275063606675, + "lb": 273.15, + "ub": 450 + } + } + }, + "_pressure_vapor_reboil_ref": { + "__type__": "", + "__id__": 665, + "data": { + "0.0": { + "__type__": "", + "__id__": 666, + "fixed": false, + "stale": true, + "value": 183700.0, + "lb": 50000.0, + "ub": 1000000.0 + } + } + }, + "zero_flow_param": { + "__type__": "", + "__id__": 667, + "_mutable": true, + "data": { + "None": { + "__type__": "", + "__id__": 668, + "value": 1e-08 + } + } + }, + "unit_material_balance": { + "__type__": "", + "__id__": 669, + "active": true, + "data": { + "(0.0, 'CO2')": { + "__type__": "", + "__id__": 670, + "active": true + }, + "(0.0, 'H2O')": { + "__type__": "", + "__id__": 671, + "active": true + }, + "(0.0, 'N2')": { + "__type__": "", + "__id__": 672, + "active": true + }, + "(0.0, 'O2')": { + "__type__": "", + "__id__": 673, + "active": true + }, + "(0.0, 'MEA')": { + "__type__": "", + "__id__": 674, + "active": true + } + } + }, + "unit_phase_equilibrium": { + "__type__": "", + "__id__": 675, + "active": true, + "data": { + "(0.0, 'CO2')": { + "__type__": "", + "__id__": 676, + "active": true + }, + "(0.0, 'H2O')": { + "__type__": "", + "__id__": 677, + "active": true + } + } + }, + "unit_temperature_equality": { + "__type__": "", + "__id__": 678, + "active": true, + "data": { + "0.0": { + "__type__": "", + "__id__": 679, + "active": true + } + } + }, + "unit_enthalpy_balance": { + "__type__": "", + "__id__": 680, + "active": true, + "data": { + "0.0": { + "__type__": "", + "__id__": 681, + "active": true + } + } + }, + "unit_pressure_balance": { + "__type__": "", + "__id__": 682, + "active": true, + "data": { + "0.0": { + "__type__": "", + "__id__": 683, + "active": true + } + } + }, + "heat_duty": { + "__type__": "", + "__id__": 684, + "data": { + "0.0": { + "__type__": "", + "__id__": 685, + "fixed": true, + "stale": false, + "value": 430610.0, + "lb": null, + "ub": null + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } +} \ No newline at end of file