Hide code cell content
###############################################################################
# The Institute for the Design of Advanced Energy Systems Integrated Platform
# Framework (IDAES IP) was produced under the DOE Institute for the
# Design of Advanced Energy Systems (IDAES).
#
# Copyright (c) 2018-2023 by the software owners: The Regents of the
# University of California, through Lawrence Berkeley National Laboratory,
# National Technology & Engineering Solutions of Sandia, LLC, Carnegie Mellon
# University, West Virginia University Research Corporation, et al.
# All rights reserved.  Please see the files COPYRIGHT.md and LICENSE.md
# for full copyright and license information.
###############################################################################

Using Parameter Estimation with Modular Property Packages#

Author: Alejandro Garciadego
Maintainer: Andrew Lee
Updated: 2023-06-01

1. Introduction#

This Jupyter Notebook estimates binary interaction parameters for a CO\(_2\)-Ionic liquid property package. A property package has been created for CO\(_2\)-[bmim][PF6]. We will utilize Pyomo’s parmest tool in conjunction with IDAES models for parameter estimation. We demonstrate these tools by estimating the parameters associated with the Peng-Robinson property model for a benzene-toluene mixture. The Peng-Robinson EOS the binary interaction parameter (kappa_ij). When estimating parameters associated with the property package, IDAES provides the flexibility of doing the parameter estimation by just using the state block or by using a unit model with a specified property package. This module will demonstrate parameter estimation by using the flash unit model with a Modular Property Package.

1.1 Tutorial objectives#

  • Utilize the Modular Property Package framework, which provides a flexible platform for users to build property packages by calling upon libraries of modular sub-models to build up complex property calculations with the least effort possible.

  • Set up a method to return an initialized model

  • Set up the parameter estimation problem using parmest

2. Problem Statement#

2.1 Importing Pyomo and IDAES model and flowsheet components.#

In the next cell, we will be importing the necessary components from Pyomo and IDAES.

# Import objects from pyomo package
from pyomo.environ import ConcreteModel, SolverFactory, units as pyunits

# Import the main FlowsheetBlock from IDAES. The flowsheet block will contain the unit model
from idaes.core import FlowsheetBlock

# Import idaes logger to set output levels
import idaes.logger as idaeslog

# Import Flash unit model from idaes.models.unit_models
from idaes.models.unit_models import Flash

2.2 Import parmest#

import pyomo.contrib.parmest.parmest as parmest

2.3 Import the Modular Property framework#

from idaes.models.properties.modular_properties.examples.CO2_bmimPF6_PR import (
    configuration,
)

from idaes.models.properties.modular_properties import GenericParameterBlock

2.4 Import data#

In the next cell, we will be importing pandas and the .csv file with preassure and composition data. For this example, we load data from the csv file CO2_IL_298.csv. The dataset consists of ninteen data points which provide the mole fraction of [bmim][PF6] and carbon dioxide and the pressure at three different temperatures.

import pandas as pd

# Load data from csv
data = pd.read_csv("CO2_IL_298.csv")

3.0 Setting up an initialized model#

We need to provide a method that returns an initialized model to the parmest tool in Pyomo.

How we build the model will depend on the data we provided in the data dataframe from pir .csv file.

In this case we have data on the liquid mixture, the temperature and the pressure. We will fix the temperature, mole franction in the liquid phase, and the mole fraction of the inlet.

def PR_model(data):

    m = ConcreteModel()

    m.fs = FlowsheetBlock(dynamic=False)

    m.fs.properties = GenericParameterBlock(**configuration)

    m.fs.state_block = m.fs.properties.build_state_block([1], defined_state=True)

    m.fs.state_block[1].flow_mol.fix(1)
    x = float(data["x_carbon_dioxide"]) + 0.5
    m.fs.state_block[1].temperature.fix(float(data["temperature"]))
    m.fs.state_block[1].pressure.fix(float(data["pressure"]))
    m.fs.state_block[1].mole_frac_comp["bmimPF6"].fix(1 - x)
    m.fs.state_block[1].mole_frac_comp["carbon_dioxide"].fix(x)

    # parameter - kappa_ij (set at 0.3, 0 if i=j)
    m.fs.properties.PR_kappa["bmimPF6", "bmimPF6"].fix(0)
    m.fs.properties.PR_kappa["bmimPF6", "carbon_dioxide"].fix(-0.047)
    m.fs.properties.PR_kappa["carbon_dioxide", "carbon_dioxide"].fix(0)
    m.fs.properties.PR_kappa["carbon_dioxide", "bmimPF6"].fix(0.002)

    # Initialize the flash unit
    m.fs.state_block.initialize(outlvl=idaeslog.INFO)

    # Fix the state variables on the state block
    m.fs.state_block[1].pressure.unfix()
    m.fs.state_block[1].temperature.fix(float(data["temperature"]))
    m.fs.state_block[1].mole_frac_phase_comp["Liq", "bmimPF6"].fix(
        float(data["x_bmimPF6"])
    )
    m.fs.state_block[1].mole_frac_phase_comp["Liq", "carbon_dioxide"].fix(
        float(data["x_carbon_dioxide"])
    )
    m.fs.state_block[1].mole_frac_comp["bmimPF6"].fix(float(data["x_bmimPF6"]))
    m.fs.state_block[1].mole_frac_comp["carbon_dioxide"].unfix()
    # Set bounds on variables to be estimated
    m.fs.properties.PR_kappa["bmimPF6", "carbon_dioxide"].setlb(-5)
    m.fs.properties.PR_kappa["bmimPF6", "carbon_dioxide"].setub(5)

    m.fs.properties.PR_kappa["carbon_dioxide", "bmimPF6"].setlb(-5)
    m.fs.properties.PR_kappa["carbon_dioxide", "bmimPF6"].setub(5)

    # Return initialized flash model
    return m

