Show 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-2026 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: Stephen Cini
Updated: 2026-06-11
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, value, Suffix
# 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)
if isinstance(data, dict) or isinstance(data, pd.Series):
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"]))
elif isinstance(data, pd.DataFrame):
x = float(data.iloc[0]["x_carbon_dioxide"]) + 0.5
m.fs.state_block[1].temperature.fix(float(data.iloc[0]["temperature"]))
m.fs.state_block[1].pressure.fix(float(data.iloc[0]["pressure"]))
else:
raise ValueError("Unrecognized data type.")
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
if isinstance(data, dict) or isinstance(data, pd.Series):
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"]))
elif isinstance(data, pd.DataFrame):
m.fs.state_block[1].temperature.fix(float(data.iloc[0]["temperature"]))
m.fs.state_block[1].mole_frac_phase_comp["Liq", "bmimPF6"].fix(
float(data.iloc[0]["x_bmimPF6"])
)
m.fs.state_block[1].mole_frac_phase_comp["Liq", "carbon_dioxide"].fix(
float(data.iloc[0]["x_carbon_dioxide"])
)
m.fs.state_block[1].mole_frac_comp["bmimPF6"].fix(
float(data.iloc[0]["x_bmimPF6"])
)
else:
raise ValueError("Unrecognized data type.")
m.fs.state_block[1].pressure.unfix()
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
# Solve the model with the default solver and display results
solver = SolverFactory("ipopt")
results = solver.solve(m, tee=True)
2026-06-11 12:42:22 [INFO] idaes.init.fs.state_block: Starting initialization
2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.
2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: State variable initialization completed.
2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:23 [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...: 39
Number of nonzeros in inequality constraint Jacobian.: 0
Number of nonzeros in Lagrangian Hessian.............: 25
Total number of variables............................: 18
variables with only lower bounds: 4
variables with lower and upper bounds: 13
variables with only upper bounds: 1
Total number of equality constraints.................: 18
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 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0
1 0.0000000e+00 1.76e-01 6.65e+03 -1.0 7.51e+04 - 2.67e-01 9.90e-01H 1
2 0.0000000e+00 4.81e-02 1.40e+02 -1.0 6.76e+02 - 9.46e-01 9.90e-01h 1
3 0.0000000e+00 8.65e-03 1.76e+01 -1.0 9.79e+00 - 9.90e-01 9.90e-01h 1
4 0.0000000e+00 1.81e-03 4.99e+04 -1.0 1.20e+00 - 9.90e-01 1.00e+00h 1
5 0.0000000e+00 3.48e-03 9.81e+04 -1.0 5.29e+01 - 9.90e-01 1.00e+00h 1
6 0.0000000e+00 1.57e-03 8.00e+02 -1.0 1.54e+02 - 9.92e-01 1.00e+00h 1
7 0.0000000e+00 7.66e-04 2.93e-04 -2.5 2.52e+02 - 1.00e+00 1.00e+00h 1
8 0.0000000e+00 3.81e-04 1.61e-04 -5.7 4.82e+02 - 1.00e+00 1.00e+00h 1
9 0.0000000e+00 1.90e-04 6.49e-05 -5.7 9.53e+02 - 1.00e+00 1.00e+00h 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
10 0.0000000e+00 9.50e-05 8.68e-05 -5.7 1.90e+03 - 1.00e+00 1.00e+00h 1
11 0.0000000e+00 4.75e-05 3.47e-04 -5.7 3.81e+03 - 1.00e+00 1.00e+00h 1
12 0.0000000e+00 2.72e-05 1.39e-03 -5.7 7.64e+03 - 1.00e+00 1.00e+00h 1
13 0.0000000e+00 1.07e-04 5.57e-03 -5.7 1.54e+04 - 1.00e+00 1.00e+00h 1
14 0.0000000e+00 4.09e-04 2.23e-02 -5.7 3.11e+04 - 1.00e+00 1.00e+00h 1
15 0.0000000e+00 1.51e-03 8.91e-02 -5.7 6.38e+04 - 1.00e+00 1.00e+00h 1
16 0.0000000e+00 5.12e-03 3.53e-01 -5.7 1.33e+05 - 1.00e+00 1.00e+00h 1
17 0.0000000e+00 1.49e-02 1.34e+00 -5.7 2.89e+05 - 1.00e+00 1.00e+00h 1
18 0.0000000e+00 3.14e-02 4.58e+00 -5.7 6.55e+05 - 1.00e+00 1.00e+00h 1
19 0.0000000e+00 2.86e-02 4.32e+00 -5.7 1.51e+06 - 1.00e+00 1.25e-01h 4
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
20 0.0000000e+00 2.82e-02 4.26e+00 -5.7 1.73e+06 - 1.00e+00 1.56e-02h 7
21 0.0000000e+00 2.79e-02 4.23e+00 -5.7 1.76e+06 - 1.00e+00 7.81e-03h 8
22 0.0000000e+00 2.79e-02 4.22e+00 -5.7 1.77e+06 - 1.00e+00 4.88e-04h 12
23 0.0000000e+00 2.79e-02 4.22e+00 -5.7 1.77e+06 - 1.00e+00 1.22e-04h 14
24 0.0000000e+00 7.05e-03 1.51e+01 -5.7 1.77e+06 - 1.00e+00 1.00e+00h 1
25 0.0000000e+00 9.63e-04 4.01e+00 -5.7 3.18e+06 - 1.00e+00 1.50e-01h 2
26 0.0000000e+00 5.53e-04 8.54e+01 -5.7 3.24e+06 - 1.00e+00 6.53e-02h 2
27 0.0000000e+00 5.53e-04 8.57e+01 -5.7 3.20e+06 - 1.00e+00 9.58e-04h 7
28 0.0000000e+00 5.53e-04 9.27e+01 -5.7 3.19e+06 - 1.00e+00 9.42e-04h 7
29 0.0000000e+00 5.53e-04 2.08e+02 -5.7 3.19e+06 - 1.00e+00 9.27e-04h 7
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
30 0.0000000e+00 5.52e-04 7.91e+03 -5.7 1.83e+06 - 1.00e+00 3.17e-03h 6
31 0.0000000e+00 3.77e-05 2.11e+06 -5.7 2.63e+04 - 1.00e+00 1.00e+00h 1
32 0.0000000e+00 3.77e-05 2.10e+06 -5.7 1.03e+06 - 1.00e+00 5.67e-04h 9
33 0.0000000e+00 3.77e-05 2.10e+06 -5.7 1.03e+06 - 1.00e+00 5.65e-04h 9
34 0.0000000e+00 3.77e-05 2.10e+06 -5.7 1.02e+06 - 1.00e+00 5.63e-04h 9
35 0.0000000e+00 3.77e-05 2.12e+06 -5.7 9.14e+05 - 1.00e+00 6.29e-04h 9
36 0.0000000e+00 3.77e-05 2.23e+06 -5.7 9.36e+05 - 1.00e+00 6.11e-04h 9
37 0.0000000e+00 3.76e-05 4.98e+06 -5.7 4.23e+05 - 1.00e+00 2.69e-03h 8
38 0.0000000e+00 3.76e-05 6.97e+06 -5.7 8.98e+05 - 1.00e+00 6.29e-04h 9
39 0.0000000e+00 3.76e-05 5.17e+07 -5.7 6.09e+05 - 1.00e+00 1.85e-03h 8
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
40 0.0000000e+00 3.76e-05 6.29e+07 -5.7 1.03e+06 - 1.00e+00 5.42e-04h 9
41 0.0000000e+00 3.76e-05 7.41e+07 -5.7 1.02e+06 - 1.00e+00 5.43e-04h 9
42 0.0000000e+00 8.59e-04 7.30e+11 -5.7 1.02e+06 - 1.00e+00 1.39e-01w 1
43 0.0000000e+00 8.58e-04 7.30e+11 -5.7 7.14e+03 - 1.00e+00 2.07e-05w 1
In iteration 43, 2 Slacks too small, adjusting variable bounds
44 0.0000000e+00 7.90e-04 5.95e+14 -5.7 4.69e+03 - 1.00e+00 8.02e-02w 1
45 0.0000000e+00 3.76e-05 8.53e+07 -5.7 4.31e+03 - 1.00e+00 5.41e-04h 8
46 0.0000000e+00 3.75e-05 9.64e+07 -5.7 1.02e+06 - 1.00e+00 5.39e-04h 9
47 0.0000000e+00 3.75e-05 1.08e+08 -5.7 1.02e+06 - 1.00e+00 5.37e-04h 9
48 0.0000000e+00 3.75e-05 1.19e+08 -5.7 1.02e+06 - 1.00e+00 5.35e-04h 9
49 0.0000000e+00 3.75e-05 1.30e+08 -5.7 1.02e+06 - 1.00e+00 5.33e-04h 9
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
50 0.0000000e+00 3.75e-05 1.41e+08 -5.7 1.02e+06 - 1.00e+00 5.31e-04h 9
51 0.0000000e+00 3.75e-05 1.52e+08 -5.7 1.02e+06 - 1.00e+00 5.29e-04h 9
52 0.0000000e+00 3.75e-05 1.64e+08 -5.7 1.02e+06 - 1.00e+00 5.27e-04h 9
53 0.0000000e+00 3.75e-05 1.75e+08 -5.7 1.02e+06 - 1.00e+00 5.25e-04h 9
54 0.0000000e+00 3.75e-05 1.86e+08 -5.7 1.02e+06 - 1.00e+00 5.23e-04h 9
55 0.0000000e+00 7.97e-04 7.34e+11 -5.7 1.02e+06 - 1.00e+00 1.33e-01w 1
56 0.0000000e+00 7.97e-04 6.89e+11 -5.7 6.89e-05 16.0 2.81e-04 5.39e-01w 1
57 0.0000000e+00 4.04e-07 2.66e+15 -5.7 4.36e+03 - 2.29e-07 1.00e+00h 1
Cannot recompute multipliers for feasibility problem. Error in eq_mult_calculator
Number of Iterations....: 57
(scaled) (unscaled)
Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00
Dual infeasibility......: 2.6563801083485440e+15 2.6563801083485440e+15
Constraint violation....: 4.0441652946975677e-07 4.0441652946975677e-07
Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00
Overall NLP error.......: 4.0441652946975677e-07 2.6563801083485440e+15
Number of objective function evaluations = 337
Number of objective gradient evaluations = 59
Number of equality constraint evaluations = 337
Number of inequality constraint evaluations = 0
Number of equality constraint Jacobian evaluations = 59
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations = 58
Total CPU secs in IPOPT (w/o function evaluations) = 0.005
Total CPU secs in NLP function evaluations = 0.008
EXIT: Solved To Acceptable Level.
4.0 Parameter estimation using parmest#
4.1 Define the Experiment class#
Define the Experiment class to label model for parameter estimation.
from pyomo.contrib.parmest.experiment import Experiment
# Create experiment class for parameter estimation
class PRExperiment(Experiment):
def __init__(self, data, meas_error=None):
"""Initialize the PR Experiment class
Args:
data: DataFrame containing the experimental data
meas_error: Measurement error for the data (optional)
"""
self.model = None
self.data = data
self.meas_error = meas_error
def create_model(self):
"""Create the Pyomo model for the PR parameter estimation problem"""
self.model = PR_model(self.data)
def label_model(self):
m = self.model
# Add Suffixes to label the outputs, parameters, and measurement error in the model
m.experiment_outputs = Suffix(direction=Suffix.LOCAL)
m.experiment_outputs.update(
[(m.fs.state_block[1].pressure, self.data["pressure"])]
)
m.measurement_error = Suffix(direction=Suffix.LOCAL)
m.measurement_error.update([(m.fs.state_block[1].pressure, self.meas_error)])
# Add unknown parameters to the model for easier access
m.unknown_parameters = Suffix(direction=Suffix.LOCAL)
m.unknown_parameters.update(
(k, value(k))
for k in [
m.fs.properties.PR_kappa["bmimPF6", "carbon_dioxide"],
m.fs.properties.PR_kappa["carbon_dioxide", "bmimPF6"],
]
)
def get_labeled_model(self):
"""Return the labeled model"""
if self.model is None:
self.create_model()
self.label_model()
return self.model
4.2 Pre-process the data into individual experiments#
We now separate our data and assign a model for each individual experiments, creating an experiment list.
# Update to new interface
exp_list = []
for i in range(data.shape[0]):
exp_list.append(PRExperiment(data.iloc[i]))
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 experiment list, and an objective function to the Estimator method. tee=True will print the solver output after solving the parameter estimation problem.
pest = parmest.Estimator(exp_list, obj_function="SSE", tee=True)
obj_value, parameters = pest.theta_est()
2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Starting initialization
2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.
2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: State variable initialization completed.
2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Starting initialization
2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.
2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: State variable initialization completed.
2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Starting initialization
2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.
2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: State variable initialization completed.
2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Starting initialization
2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.
2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: State variable initialization completed.
2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Starting initialization
2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.
2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: State variable initialization completed.
2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Starting initialization
2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.
2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: State variable initialization completed.
2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Starting initialization
2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.
2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: State variable initialization completed.
2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Starting initialization
2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.
2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: State variable initialization completed.
2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Starting initialization
2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.
2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: State variable initialization completed.
2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Starting initialization
2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.
2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: State variable initialization completed.
2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Starting initialization
2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.
2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: State variable initialization completed.
2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Starting initialization
2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.
2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: State variable initialization completed.
2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Starting initialization
2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.
2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: State variable initialization completed.
2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Starting initialization
2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.
2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: State variable initialization completed.
2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Starting initialization
2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.
2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: State variable initialization completed.
2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Starting initialization
2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.
2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: State variable initialization completed.
2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Starting initialization
2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.
2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: State variable initialization completed.
2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Starting initialization
2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.
2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: State variable initialization completed.
2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.
2026-06-11 12:42:26 [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...: 846
Number of nonzeros in inequality constraint Jacobian.: 0
Number of nonzeros in Lagrangian Hessian.............: 720
Total number of variables............................: 362
variables with only lower bounds: 72
variables with lower and upper bounds: 270
variables with only upper bounds: 18
Total number of equality constraints.................: 360
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 2.44e-15 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0
1 6.9602464e+06 4.12e-01 1.82e+07 -1.0 2.99e+04 - 3.39e-01 1.72e-01h 3
2 1.6667677e+08 2.58e-01 2.70e+08 -1.0 2.58e+04 - 6.19e-01 7.79e-01h 1
3 2.8786912e+08 1.32e-01 4.98e+07 -1.0 8.26e+03 - 8.13e-01 9.90e-01h 1
4 2.9277551e+08 1.44e-01 5.76e+05 -1.0 3.05e+02 - 9.77e-01 9.90e-01h 1
5 2.9282842e+08 3.31e-02 5.28e+03 -1.0 3.24e+00 - 9.90e-01 9.91e-01h 1
6 2.9282891e+08 4.65e-03 8.12e+04 -1.0 1.08e+00 - 9.90e-01 1.00e+00h 1
7 2.9282891e+08 3.59e-05 2.33e+04 -2.5 9.23e-02 - 9.97e-01 1.00e+00h 1
8 2.9282891e+08 3.17e-09 2.26e-05 -3.8 8.65e-04 - 1.00e+00 1.00e+00h 1
9 2.9282891e+08 1.29e-12 2.38e-05 -8.6 6.67e-08 - 1.00e+00 1.00e+00f 1
Number of Iterations....: 9
(scaled) (unscaled)
Objective...............: 2.9282891309627521e+08 2.9282891309627521e+08
Dual infeasibility......: 2.3841853781623475e-05 2.3841853781623475e-05
Constraint violation....: 1.2910152591875072e-12 1.2910152591875072e-12
Complementarity.........: 2.5062901281861244e-09 2.5062901281861244e-09
Overall NLP error.......: 2.5062901281861244e-09 2.3841853781623475e-05
Number of objective function evaluations = 12
Number of objective gradient evaluations = 10
Number of equality constraint evaluations = 12
Number of inequality constraint evaluations = 0
Number of equality constraint Jacobian evaluations = 10
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations = 9
Total CPU secs in IPOPT (w/o function evaluations) = 0.006
Total CPU secs in NLP function evaluations = 0.020
EXIT: Optimal Solution Found.
5.0 Display results#
Let us display the results by running the next cell.
print(f"The SSE at the optimal solution is {obj_value*1e-7:0.6f}")
print()
print("The values for the parameters are as follows:")
for k, v in parameters.items():
print(f"{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.40714284008565715
fs.properties.PR_kappa[carbon_dioxide,bmimPF6] = 0.02059368400143062
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.