3.1 Solving square problem#

from idaes.core.util.model_statistics import degrees_of_freedom
import pytest

test_data = {
    "temperature": 298,
    "pressure": 812323,
    "x_bmimPF6": 0.86,
    "x_carbon_dioxide": 0.14,
}

m = PR_model(test_data)

# Check that degrees of freedom is 0
assert degrees_of_freedom(m) == 0
ERROR: Rule failed when generating expression for Constraint
fs.state_block[1].eq_temperature_bubble with index ('Vap', 'Liq',
'carbon_dioxide'): RuntimeError: Cubic root external functions are not
available.
ERROR: Constructing component 'fs.state_block[1].eq_temperature_bubble' from
data=None failed:
        RuntimeError: Cubic root external functions are not available.
ERROR: Rule failed when generating expression for Constraint
fs.state_block[1]._t1_constraint_Vap_Liq with index None: RuntimeError: Cubic
root external functions are not available.
ERROR: Constructing component 'fs.state_block[1]._t1_constraint_Vap_Liq' from
data=None failed:
        RuntimeError: Cubic root external functions are not available.
2024-05-09 18:34:58 [ERROR] idaes.core.base.process_block: Failure in build: fs.state_block[1]
Traceback (most recent call last):
  File "/home/docs/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/idaes/core/base/property_base.py", line 792, in __getattr__
    return super().__getattr__(attr)
  File "/home/docs/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/pyomo/core/base/block.py", line 550, in __getattr__
    raise AttributeError(
AttributeError: 'GenericStateBlockData' object has no attribute 'temperature_bubble'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/docs/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/idaes/core/base/process_block.py", line 41, in _rule_default
    b.build()
  File "/home/docs/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/idaes/models/properties/modular_properties/base/generic_property.py", line 2446, in build
    pe_form_config[pp].phase_equil(self, pp)
  File "/home/docs/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/idaes/models/properties/modular_properties/phase_equil/smooth_VLE.py", line 94, in phase_equil
    b.add_component("_t1_constraint" + suffix, Constraint(rule=rule_t1))
  File "/home/docs/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/pyomo/core/base/block.py", line 1129, in add_component
    val.construct(data)
  File "/home/docs/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/pyomo/core/base/disable_methods.py", line 124, in construct
    return base.construct(self, data)
  File "/home/docs/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/pyomo/core/base/constraint.py", line 720, in construct
    self._setitem_when_not_present(index, rule(block, index))
  File "/home/docs/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/pyomo/core/base/initializer.py", line 438, in __call__
    return self._fcn(parent)
  File "/home/docs/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/idaes/models/properties/modular_properties/phase_equil/smooth_VLE.py", line 91, in rule_t1
    b.temperature, b.temperature_bubble[phase_pair], eps_1
  File "/home/docs/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/idaes/core/base/property_base.py", line 794, in __getattr__
    return build_on_demand(self, attr)
  File "/home/docs/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/idaes/core/base/util.py", line 220, in build_on_demand
    f()
  File "/home/docs/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/idaes/models/properties/modular_properties/base/generic_property.py", line 3036, in _temperature_bubble
    _temperature_pressure_bubble_dew(b, "temperature_bubble")
  File "/home/docs/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/idaes/models/properties/modular_properties/base/generic_property.py", line 5069, in _temperature_pressure_bubble_dew
    tmp(b)
  File "/home/docs/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/idaes/models/properties/modular_properties/phase_equil/bubble_dew.py", line 527, in temperature_bubble
    b.eq_temperature_bubble = Constraint(
  File "/home/docs/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/pyomo/core/base/block.py", line 571, in __setattr__
    self.add_component(name, val)
  File "/home/docs/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/pyomo/core/base/block.py", line 1129, in add_component
    val.construct(data)
  File "/home/docs/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/pyomo/core/base/constraint.py", line 720, in construct
    self._setitem_when_not_present(index, rule(block, index))
  File "/home/docs/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/pyomo/core/base/initializer.py", line 314, in __call__
    return self._fcn(parent, *idx)
  File "/home/docs/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/idaes/models/properties/modular_properties/phase_equil/bubble_dew.py", line 521, in rule_bubble_temp
    return l_eos.log_fug_phase_comp_Tbub(
  File "/home/docs/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/idaes/models/properties/modular_properties/eos/ceos.py", line 819, in log_fug_phase_comp_Tbub
    return _bubble_dew_log_fug_coeff_method(blk, p, j, pp, blk.temperature_bubble)
  File "/home/docs/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/idaes/models/properties/modular_properties/eos/ceos.py", line 1343, in _bubble_dew_log_fug_coeff_method
    expr_write = CubicThermoExpressions(blk)
  File "/home/docs/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/idaes/models/properties/modular_properties/eos/ceos_common.py", line 106, in __init__
    raise RuntimeError("Cubic root external functions are not available.")
RuntimeError: Cubic root external functions are not available.
ERROR: Constructing component 'fs.state_block' from data=None failed:
        RuntimeError: Cubic root external functions are not available.
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
File ~/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/idaes/core/base/property_base.py:792, in StateBlockData.__getattr__(self, attr)
    788 try:
    789     # try the Pyomo Block's __getattr__ method first which will return
    790     # decorators for creating components on the block (e.g. Expression,
    791     # Constraint, ...).
--> 792     return super().__getattr__(attr)
    793 except AttributeError:

File ~/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/pyomo/core/base/block.py:550, in BlockData.__getattr__(self, val)
    548 # Since the base classes don't support getattr, we can just
    549 # throw the "normal" AttributeError
--> 550 raise AttributeError(
    551     "'%s' object has no attribute '%s'" % (self.__class__.__name__, val)
    552 )

AttributeError: 'GenericStateBlockData' object has no attribute 'temperature_bubble'

During handling of the above exception, another exception occurred:

RuntimeError                              Traceback (most recent call last)
Cell In[7], line 11
      2 import pytest
      4 test_data = {
      5     "temperature": 298,
      6     "pressure": 812323,
      7     "x_bmimPF6": 0.86,
      8     "x_carbon_dioxide": 0.14,
      9 }
---> 11 m = PR_model(test_data)
     13 # Check that degrees of freedom is 0
     14 assert degrees_of_freedom(m) == 0

Cell In[6], line 9, in PR_model(data)
      5 m.fs = FlowsheetBlock(dynamic=False)
      7 m.fs.properties = GenericParameterBlock(**configuration)
----> 9 m.fs.state_block = m.fs.properties.build_state_block([1], defined_state=True)
     11 m.fs.state_block[1].flow_mol.fix(1)
     12 x = float(data["x_carbon_dioxide"]) + 0.5

File ~/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/pyomo/core/base/block.py:571, in BlockData.__setattr__(self, name, val)
    566 if name not in self.__dict__:
    567     if isinstance(val, Component):
    568         #
    569         # Pyomo components are added with the add_component method.
    570         #
--> 571         self.add_component(name, val)
    572     else:
    573         #
    574         # Other Python objects are added with the standard __setattr__
    575         # method.
    576         #
    577         super(BlockData, self).__setattr__(name, val)

File ~/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/pyomo/core/base/block.py:1129, in BlockData.add_component(self, name, val)
   1121     logger.debug(
   1122         "Constructing %s '%s' on %s from data=%s",
   1123         val.__class__.__name__,
   (...)
   1126         str(data),
   1127     )
   1128 try:
-> 1129     val.construct(data)
   1130 except:
   1131     err = sys.exc_info()[1]

File ~/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/pyomo/core/base/block.py:2162, in Block.construct(self, data)
   2157     if self.index_set().isfinite() and (
   2158         self._dense or self._rule is not None
   2159     ):
   2160         for _idx in self.index_set():
   2161             # Trigger population & call the rule
-> 2162             self._getitem_when_not_present(_idx)
   2163 else:
   2164     # We must check that any pre-existing components are
   2165     # constructed.  This catches the case where someone is
   2166     # building a Concrete model by building (potentially
   2167     # pseudo-abstract) sub-blocks and then adding them to a
   2168     # Concrete model block.
   2169     _idx = next(iter(UnindexedComponent_set))

File ~/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/pyomo/core/base/block.py:2101, in Block._getitem_when_not_present(self, idx)
   2098     data = None
   2100 try:
-> 2101     obj = self._rule(_block, idx)
   2102     # If the user returns a block, transfer over everything
   2103     # they defined into the empty one we created.  We do
   2104     # this inside the try block so that any abstract
   2105     # components declared by the rule have the opportunity
   2106     # to be initialized with data from
   2107     # _BlockConstruction.data as they are transferred over.
   2108     if obj is not _block and isinstance(obj, BlockData):

File ~/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/pyomo/core/base/initializer.py:316, in IndexedCallInitializer.__call__(self, parent, idx)
    314     return self._fcn(parent, *idx)
    315 else:
--> 316     return self._fcn(parent, idx)

File ~/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/idaes/core/base/process_block.py:41, in _rule_default(b, *args)
     35 """
     36 Default rule for ProcessBlock, which calls build(). A different rule can
     37 be specified to add additional build steps, or to not call build at all
     38 using the normal rule argument to ProcessBlock init.
     39 """
     40 try:
---> 41     b.build()
     42 except Exception:
     43     logging.getLogger(__name__).exception(f"Failure in build: {b}")

File ~/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/idaes/models/properties/modular_properties/base/generic_property.py:2446, in GenericStateBlockData.build(self)
   2444 pe_form_config = self.params.config.phase_equilibrium_state
   2445 for pp in self.params._pe_pairs:
-> 2446     pe_form_config[pp].phase_equil(self, pp)
   2448 def rule_equilibrium(b, phase1, phase2, j):
   2449     if (phase1, j) not in b.phase_component_set or (
   2450         phase2,
   2451         j,
   2452     ) not in b.phase_component_set:

File ~/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/idaes/models/properties/modular_properties/phase_equil/smooth_VLE.py:94, in SmoothVLE.phase_equil(b, phase_pair)
     89     def rule_t1(b):
     90         return _t1 == smooth_max(
     91             b.temperature, b.temperature_bubble[phase_pair], eps_1
     92         )
---> 94     b.add_component("_t1_constraint" + suffix, Constraint(rule=rule_t1))
     95 else:
     96     _t1 = b.temperature

File ~/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/pyomo/core/base/block.py:1129, in BlockData.add_component(self, name, val)
   1121     logger.debug(
   1122         "Constructing %s '%s' on %s from data=%s",
   1123         val.__class__.__name__,
   (...)
   1126         str(data),
   1127     )
   1128 try:
-> 1129     val.construct(data)
   1130 except:
   1131     err = sys.exc_info()[1]

File ~/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/pyomo/core/base/disable_methods.py:124, in disable_methods.<locals>.class_decorator.<locals>.construct(self, data)
    122     self._name = base.__name__
    123 self.__class__ = base
--> 124 return base.construct(self, data)

File ~/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/pyomo/core/base/constraint.py:720, in Constraint.construct(self, data)
    717     else:
    718         # Bypass the index validation and create the member directly
    719         for index in self.index_set():
--> 720             self._setitem_when_not_present(index, rule(block, index))
    721 except Exception:
    722     err = sys.exc_info()[1]

File ~/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/pyomo/core/base/initializer.py:438, in ScalarCallInitializer.__call__(self, parent, idx)
    437 def __call__(self, parent, idx):
--> 438     return self._fcn(parent)

File ~/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/idaes/models/properties/modular_properties/phase_equil/smooth_VLE.py:91, in SmoothVLE.phase_equil.<locals>.rule_t1(b)
     89 def rule_t1(b):
     90     return _t1 == smooth_max(
---> 91         b.temperature, b.temperature_bubble[phase_pair], eps_1
     92     )

File ~/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/idaes/core/base/property_base.py:794, in StateBlockData.__getattr__(self, attr)
    792     return super().__getattr__(attr)
    793 except AttributeError:
--> 794     return build_on_demand(self, attr)

File ~/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/idaes/core/base/util.py:220, in build_on_demand(self, attr)
    218 if callable(f):
    219     try:
--> 220         f()
    221     except Exception:
    222         # Clear call list and reraise error
    223         clear_call_list(self, attr)

File ~/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/idaes/models/properties/modular_properties/base/generic_property.py:3036, in GenericStateBlockData._temperature_bubble(b)
   3035 def _temperature_bubble(b):
-> 3036     _temperature_pressure_bubble_dew(b, "temperature_bubble")

File ~/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/idaes/models/properties/modular_properties/base/generic_property.py:5069, in _temperature_pressure_bubble_dew(b, name)
   5055     setattr(
   5056         b,
   5057         "_mole_frac_" + abbrv,
   (...)
   5065         ),
   5066     )
   5068     tmp = getattr(b.params.config.bubble_dew_method, name)
-> 5069     tmp(b)
   5071 except AttributeError:
   5072     if hasattr(b, name):

File ~/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/idaes/models/properties/modular_properties/phase_equil/bubble_dew.py:527, in LogBubbleDew.temperature_bubble(b)
    524         else:
    525             return b._mole_frac_tbub[p1, p2, j] == 0
--> 527     b.eq_temperature_bubble = Constraint(
    528         b.params._pe_pairs, b.component_list, rule=rule_bubble_temp
    529     )
    530 except AttributeError:
    531     b.del_component(b.eq_temperature_bubble)

File ~/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/pyomo/core/base/block.py:571, in BlockData.__setattr__(self, name, val)
    566 if name not in self.__dict__:
    567     if isinstance(val, Component):
    568         #
    569         # Pyomo components are added with the add_component method.
    570         #
--> 571         self.add_component(name, val)
    572     else:
    573         #
    574         # Other Python objects are added with the standard __setattr__
    575         # method.
    576         #
    577         super(BlockData, self).__setattr__(name, val)

File ~/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/pyomo/core/base/block.py:1129, in BlockData.add_component(self, name, val)
   1121     logger.debug(
   1122         "Constructing %s '%s' on %s from data=%s",
   1123         val.__class__.__name__,
   (...)
   1126         str(data),
   1127     )
   1128 try:
-> 1129     val.construct(data)
   1130 except:
   1131     err = sys.exc_info()[1]

File ~/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/pyomo/core/base/constraint.py:720, in Constraint.construct(self, data)
    717     else:
    718         # Bypass the index validation and create the member directly
    719         for index in self.index_set():
--> 720             self._setitem_when_not_present(index, rule(block, index))
    721 except Exception:
    722     err = sys.exc_info()[1]

File ~/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/pyomo/core/base/initializer.py:314, in IndexedCallInitializer.__call__(self, parent, idx)
    308 def __call__(self, parent, idx):
    309     # Note: this is called by a component using data from a Set (so
    310     # any tuple-like type should have already been checked and
    311     # converted to a tuple; or flattening is turned off and it is
    312     # the user's responsibility to sort things out.
    313     if idx.__class__ is tuple:
--> 314         return self._fcn(parent, *idx)
    315     else:
    316         return self._fcn(parent, idx)

File ~/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/idaes/models/properties/modular_properties/phase_equil/bubble_dew.py:521, in LogBubbleDew.temperature_bubble.<locals>.rule_bubble_temp(b, p1, p2, j)
    518 v_eos = b.params.get_phase(v_phase).config.equation_of_state
    520 if j in vl_comps or j in henry_comps:
--> 521     return l_eos.log_fug_phase_comp_Tbub(
    522         b, l_phase, j, (p1, p2)
    523     ) == v_eos.log_fug_phase_comp_Tbub(b, v_phase, j, (p1, p2))
    524 else:
    525     return b._mole_frac_tbub[p1, p2, j] == 0

File ~/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/idaes/models/properties/modular_properties/eos/ceos.py:819, in Cubic.log_fug_phase_comp_Tbub(blk, p, j, pp)
    817 @staticmethod
    818 def log_fug_phase_comp_Tbub(blk, p, j, pp):
--> 819     return _bubble_dew_log_fug_coeff_method(blk, p, j, pp, blk.temperature_bubble)

File ~/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/idaes/models/properties/modular_properties/eos/ceos.py:1343, in _bubble_dew_log_fug_coeff_method(blk, p, j, pp, pt_var)
   1334 B = bm * P / (R * T)
   1336 delta = (
   1337     2
   1338     * sqrt(a(j))
   1339     / am
   1340     * sum(x[xidx, i] * sqrt(a(i)) * (1 - kappa[j, i]) for i in blk.component_list)
   1341 )
-> 1343 expr_write = CubicThermoExpressions(blk)
   1344 if pobj.is_vapor_phase():
   1345     Z = expr_write.z_vap(eos=pobj._cubic_type, A=A, B=B)

File ~/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/idaes/models/properties/modular_properties/eos/ceos_common.py:106, in CubicThermoExpressions.__init__(self, blk)
    104 def __init__(self, blk):
    105     if not cubic_roots_available():
--> 106         raise RuntimeError("Cubic root external functions are not available.")
    107     self.blk = blk

RuntimeError: Cubic root external functions are not available.

4.0 Parameter estimation using parmest#

4.1 List of variable names to be estimated#

Create a list of vars to estimate

variable_name = [
    "fs.properties.PR_kappa['bmimPF6', 'carbon_dioxide']",
    "fs.properties.PR_kappa['carbon_dioxide', 'bmimPF6']",
]

4.2 Create method to return an expression that computes the sum of squared error#

We need to provide a method to return an expression to compute the sum of squared errors that will be used as the objective in solving the parameter estimation problem. For this problem, the error will be computed for the pressure.

def SSE(m, data):
    expr = (float(data["pressure"]) - m.fs.state_block[1].pressure) ** 2
    return expr * 1e-7

4.3 Run the parameter estimation#

We are now ready to set up the parameter estimation problem. We will create a parameter estimation object called pest. As shown below, we pass the method that returns an initialized model, data, variable_name, and the SSE expression to the Estimator method. tee=True will print the solver output after solving the parameter estimation problem.

pest = parmest.Estimator(PR_model, data, variable_name, SSE, tee=True)

obj_value, parameters = pest.theta_est()
2023-11-02 10:30:00 [INFO] idaes.init.fs.state_block: Starting initialization
WARNING (W1002): Setting Var
'fs.state_block[1].log_mole_frac_tbub[Vap,Liq,carbon_dioxide]' to a numeric
value `4.301303339264284e-06` outside the bounds (None, 0).
    See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
2023-11-02 10:30:00 [INFO] idaes.init.fs.state_block: Dew and bubble point initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:00 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.
2023-11-02 10:30:00 [INFO] idaes.init.fs.state_block: State variable initialization completed.
2023-11-02 10:30:00 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.
C:\Users\dkgun\AppData\Local\Temp\ipykernel_28652\3856510393.py:12: FutureWarning: Calling float on a single element Series is deprecated and will raise a TypeError in the future. Use float(ser.iloc[0]) instead
  x = float(data["x_carbon_dioxide"]) + 0.5
C:\Users\dkgun\AppData\Local\Temp\ipykernel_28652\3856510393.py:13: FutureWarning: Calling float on a single element Series is deprecated and will raise a TypeError in the future. Use float(ser.iloc[0]) instead
  m.fs.state_block[1].temperature.fix(float(data["temperature"]))
C:\Users\dkgun\AppData\Local\Temp\ipykernel_28652\3856510393.py:14: FutureWarning: Calling float on a single element Series is deprecated and will raise a TypeError in the future. Use float(ser.iloc[0]) instead
  m.fs.state_block[1].pressure.fix(float(data["pressure"]))
2023-11-02 10:30:00 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:00 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:00 [INFO] idaes.init.fs.state_block: Starting initialization
WARNING (W1002): Setting Var
'fs.state_block[1].log_mole_frac_tbub[Vap,Liq,carbon_dioxide]' to a numeric
value `4.814447495739171e-09` outside the bounds (None, 0).
    See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
2023-11-02 10:30:00 [INFO] idaes.init.fs.state_block: Dew and bubble point initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:00 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.
2023-11-02 10:30:00 [INFO] idaes.init.fs.state_block: State variable initialization completed.
2023-11-02 10:30:00 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.
C:\Users\dkgun\AppData\Local\Temp\ipykernel_28652\3856510393.py:29: FutureWarning: Calling float on a single element Series is deprecated and will raise a TypeError in the future. Use float(ser.iloc[0]) instead
  m.fs.state_block[1].temperature.fix(float(data["temperature"]))
C:\Users\dkgun\AppData\Local\Temp\ipykernel_28652\3856510393.py:31: FutureWarning: Calling float on a single element Series is deprecated and will raise a TypeError in the future. Use float(ser.iloc[0]) instead
  float(data["x_bmimPF6"])
C:\Users\dkgun\AppData\Local\Temp\ipykernel_28652\3856510393.py:34: FutureWarning: Calling float on a single element Series is deprecated and will raise a TypeError in the future. Use float(ser.iloc[0]) instead
  float(data["x_carbon_dioxide"])
C:\Users\dkgun\AppData\Local\Temp\ipykernel_28652\3856510393.py:36: FutureWarning: Calling float on a single element Series is deprecated and will raise a TypeError in the future. Use float(ser.iloc[0]) instead
  m.fs.state_block[1].mole_frac_comp["bmimPF6"].fix(float(data["x_bmimPF6"]))
C:\Users\dkgun\AppData\Local\Temp\ipykernel_28652\1809745473.py:2: FutureWarning: Calling float on a single element Series is deprecated and will raise a TypeError in the future. Use float(ser.iloc[0]) instead
  expr = (float(data["pressure"]) - m.fs.state_block[1].pressure) ** 2
2023-11-02 10:30:00 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:00 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:00 [INFO] idaes.init.fs.state_block: Starting initialization
WARNING (W1002): Setting Var
'fs.state_block[1].log_mole_frac_tbub[Vap,Liq,carbon_dioxide]' to a numeric
value `6.357548229111755e-06` outside the bounds (None, 0).
    See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
2023-11-02 10:30:00 [INFO] idaes.init.fs.state_block: Dew and bubble point initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:00 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.
2023-11-02 10:30:00 [INFO] idaes.init.fs.state_block: State variable initialization completed.
2023-11-02 10:30:00 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: Starting initialization
WARNING (W1002): Setting Var
'fs.state_block[1].log_mole_frac_tbub[Vap,Liq,carbon_dioxide]' to a numeric
value `6.169320987299437e-07` outside the bounds (None, 0).
    See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: Dew and bubble point initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.
2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: State variable initialization completed.
2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: Starting initialization
WARNING (W1002): Setting Var
'fs.state_block[1].log_mole_frac_tbub[Vap,Liq,carbon_dioxide]' to a numeric
value `7.629131479751715e-08` outside the bounds (None, 0).
    See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: Dew and bubble point initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.
2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: State variable initialization completed.
2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: Starting initialization
WARNING (W1002): Setting Var
'fs.state_block[1].log_mole_frac_tbub[Vap,Liq,carbon_dioxide]' to a numeric
value `1.3059472085065408e-08` outside the bounds (None, 0).
    See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: Dew and bubble point initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.
2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: State variable initialization completed.
2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: Starting initialization
WARNING (W1002): Setting Var
'fs.state_block[1].log_mole_frac_tbub[Vap,Liq,carbon_dioxide]' to a numeric
value `4.761445527533956e-06` outside the bounds (None, 0).
    See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
2023-11-02 10:30:02 [INFO] idaes.init.fs.state_block: Dew and bubble point initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:02 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.
2023-11-02 10:30:02 [INFO] idaes.init.fs.state_block: State variable initialization completed.
2023-11-02 10:30:02 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:02 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:02 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:02 [INFO] idaes.init.fs.state_block: Starting initialization
WARNING (W1002): Setting Var
'fs.state_block[1].log_mole_frac_tbub[Vap,Liq,carbon_dioxide]' to a numeric
value `7.219204097329158e-09` outside the bounds (None, 0).
    See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
2023-11-02 10:30:02 [INFO] idaes.init.fs.state_block: Dew and bubble point initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:02 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.
2023-11-02 10:30:02 [INFO] idaes.init.fs.state_block: State variable initialization completed.
2023-11-02 10:30:02 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:02 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:02 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:02 [INFO] idaes.init.fs.state_block: Starting initialization
WARNING (W1002): Setting Var
'fs.state_block[1].log_mole_frac_tbub[Vap,Liq,carbon_dioxide]' to a numeric
value `1.03769179356835e-05` outside the bounds (None, 0).
    See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
2023-11-02 10:30:02 [INFO] idaes.init.fs.state_block: Dew and bubble point initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:02 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.
2023-11-02 10:30:02 [INFO] idaes.init.fs.state_block: State variable initialization completed.
2023-11-02 10:30:02 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:02 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:02 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:02 [INFO] idaes.init.fs.state_block: Starting initialization
WARNING (W1002): Setting Var
'fs.state_block[1].log_mole_frac_tbub[Vap,Liq,carbon_dioxide]' to a numeric
value `1.269889598521249e-06` outside the bounds (None, 0).
    See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: Dew and bubble point initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.
2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: State variable initialization completed.
2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: Starting initialization
WARNING (W1002): Setting Var
'fs.state_block[1].log_mole_frac_tbub[Vap,Liq,carbon_dioxide]' to a numeric
value `2.021447098567687e-07` outside the bounds (None, 0).
    See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: Dew and bubble point initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.
2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: State variable initialization completed.
2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: Starting initialization
WARNING (W1002): Setting Var
'fs.state_block[1].log_mole_frac_tbub[Vap,Liq,carbon_dioxide]' to a numeric
value `4.096574706592338e-08` outside the bounds (None, 0).
    See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: Dew and bubble point initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.
2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: State variable initialization completed.
2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: Starting initialization
WARNING (W1002): Setting Var
'fs.state_block[1].log_mole_frac_tbub[Vap,Liq,carbon_dioxide]' to a numeric
value `6.21086636630859e-06` outside the bounds (None, 0).
    See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: Dew and bubble point initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.
2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: State variable initialization completed.
2023-11-02 10:30:04 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:04 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:04 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:04 [INFO] idaes.init.fs.state_block: Starting initialization
WARNING (W1002): Setting Var
'fs.state_block[1].log_mole_frac_tbub[Vap,Liq,carbon_dioxide]' to a numeric
value `1.1919675619879674e-08` outside the bounds (None, 0).
    See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
2023-11-02 10:30:04 [INFO] idaes.init.fs.state_block: Dew and bubble point initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:04 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.
2023-11-02 10:30:04 [INFO] idaes.init.fs.state_block: State variable initialization completed.
2023-11-02 10:30:04 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:04 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:04 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:04 [INFO] idaes.init.fs.state_block: Starting initialization
WARNING (W1002): Setting Var
'fs.state_block[1].log_mole_frac_tbub[Vap,Liq,carbon_dioxide]' to a numeric
value `1.0197309662820167e-10` outside the bounds (None, 0).
    See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
2023-11-02 10:30:04 [INFO] idaes.init.fs.state_block: Dew and bubble point initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:04 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.
2023-11-02 10:30:04 [INFO] idaes.init.fs.state_block: State variable initialization completed.
2023-11-02 10:30:04 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:04 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:04 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:04 [INFO] idaes.init.fs.state_block: Starting initialization
WARNING (W1002): Setting Var
'fs.state_block[1].log_mole_frac_tbub[Vap,Liq,carbon_dioxide]' to a numeric
value `2.385494860297472e-06` outside the bounds (None, 0).
    See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
2023-11-02 10:30:05 [INFO] idaes.init.fs.state_block: Dew and bubble point initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:05 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.
2023-11-02 10:30:05 [INFO] idaes.init.fs.state_block: State variable initialization completed.
2023-11-02 10:30:05 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:05 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:05 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:05 [INFO] idaes.init.fs.state_block: Starting initialization
WARNING (W1002): Setting Var
'fs.state_block[1].log_mole_frac_tbub[Vap,Liq,carbon_dioxide]' to a numeric
value `4.578395178499122e-07` outside the bounds (None, 0).
    See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
2023-11-02 10:30:05 [INFO] idaes.init.fs.state_block: Dew and bubble point initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:05 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.
2023-11-02 10:30:05 [INFO] idaes.init.fs.state_block: State variable initialization completed.
2023-11-02 10:30:05 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:05 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:05 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:05 [INFO] idaes.init.fs.state_block: Starting initialization
WARNING (W1002): Setting Var
'fs.state_block[1].log_mole_frac_tbub[Vap,Liq,carbon_dioxide]' to a numeric
value `1.0835202436687703e-07` outside the bounds (None, 0).
    See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002
2023-11-02 10:30:05 [INFO] idaes.init.fs.state_block: Dew and bubble point initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:05 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.
2023-11-02 10:30:05 [INFO] idaes.init.fs.state_block: State variable initialization completed.
2023-11-02 10:30:05 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:05 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.
2023-11-02 10:30:05 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.
Ipopt 3.13.2: 

******************************************************************************
This program contains Ipopt, a library for large-scale nonlinear optimization.
 Ipopt is released as open source code under the Eclipse Public License (EPL).
         For more information visit http://projects.coin-or.org/Ipopt

This version of Ipopt was compiled from source code available at
    https://github.com/IDAES/Ipopt as part of the Institute for the Design of
    Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE
    Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.

This version of Ipopt was compiled using HSL, a collection of Fortran codes
    for large-scale scientific computation.  All technical papers, sales and
    publicity material resulting from use of the HSL codes within IPOPT must
    contain the following acknowledgement:
        HSL, a collection of Fortran codes for large-scale scientific
        computation. See http://www.hsl.rl.ac.uk.
******************************************************************************

This is Ipopt version 3.13.2, running with linear solver ma27.

Number of nonzeros in equality constraint Jacobian...:      842
Number of nonzeros in inequality constraint Jacobian.:        0
Number of nonzeros in Lagrangian Hessian.............:      720

Total number of variables............................:      360
                     variables with only lower bounds:       72
                variables with lower and upper bounds:      234
                     variables with only upper bounds:       18
Total number of equality constraints.................:      358
Total number of inequality constraints...............:        0
        inequality constraints with only lower bounds:        0
   inequality constraints with lower and upper bounds:        0
        inequality constraints with only upper bounds:        0

iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
   0  0.0000000e+00 5.00e-01 6.99e-14  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1  1.1422488e+01 2.60e-01 2.37e+03  -1.0 3.35e+04    -  3.39e-01 6.89e-01h  1
   2  2.8748813e+01 1.27e-01 1.10e+03  -1.0 1.36e+04    -  8.22e-02 9.88e-01h  1
   3  2.9813930e+01 1.87e-01 5.94e+02  -1.0 5.01e+02    -  8.73e-01 9.90e-01h  1
   4  2.9709737e+01 4.27e-02 1.57e+03  -1.0 5.49e+02    -  9.85e-01 9.90e-01h  1
   5  2.9285216e+01 8.02e-03 9.53e+04  -1.0 2.77e+03    -  9.87e-01 1.00e+00h  1
   6  2.9283589e+01 1.44e-04 9.56e+04  -1.0 3.48e+02    -  9.90e-01 1.00e+00h  1
   7  2.9283603e+01 7.59e-08 9.12e+02  -1.0 5.97e-01    -  9.90e-01 1.00e+00h  1
   8  2.9282891e+01 3.35e-07 1.47e+04  -2.5 1.24e+02    -  9.98e-01 1.00e+00f  1
   9  2.9282892e+01 2.21e-12 4.97e-08  -2.5 2.39e-01    -  1.00e+00 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10  2.9282891e+01 2.85e-10 3.05e+00  -8.6 3.61e+00    -  1.00e+00 1.00e+00h  1
  11  2.9282891e+01 2.72e-12 3.60e-12  -8.6 2.03e-04    -  1.00e+00 1.00e+00h  1

Number of Iterations....: 11

                                   (scaled)                 (unscaled)
Objective...............:   2.9282891309640156e+01    2.9282891309640156e+01
Dual infeasibility......:   3.6021722623181066e-12    3.6021722623181066e-12
Constraint violation....:   2.7191470654339899e-12    2.7191470654339899e-12
Complementarity.........:   2.5059037693947522e-09    2.5059037693947522e-09
Overall NLP error.......:   2.5059037693947522e-09    2.5059037693947522e-09


Number of objective function evaluations             = 12
Number of objective gradient evaluations             = 12
Number of equality constraint evaluations            = 12
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 12
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 11
Total CPU secs in IPOPT (w/o function evaluations)   =      0.000
Total CPU secs in NLP function evaluations           =      0.048

EXIT: Optimal Solution Found.


5.0 Display results#

Let us display the results by running the next cell.

print("The SSE at the optimal solution is %0.6f" % obj_value)
print()
print("The values for the parameters are as follows:")
for k, v in parameters.items():
    print(k, "=", v)
The SSE at the optimal solution is 29.282891

The values for the parameters are as follows:
fs.properties.PR_kappa[bmimPF6,carbon_dioxide] = -0.4071428400296551
fs.properties.PR_kappa[carbon_dioxide,bmimPF6] = 0.020593684002515204

Now we can use this parameters and include them in the configuration dictionary. We can also use m.fs.properties = GenericParameterBlock(**configuration) to solve unit models.