From 632ce2d7090dd6a3394ce1f6bb2070d8e1ba4883 Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Wed, 10 Jun 2026 13:44:56 -0400 Subject: [PATCH 01/23] First attempt to add experiment class and updated parmest --- ...ter_estimation_nrtl_using_unit_model.ipynb | 559 +++++++++++++++++- 1 file changed, 538 insertions(+), 21 deletions(-) diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb index 495b6540..889a249b 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "metadata": { "tags": [ "header", @@ -35,6 +35,9 @@ "Maintainer: Andrew Lee \n", "Updated: 2023-06-01 \n", "\n", + "Updated by Stephen Cini\n", + "Updated: 2026-06-10\n", + "\n", "In this module, we will be using Pyomo's `parmest` tool in conjunction with IDAES models for parameter estimation. We demonstrate these tools by estimating the parameters associated with the NRTL property model for a benzene-toluene mixture. The NRTL model has 2 sets of parameters: the non-randomness parameter (`alpha_ij`) and the binary interaction parameter (`tau_ij`), where `i` and `j` is the pure component species. In this example, we will be only estimate the binary interaction parameter (`tau_ij`) for a given dataset. 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 the NRTL property package. \n", "\n", "We will complete the following tasks:\n", @@ -60,7 +63,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "metadata": { "tags": [ "exercise" @@ -68,7 +71,7 @@ }, "outputs": [], "source": [ - "# Todo: import ConcreteModel from pyomo.environ\n", + "# Todo: import pyomo.environ as pyo\n", "\n", "# Todo: import FlowsheetBlock from idaes.core\n", "\n", @@ -77,7 +80,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "metadata": { "tags": [ "solution" @@ -86,7 +89,9 @@ "outputs": [], "source": [ "# Todo: import ConcreteModel from pyomo.environ\n", - "from pyomo.environ import ConcreteModel, value\n", + "# from pyomo.environ import ConcreteModel, value\n", + "\n", + "import pyomo.environ as pyo\n", "\n", "# Todo: import FlowsheetBlock from idaes.core\n", "from idaes.core import FlowsheetBlock\n", @@ -104,7 +109,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "metadata": {}, "outputs": [], "source": [ @@ -123,7 +128,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "metadata": {}, "outputs": [], "source": [ @@ -152,7 +157,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, "metadata": { "tags": [ "exercise" @@ -220,7 +225,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "metadata": { "tags": [ "solution" @@ -231,7 +236,7 @@ "def NRTL_model(data):\n", "\n", " # Todo: Create a ConcreteModel object\n", - " m = ConcreteModel()\n", + " m = pyo.ConcreteModel()\n", "\n", " # Todo: Create FlowsheetBlock object\n", " m.fs = FlowsheetBlock(dynamic=False)\n", @@ -292,7 +297,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 16, "metadata": { "tags": [ "testing" @@ -312,17 +317,17 @@ "assert degrees_of_freedom(m) == 0\n", "\n", "# Check for output values\n", - "assert value(m.fs.flash.liq_outlet.mole_frac_comp[0, \"benzene\"]) == pytest.approx(\n", + "assert pyo.value(m.fs.flash.liq_outlet.mole_frac_comp[0, \"benzene\"]) == pytest.approx(\n", " 0.389, abs=1e-2\n", ")\n", - "assert value(m.fs.flash.vap_outlet.mole_frac_comp[0, \"benzene\"]) == pytest.approx(\n", + "assert pyo.value(m.fs.flash.vap_outlet.mole_frac_comp[0, \"benzene\"]) == pytest.approx(\n", " 0.610, abs=1e-2\n", ")\n", "\n", - "assert value(m.fs.flash.liq_outlet.mole_frac_comp[0, \"toluene\"]) == pytest.approx(\n", + "assert pyo.value(m.fs.flash.liq_outlet.mole_frac_comp[0, \"toluene\"]) == pytest.approx(\n", " 0.610, abs=1e-2\n", ")\n", - "assert value(m.fs.flash.vap_outlet.mole_frac_comp[0, \"toluene\"]) == pytest.approx(\n", + "assert pyo.value(m.fs.flash.vap_outlet.mole_frac_comp[0, \"toluene\"]) == pytest.approx(\n", " 0.394, abs=1e-2\n", ")" ] @@ -361,6 +366,74 @@ "" ] }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [], + "source": [ + "# Build an experiment class to take advantage of new parmest interface\n", + "from pyomo.contrib.parmest.experiment import Experiment\n", + "\n", + "class NRTLExperiment(Experiment):\n", + " \"\"\" Experiment class for parameter estimation of NRTL model using parmest\"\"\"\n", + "\n", + " def __init__(self, \n", + " data,\n", + " meas_error = None,\n", + " ):\n", + " \n", + " \"\"\" Initialize the NRTLExperiment class\n", + " \n", + " Args:\n", + " data: DataFrame containing the experimental data\n", + " meas_error: Measurement error for the data (optional)\n", + " \"\"\"\n", + " self.model = None\n", + " self.data = data\n", + " self.meas_error = meas_error\n", + "\n", + " def create_model(self):\n", + " \"\"\" Create the Pyomo model for the NRTL parameter estimation problem \"\"\"\n", + " self.model = NRTL_model(self.data)\n", + " \n", + " def label_model(self):\n", + " m = self.model\n", + "\n", + " # Add experiment outputs to the model for easier access\n", + " m.experiment_outputs = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + " m.experiment_outputs.update(\n", + " (m.fs.flash.liq_outlet.mole_frac_comp[0, \"benzene\"], self.data.iloc[0][\"liq_benzene\"]),\n", + " (m.fs.flash.vap_outlet.mole_frac_comp[0, \"benzene\"], self.data.iloc[0][\"vap_benzene\"]),\n", + " )\n", + "\n", + " m.measurement_eror = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + " m.measurement_error.update(\n", + " (m.fs.flash.liq_outlet.mole_frac_comp[0, \"benzene\"], self.meas_error),\n", + " (m.fs.flash.vap_outlet.mole_frac_comp[0, \"benzene\"], self.meas_error),\n", + " )\n", + "\n", + " # Add unknown parameters to the model for easier access\n", + " m.unknown_parameters = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + " m.unknown_parameters.update(\n", + " (k, pyo.value(k)) for k in \n", + "\n", + " [m.fs.properties.tau[\"benzene\", \"toluene\"],\n", + " m.fs.properties.tau[\"toluene\", \"benzene\"],\n", + " ]\n", + " )\n", + " \n", + " def get_labeled_model(self):\n", + " \"\"\" Return the labeled model \"\"\"\n", + " if self.model is None:\n", + " self.create_model()\n", + " self.label_model()\n", + " return self.model\n", + "\n", + "\n", + " \n" + ] + }, { "cell_type": "code", "execution_count": null, @@ -407,9 +480,398 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 27, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
temperatureliq_benzenevap_benzene
0365.5000000.4809530.692110
1365.6176470.4624440.667699
2365.7352940.4779840.692441
3365.8529410.4405470.640336
4365.9705880.4274210.623328
5366.0882350.4427250.647796
6366.2058820.4343740.637691
7366.3235290.4446420.654933
8366.4411760.4271320.631229
9366.5588240.4463010.661743
10366.6764710.4380040.651591
11366.7941180.4253200.634814
12366.9117650.4394350.658047
13367.0294120.4356550.654539
14367.1470590.4013500.604987
15367.2647060.3978620.601703
16367.3823530.4158210.630930
17367.5000000.4206670.640380
18367.6176470.3916830.598214
19367.7352940.4049030.620432
20367.8529410.4095630.629626
21367.9705880.3894880.600722
22368.0000000.3967890.612483
23368.0882350.3981620.616106
24368.2058820.3623400.562505
25368.3235290.3869580.602680
26368.4411760.3636430.568210
27368.5588240.3681180.577072
28368.6764710.3840980.604078
29368.7941180.3536050.557925
30368.9117650.3464740.548445
31369.0294120.3507410.556996
32369.1470590.3623470.577286
33369.2647060.3625780.579519
34369.3823530.3407650.546411
35369.5000000.3374620.542857
36369.6176470.3557290.574083
37369.7352940.3486790.564513
38369.8529410.3381870.549284
39369.9705880.3243600.528514
40370.0882350.3107530.507964
41370.2058820.3110370.510055
42370.3235290.3112630.512055
43370.4411760.3080810.508437
44370.5588240.3082240.510293
45370.6764710.3181480.528399
46370.7941180.3083340.513728
47370.9117650.3179370.531410
48371.0294120.2891490.484824
49371.1470590.2986370.502318
\n", + "
" + ], + "text/plain": [ + " temperature liq_benzene vap_benzene\n", + "0 365.500000 0.480953 0.692110\n", + "1 365.617647 0.462444 0.667699\n", + "2 365.735294 0.477984 0.692441\n", + "3 365.852941 0.440547 0.640336\n", + "4 365.970588 0.427421 0.623328\n", + "5 366.088235 0.442725 0.647796\n", + "6 366.205882 0.434374 0.637691\n", + "7 366.323529 0.444642 0.654933\n", + "8 366.441176 0.427132 0.631229\n", + "9 366.558824 0.446301 0.661743\n", + "10 366.676471 0.438004 0.651591\n", + "11 366.794118 0.425320 0.634814\n", + "12 366.911765 0.439435 0.658047\n", + "13 367.029412 0.435655 0.654539\n", + "14 367.147059 0.401350 0.604987\n", + "15 367.264706 0.397862 0.601703\n", + "16 367.382353 0.415821 0.630930\n", + "17 367.500000 0.420667 0.640380\n", + "18 367.617647 0.391683 0.598214\n", + "19 367.735294 0.404903 0.620432\n", + "20 367.852941 0.409563 0.629626\n", + "21 367.970588 0.389488 0.600722\n", + "22 368.000000 0.396789 0.612483\n", + "23 368.088235 0.398162 0.616106\n", + "24 368.205882 0.362340 0.562505\n", + "25 368.323529 0.386958 0.602680\n", + "26 368.441176 0.363643 0.568210\n", + "27 368.558824 0.368118 0.577072\n", + "28 368.676471 0.384098 0.604078\n", + "29 368.794118 0.353605 0.557925\n", + "30 368.911765 0.346474 0.548445\n", + "31 369.029412 0.350741 0.556996\n", + "32 369.147059 0.362347 0.577286\n", + "33 369.264706 0.362578 0.579519\n", + "34 369.382353 0.340765 0.546411\n", + "35 369.500000 0.337462 0.542857\n", + "36 369.617647 0.355729 0.574083\n", + "37 369.735294 0.348679 0.564513\n", + "38 369.852941 0.338187 0.549284\n", + "39 369.970588 0.324360 0.528514\n", + "40 370.088235 0.310753 0.507964\n", + "41 370.205882 0.311037 0.510055\n", + "42 370.323529 0.311263 0.512055\n", + "43 370.441176 0.308081 0.508437\n", + "44 370.558824 0.308224 0.510293\n", + "45 370.676471 0.318148 0.528399\n", + "46 370.794118 0.308334 0.513728\n", + "47 370.911765 0.317937 0.531410\n", + "48 371.029412 0.289149 0.484824\n", + "49 371.147059 0.298637 0.502318" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "# Load data from csv\n", "data = pd.read_csv(\"BT_NRTL_dataset.csv\")\n", @@ -493,9 +955,21 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 33, "metadata": {}, - "outputs": [], + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'variable_name' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mNameError\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[33]\u001b[39m\u001b[32m, line 2\u001b[39m\n\u001b[32m 1\u001b[39m \u001b[38;5;66;03m# Initialize a parameter estimation object\u001b[39;00m\n\u001b[32m----> \u001b[39m\u001b[32m2\u001b[39m pest = parmest.Estimator(NRTL_model, data, variable_name, SSE, tee=\u001b[38;5;28;01mTrue\u001b[39;00m)\n\u001b[32m 3\u001b[39m \n\u001b[32m 4\u001b[39m \u001b[38;5;66;03m# Run parameter estimation using all data\u001b[39;00m\n\u001b[32m 5\u001b[39m obj_value, parameters = pest.theta_est()\n", + "\u001b[31mNameError\u001b[39m: name 'variable_name' is not defined" + ] + } + ], "source": [ "# Initialize a parameter estimation object\n", "pest = parmest.Estimator(NRTL_model, data, variable_name, SSE, tee=True)\n", @@ -504,6 +978,49 @@ "obj_value, parameters = pest.theta_est()" ] }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [ + { + "ename": "RuntimeError", + "evalue": "Failed to clone labeled model: invalid index to scalar variable.", + "output_type": "error", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mIndexError\u001b[39m Traceback (most recent call last)", + "\u001b[36mFile \u001b[39m\u001b[32m/Applications/anaconda3/envs/idaes-examples-dev-py313-macmini/lib/python3.13/site-packages/pyomo/contrib/parmest/parmest.py:374\u001b[39m, in \u001b[36m_get_labeled_model\u001b[39m\u001b[34m(experiment)\u001b[39m\n\u001b[32m 373\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m374\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[30;43mget_model\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43m)\u001b[39;49m.clone()\n\u001b[32m 375\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m exc:\n", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[32]\u001b[39m\u001b[32m, line 56\u001b[39m, in \u001b[36mNRTLExperiment.get_labeled_model\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 54\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m self.model \u001b[38;5;28;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m 55\u001b[39m self.create_model()\n\u001b[32m---> \u001b[39m\u001b[32m56\u001b[39m self.label_model()\n\u001b[32m 57\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m self.model\n", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[32]\u001b[39m\u001b[32m, line 32\u001b[39m, in \u001b[36mNRTLExperiment.label_model\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 30\u001b[39m m.experiment_outputs = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n\u001b[32m 31\u001b[39m m.experiment_outputs.update(\n\u001b[32m---> \u001b[39m\u001b[32m32\u001b[39m (m.fs.flash.liq_outlet.mole_frac_comp[\u001b[32m0\u001b[39m, \u001b[33m\"benzene\"\u001b[39m], self.data.iloc[\u001b[32m0\u001b[39m][\u001b[33m\"liq_benzene\"\u001b[39m]),\n\u001b[32m 33\u001b[39m (m.fs.flash.vap_outlet.mole_frac_comp[\u001b[32m0\u001b[39m, \u001b[33m\"benzene\"\u001b[39m], self.data.iloc[\u001b[32m0\u001b[39m][\u001b[33m\"vap_benzene\"\u001b[39m]),\n", + "\u001b[31mIndexError\u001b[39m: invalid index to scalar variable.", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[31mRuntimeError\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[34]\u001b[39m\u001b[32m, line 6\u001b[39m\n\u001b[32m 2\u001b[39m exp_list = []\n\u001b[32m 3\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m i \u001b[38;5;28;01min\u001b[39;00m range(data.shape[\u001b[32m0\u001b[39m]):\n\u001b[32m 4\u001b[39m exp_list.append(NRTLExperiment(data.iloc[i]))\n\u001b[32m 5\u001b[39m \n\u001b[32m----> \u001b[39m\u001b[32m6\u001b[39m pest_new = parmest.Estimator(exp_list, obj_function=\u001b[33m\"SSE\"\u001b[39m, tee=\u001b[38;5;28;01mTrue\u001b[39;00m)\n", + "\u001b[36mFile \u001b[39m\u001b[32m/Applications/anaconda3/envs/idaes-examples-dev-py313-macmini/lib/python3.13/functools.py:974\u001b[39m, in \u001b[36msingledispatchmethod.__get__.._method\u001b[39m\u001b[34m(*args, **kwargs)\u001b[39m\n\u001b[32m 971\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m args:\n\u001b[32m 972\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m(\u001b[33mf\u001b[39m\u001b[33m'\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mfuncname\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m requires at least \u001b[39m\u001b[33m'\u001b[39m\n\u001b[32m 973\u001b[39m \u001b[33m'\u001b[39m\u001b[33m1 positional argument\u001b[39m\u001b[33m'\u001b[39m)\n\u001b[32m--> \u001b[39m\u001b[32m974\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[30;43mdispatch\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43margs\u001b[39;49m\u001b[30;43m[\u001b[39;49m\u001b[30;43m0\u001b[39;49m\u001b[30;43m]\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43m__class__\u001b[39;49m\u001b[30;43m)\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43m__get__\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mobj\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mcls\u001b[39;49m\u001b[30;43m)\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43margs\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43mkwargs\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m/Applications/anaconda3/envs/idaes-examples-dev-py313-macmini/lib/python3.13/site-packages/pyomo/contrib/parmest/parmest.py:1078\u001b[39m, in \u001b[36mEstimator.__init__\u001b[39m\u001b[34m(self, experiment_list, obj_function, tee, diagnostic_mode, solver_options, regularization, prior_FIM, theta_ref, regularization_weight)\u001b[39m\n\u001b[32m 1075\u001b[39m \u001b[38;5;28mself\u001b[39m.exp_list = experiment_list\n\u001b[32m 1077\u001b[39m \u001b[38;5;66;03m# get the number of experiments\u001b[39;00m\n\u001b[32m-> \u001b[39m\u001b[32m1078\u001b[39m \u001b[38;5;28mself\u001b[39m.number_exp = \u001b[30;43m_count_total_experiments\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mexp_list\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 1080\u001b[39m \u001b[38;5;66;03m# check if the experiment has a ``get_labeled_model`` function\u001b[39;00m\n\u001b[32m 1081\u001b[39m model = _get_labeled_model(\u001b[38;5;28mself\u001b[39m.exp_list[\u001b[32m0\u001b[39m])\n", + "\u001b[36mFile \u001b[39m\u001b[32m/Applications/anaconda3/envs/idaes-examples-dev-py313-macmini/lib/python3.13/site-packages/pyomo/contrib/parmest/parmest.py:487\u001b[39m, in \u001b[36m_count_total_experiments\u001b[39m\u001b[34m(experiment_list)\u001b[39m\n\u001b[32m 484\u001b[39m total_data_points = \u001b[32m0\u001b[39m\n\u001b[32m 486\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m experiment \u001b[38;5;129;01min\u001b[39;00m experiment_list:\n\u001b[32m--> \u001b[39m\u001b[32m487\u001b[39m model = \u001b[30;43m_get_labeled_model\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mexperiment\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 488\u001b[39m output_vars = model.experiment_outputs\n\u001b[32m 490\u001b[39m \u001b[38;5;66;03m# check if the experiment outputs are defined correctly\u001b[39;00m\n", + "\u001b[36mFile \u001b[39m\u001b[32m/Applications/anaconda3/envs/idaes-examples-dev-py313-macmini/lib/python3.13/site-packages/pyomo/contrib/parmest/parmest.py:376\u001b[39m, in \u001b[36m_get_labeled_model\u001b[39m\u001b[34m(experiment)\u001b[39m\n\u001b[32m 374\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m get_model().clone()\n\u001b[32m 375\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m exc:\n\u001b[32m--> \u001b[39m\u001b[32m376\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mRuntimeError\u001b[39;00m(\u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mFailed to clone labeled model: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mexc\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m\"\u001b[39m)\n", + "\u001b[31mRuntimeError\u001b[39m: Failed to clone labeled model: invalid index to scalar variable." + ] + } + ], + "source": [ + "# Update to new interface\n", + "exp_list = []\n", + "for i in range(data.shape[0]):\n", + " exp_list.append(NRTLExperiment(data.iloc[i]))\n", + "\n", + "pest_new = parmest.Estimator(exp_list, obj_function=\"SSE\", tee=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, { "cell_type": "code", "execution_count": null, @@ -585,7 +1102,7 @@ "metadata": { "celltoolbar": "Tags", "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "idaes-examples-dev-py313-macmini", "language": "python", "name": "python3" }, @@ -599,7 +1116,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.19" + "version": "3.13.13" } }, "nbformat": 4, From 5840f32dca57eb2de81633953f3c38e889772fe7 Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Wed, 10 Jun 2026 17:08:10 -0400 Subject: [PATCH 02/23] New interface working and matching old --- ...ter_estimation_nrtl_using_unit_model.ipynb | 372 +++++++++++++++--- 1 file changed, 312 insertions(+), 60 deletions(-) diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb index 889a249b..79dec127 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 9, + "execution_count": 1, "metadata": { "tags": [ "header", @@ -63,7 +63,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 2, "metadata": { "tags": [ "exercise" @@ -80,7 +80,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 3, "metadata": { "tags": [ "solution" @@ -109,7 +109,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -128,7 +128,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -157,7 +157,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 6, "metadata": { "tags": [ "exercise" @@ -225,7 +225,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 7, "metadata": { "tags": [ "solution" @@ -297,7 +297,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 8, "metadata": { "tags": [ "testing" @@ -368,7 +368,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 23, "metadata": {}, "outputs": [], "source": [ @@ -403,14 +403,15 @@ " # Add experiment outputs to the model for easier access\n", " m.experiment_outputs = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", " m.experiment_outputs.update(\n", - " (m.fs.flash.liq_outlet.mole_frac_comp[0, \"benzene\"], self.data.iloc[0][\"liq_benzene\"]),\n", - " (m.fs.flash.vap_outlet.mole_frac_comp[0, \"benzene\"], self.data.iloc[0][\"vap_benzene\"]),\n", - " )\n", + " [(m.fs.flash.liq_outlet.mole_frac_comp[0, \"benzene\"], self.data[\"liq_benzene\"]),\n", + " (m.fs.flash.vap_outlet.mole_frac_comp[0, \"benzene\"], self.data[\"vap_benzene\"])\n", + " ])\n", "\n", - " m.measurement_eror = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + " m.measurement_error = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", " m.measurement_error.update(\n", - " (m.fs.flash.liq_outlet.mole_frac_comp[0, \"benzene\"], self.meas_error),\n", - " (m.fs.flash.vap_outlet.mole_frac_comp[0, \"benzene\"], self.meas_error),\n", + " [(m.fs.flash.liq_outlet.mole_frac_comp[0, \"benzene\"], self.meas_error),\n", + " (m.fs.flash.vap_outlet.mole_frac_comp[0, \"benzene\"], self.meas_error)\n", + " ]\n", " )\n", "\n", " # Add unknown parameters to the model for easier access\n", @@ -436,7 +437,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "metadata": { "tags": [ "exercise" @@ -449,7 +450,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "metadata": { "tags": [ "solution" @@ -480,7 +481,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 18, "metadata": {}, "outputs": [ { @@ -894,7 +895,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "metadata": { "tags": [ "exercise" @@ -913,7 +914,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, "metadata": { "tags": [ "solution" @@ -955,18 +956,85 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 19, "metadata": {}, "outputs": [ { - "ename": "NameError", - "evalue": "name 'variable_name' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[31m---------------------------------------------------------------------------\u001b[39m", - "\u001b[31mNameError\u001b[39m Traceback (most recent call last)", - "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[33]\u001b[39m\u001b[32m, line 2\u001b[39m\n\u001b[32m 1\u001b[39m \u001b[38;5;66;03m# Initialize a parameter estimation object\u001b[39;00m\n\u001b[32m----> \u001b[39m\u001b[32m2\u001b[39m pest = parmest.Estimator(NRTL_model, data, variable_name, SSE, tee=\u001b[38;5;28;01mTrue\u001b[39;00m)\n\u001b[32m 3\u001b[39m \n\u001b[32m 4\u001b[39m \u001b[38;5;66;03m# Run parameter estimation using all data\u001b[39;00m\n\u001b[32m 5\u001b[39m obj_value, parameters = pest.theta_est()\n", - "\u001b[31mNameError\u001b[39m: name 'variable_name' is not defined" + "name": "stdout", + "output_type": "stream", + "text": [ + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 10946\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 6600\n", + "\n", + "Total number of variables............................: 2950\n", + " variables with only lower bounds: 150\n", + " variables with lower and upper bounds: 600\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 2948\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 6.0671019e+01 5.63e+02 1.08e-04 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 5.0339335e+00 1.57e+03 7.47e+01 -1.0 1.37e+04 - 9.45e-01 1.00e+00h 1\n", + " 2 5.1535704e+00 1.93e+02 4.59e+02 -1.0 5.54e+02 -4.0 9.90e-01 1.00e+00h 1\n", + " 3 5.1392848e+00 1.07e+00 3.40e+01 -1.0 6.17e+01 -4.5 9.92e-01 1.00e+00h 1\n", + " 4 5.1359488e+00 3.65e+02 2.24e+01 -1.0 8.41e+02 - 1.00e+00 1.00e+00h 1\n", + " 5 5.1198699e+00 1.64e+00 1.32e-01 -1.0 3.65e+02 - 1.00e+00 1.00e+00h 1\n", + " 6 5.0735545e+00 1.54e+02 1.83e-01 -2.5 3.80e+02 - 9.96e-01 1.00e+00h 1\n", + " 7 5.0752210e+00 1.03e+01 5.00e-02 -2.5 9.51e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 5.0750012e+00 5.57e-03 2.07e-05 -2.5 2.09e-01 - 1.00e+00 1.00e+00h 1\n", + " 9 5.0749679e+00 5.85e-02 7.21e-04 -3.8 8.43e+00 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 5.0749686e+00 5.59e-04 1.05e-05 -5.7 9.63e-01 - 1.00e+00 1.00e+00h 1\n", + " 11 5.0749686e+00 3.98e-08 1.56e-09 -8.6 7.56e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 11\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 5.0749685783044818e+00 5.0749685783044818e+00\n", + "Dual infeasibility......: 1.5648777723425133e-09 1.5648777723425133e-09\n", + "Constraint violation....: 1.3843631310512158e-10 3.9843143895268440e-08\n", + "Complementarity.........: 2.5074825420344762e-09 2.5074825420344762e-09\n", + "Overall NLP error.......: 2.5074825420344762e-09 3.9843143895268440e-08\n", + "\n", + "\n", + "Number of objective function evaluations = 12\n", + "Number of objective gradient evaluations = 12\n", + "Number of equality constraint evaluations = 12\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 12\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 11\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.043\n", + "Total CPU secs in NLP function evaluations = 0.009\n", + "\n", + "EXIT: Optimal Solution Found.\n" ] } ], @@ -980,46 +1048,192 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 24, "metadata": {}, - "outputs": [ - { - "ename": "RuntimeError", - "evalue": "Failed to clone labeled model: invalid index to scalar variable.", - "output_type": "error", - "traceback": [ - "\u001b[31m---------------------------------------------------------------------------\u001b[39m", - "\u001b[31mIndexError\u001b[39m Traceback (most recent call last)", - "\u001b[36mFile \u001b[39m\u001b[32m/Applications/anaconda3/envs/idaes-examples-dev-py313-macmini/lib/python3.13/site-packages/pyomo/contrib/parmest/parmest.py:374\u001b[39m, in \u001b[36m_get_labeled_model\u001b[39m\u001b[34m(experiment)\u001b[39m\n\u001b[32m 373\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m374\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[30;43mget_model\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43m)\u001b[39;49m.clone()\n\u001b[32m 375\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m exc:\n", - "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[32]\u001b[39m\u001b[32m, line 56\u001b[39m, in \u001b[36mNRTLExperiment.get_labeled_model\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 54\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m self.model \u001b[38;5;28;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m 55\u001b[39m self.create_model()\n\u001b[32m---> \u001b[39m\u001b[32m56\u001b[39m self.label_model()\n\u001b[32m 57\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m self.model\n", - "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[32]\u001b[39m\u001b[32m, line 32\u001b[39m, in \u001b[36mNRTLExperiment.label_model\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 30\u001b[39m m.experiment_outputs = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n\u001b[32m 31\u001b[39m m.experiment_outputs.update(\n\u001b[32m---> \u001b[39m\u001b[32m32\u001b[39m (m.fs.flash.liq_outlet.mole_frac_comp[\u001b[32m0\u001b[39m, \u001b[33m\"benzene\"\u001b[39m], self.data.iloc[\u001b[32m0\u001b[39m][\u001b[33m\"liq_benzene\"\u001b[39m]),\n\u001b[32m 33\u001b[39m (m.fs.flash.vap_outlet.mole_frac_comp[\u001b[32m0\u001b[39m, \u001b[33m\"benzene\"\u001b[39m], self.data.iloc[\u001b[32m0\u001b[39m][\u001b[33m\"vap_benzene\"\u001b[39m]),\n", - "\u001b[31mIndexError\u001b[39m: invalid index to scalar variable.", - "\nDuring handling of the above exception, another exception occurred:\n", - "\u001b[31mRuntimeError\u001b[39m Traceback (most recent call last)", - "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[34]\u001b[39m\u001b[32m, line 6\u001b[39m\n\u001b[32m 2\u001b[39m exp_list = []\n\u001b[32m 3\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m i \u001b[38;5;28;01min\u001b[39;00m range(data.shape[\u001b[32m0\u001b[39m]):\n\u001b[32m 4\u001b[39m exp_list.append(NRTLExperiment(data.iloc[i]))\n\u001b[32m 5\u001b[39m \n\u001b[32m----> \u001b[39m\u001b[32m6\u001b[39m pest_new = parmest.Estimator(exp_list, obj_function=\u001b[33m\"SSE\"\u001b[39m, tee=\u001b[38;5;28;01mTrue\u001b[39;00m)\n", - "\u001b[36mFile \u001b[39m\u001b[32m/Applications/anaconda3/envs/idaes-examples-dev-py313-macmini/lib/python3.13/functools.py:974\u001b[39m, in \u001b[36msingledispatchmethod.__get__.._method\u001b[39m\u001b[34m(*args, **kwargs)\u001b[39m\n\u001b[32m 971\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m args:\n\u001b[32m 972\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m(\u001b[33mf\u001b[39m\u001b[33m'\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mfuncname\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m requires at least \u001b[39m\u001b[33m'\u001b[39m\n\u001b[32m 973\u001b[39m \u001b[33m'\u001b[39m\u001b[33m1 positional argument\u001b[39m\u001b[33m'\u001b[39m)\n\u001b[32m--> \u001b[39m\u001b[32m974\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[30;43mdispatch\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43margs\u001b[39;49m\u001b[30;43m[\u001b[39;49m\u001b[30;43m0\u001b[39;49m\u001b[30;43m]\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43m__class__\u001b[39;49m\u001b[30;43m)\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43m__get__\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mobj\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mcls\u001b[39;49m\u001b[30;43m)\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43margs\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43mkwargs\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n", - "\u001b[36mFile \u001b[39m\u001b[32m/Applications/anaconda3/envs/idaes-examples-dev-py313-macmini/lib/python3.13/site-packages/pyomo/contrib/parmest/parmest.py:1078\u001b[39m, in \u001b[36mEstimator.__init__\u001b[39m\u001b[34m(self, experiment_list, obj_function, tee, diagnostic_mode, solver_options, regularization, prior_FIM, theta_ref, regularization_weight)\u001b[39m\n\u001b[32m 1075\u001b[39m \u001b[38;5;28mself\u001b[39m.exp_list = experiment_list\n\u001b[32m 1077\u001b[39m \u001b[38;5;66;03m# get the number of experiments\u001b[39;00m\n\u001b[32m-> \u001b[39m\u001b[32m1078\u001b[39m \u001b[38;5;28mself\u001b[39m.number_exp = \u001b[30;43m_count_total_experiments\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mexp_list\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 1080\u001b[39m \u001b[38;5;66;03m# check if the experiment has a ``get_labeled_model`` function\u001b[39;00m\n\u001b[32m 1081\u001b[39m model = _get_labeled_model(\u001b[38;5;28mself\u001b[39m.exp_list[\u001b[32m0\u001b[39m])\n", - "\u001b[36mFile \u001b[39m\u001b[32m/Applications/anaconda3/envs/idaes-examples-dev-py313-macmini/lib/python3.13/site-packages/pyomo/contrib/parmest/parmest.py:487\u001b[39m, in \u001b[36m_count_total_experiments\u001b[39m\u001b[34m(experiment_list)\u001b[39m\n\u001b[32m 484\u001b[39m total_data_points = \u001b[32m0\u001b[39m\n\u001b[32m 486\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m experiment \u001b[38;5;129;01min\u001b[39;00m experiment_list:\n\u001b[32m--> \u001b[39m\u001b[32m487\u001b[39m model = \u001b[30;43m_get_labeled_model\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mexperiment\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 488\u001b[39m output_vars = model.experiment_outputs\n\u001b[32m 490\u001b[39m \u001b[38;5;66;03m# check if the experiment outputs are defined correctly\u001b[39;00m\n", - "\u001b[36mFile \u001b[39m\u001b[32m/Applications/anaconda3/envs/idaes-examples-dev-py313-macmini/lib/python3.13/site-packages/pyomo/contrib/parmest/parmest.py:376\u001b[39m, in \u001b[36m_get_labeled_model\u001b[39m\u001b[34m(experiment)\u001b[39m\n\u001b[32m 374\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m get_model().clone()\n\u001b[32m 375\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m exc:\n\u001b[32m--> \u001b[39m\u001b[32m376\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mRuntimeError\u001b[39;00m(\u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mFailed to clone labeled model: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mexc\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m\"\u001b[39m)\n", - "\u001b[31mRuntimeError\u001b[39m: Failed to clone labeled model: invalid index to scalar variable." - ] - } - ], + "outputs": [], "source": [ "# Update to new interface\n", "exp_list = []\n", "for i in range(data.shape[0]):\n", - " exp_list.append(NRTLExperiment(data.iloc[i]))\n", - "\n", - "pest_new = parmest.Estimator(exp_list, obj_function=\"SSE\", tee=True)" + " exp_list.append(NRTLExperiment(data.iloc[i]))" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 25, "metadata": {}, "outputs": [], - "source": [] + "source": [ + "pest_new = parmest.Estimator(exp_list, obj_function=\"SSE\", tee=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 10950\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 6600\n", + "\n", + "Total number of variables............................: 2952\n", + " variables with only lower bounds: 150\n", + " variables with lower and upper bounds: 600\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 2950\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 6.0671019e-03 5.63e+02 1.20e-08 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 9.0714942e-04 1.37e+03 1.61e+01 -1.0 1.37e+04 - 9.82e-01 1.00e+00h 1\n", + " 2 1.3219937e-03 1.17e+04 1.62e+01 -1.0 5.23e+03 - 3.41e-01 1.65e-01h 3\n", + " 3 1.3161671e-03 1.11e+04 4.02e+01 -1.0 3.96e+02 -4.0 8.19e-01 1.25e-01h 4\n", + " 4 1.3154170e-03 1.11e+04 4.32e+01 -1.0 3.47e+02 -4.5 9.90e-01 4.43e-02h 5\n", + " 5 9.4424343e-04 1.04e+04 4.05e+01 -1.0 1.16e+04 - 9.33e-01 5.61e-02h 5\n", + " 6 9.4571258e-04 1.11e+04 4.85e+01 -1.0 3.13e+02 -5.0 8.74e-01 1.25e-01h 4\n", + " 7 9.4862862e-04 1.11e+04 4.84e+01 -1.0 2.41e+03 -5.4 1.72e-01 1.50e-03h 8\n", + " 8 9.5448936e-04 1.10e+04 4.81e+01 -1.0 4.11e+02 -5.0 1.00e+00 1.97e-02h 6\n", + " 9 9.5650047e-04 1.10e+04 4.81e+01 -1.0 5.14e+02 -4.6 3.46e-01 5.24e-03h 7\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 9.5730419e-04 1.10e+04 4.81e+01 -1.0 9.78e+02 -4.2 4.40e-01 1.08e-03h 8\n", + " 11 9.5774182e-04 1.10e+04 4.84e+01 -1.0 2.76e+02 -3.7 2.91e-01 2.99e-03h 7\n", + " 12 9.4292855e-04 7.77e+04 4.09e+04 -1.0 5.38e+02 -2.4 5.48e-02 6.44e-02w 1\n", + " 13 2.4318219e-01 2.38e+07 4.22e+14 -1.0 1.28e+06 - 2.55e-02 3.49e-02w 1\n", + " 14 2.8902019e-01 1.64e+07 2.92e+14 -1.0 1.11e+05 -2.9 9.54e-01 3.01e-01w 1\n", + " 15 9.5768293e-04 1.10e+04 4.85e+01 -1.0 2.80e+05 -3.4 5.48e-02 2.52e-04h 8\n", + " 16 9.5769345e-04 1.10e+04 4.85e+01 -1.0 4.33e+02 -2.9 7.95e-02 1.91e-04h 9\n", + " 17 9.5763809e-04 1.10e+04 4.85e+01 -1.0 6.35e+02 -2.5 4.94e-02 2.08e-04h 9\n", + " 18 9.5734836e-04 1.10e+04 4.87e+01 -1.0 3.22e+02 -3.0 1.00e+00 1.22e-03h 8\n", + " 19 9.3628114e-04 1.09e+04 4.62e+01 -1.0 4.22e+02 -3.5 5.16e-01 5.87e-02h 5\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 7.1894543e-04 4.02e+03 4.95e+02 -1.0 3.49e+02 -3.9 1.00e+00 1.00e+00h 1\n", + " 21 6.7062834e-04 1.58e+02 2.21e+02 -1.0 1.78e+02 -4.4 1.00e+00 1.00e+00h 1\n", + " 22 6.6635123e-04 4.17e+01 1.12e+01 -1.0 2.44e+02 -4.9 1.00e+00 1.00e+00h 1\n", + " 23 6.6729070e-04 1.43e+00 9.69e-01 -1.0 1.08e+01 -5.4 1.00e+00 1.00e+00h 1\n", + " 24 6.6785681e-04 3.58e-01 5.25e-03 -1.7 6.65e+00 -5.8 1.00e+00 1.00e+00h 1\n", + " 25 6.2552355e-04 9.80e+02 6.48e-02 -3.8 7.92e+02 - 9.22e-01 1.00e+00h 1\n", + " 26 5.9105707e-04 8.13e+00 6.13e-04 -3.8 5.66e+02 - 1.00e+00 1.00e+00h 1\n", + " 27 6.1313801e-04 6.24e+01 8.08e-06 -3.8 1.70e+02 - 1.00e+00 1.00e+00h 1\n", + " 28 6.1208051e-04 3.58e-01 1.18e-08 -3.8 1.88e+00 - 1.00e+00 1.00e+00h 1\n", + " 29 5.9010560e-04 1.58e+01 1.00e-05 -5.7 1.08e+02 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30 5.9008319e-04 2.74e-02 7.90e-07 -5.7 7.54e-02 -6.3 1.00e+00 1.00e+00h 1\n", + " 31 5.3570104e-04 1.48e+04 8.70e-04 -5.7 1.81e+02 - 1.00e+00 1.00e+00h 1\n", + " 32 5.1618763e-04 6.29e+02 8.06e-05 -5.7 2.55e+02 - 1.00e+00 1.00e+00h 1\n", + " 33 5.5250565e-04 2.88e+01 2.58e-04 -5.7 1.81e+04 - 6.26e-01 6.25e-02h 5\n", + " 34 5.2209909e-04 2.88e+02 2.02e-04 -5.7 1.89e+03 - 1.00e+00 1.00e+00h 1\n", + " 35 5.0707798e-04 5.60e+01 2.02e-04 -5.7 2.93e+03 - 1.00e+00 1.00e+00h 1\n", + " 36 5.0765648e-04 7.87e+00 1.91e-05 -5.7 1.02e+02 - 1.00e+00 1.00e+00h 1\n", + " 37 5.0740606e-04 2.57e+00 1.88e-05 -5.7 6.96e+01 - 1.00e+00 1.00e+00h 1\n", + " 38 5.0764164e-04 2.55e+00 1.76e-05 -5.7 6.81e+01 - 1.00e+00 1.00e+00h 1\n", + " 39 5.0740672e-04 2.55e+00 1.88e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 40 5.0764162e-04 2.54e+00 1.76e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", + " 41 5.0740672e-04 2.55e+00 1.88e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", + " 42 5.0782847e-04 1.43e-01 1.83e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00H 1\n", + " 43 5.0751252e-04 1.58e-02 1.93e-05 -5.7 6.88e+01 - 1.00e+00 1.00e+00H 1\n", + " 44 5.0783218e-04 4.79e-03 1.85e-05 -5.7 6.92e+01 - 1.00e+00 1.00e+00H 1\n", + " 45 5.0751252e-04 1.60e-02 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", + " 46 5.0783222e-04 1.23e-04 1.85e-05 -5.7 6.92e+01 - 1.00e+00 1.00e+00H 1\n", + " 47 5.0751252e-04 1.60e-02 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", + " 48 5.0783216e-04 1.24e-04 1.85e-05 -5.7 6.92e+01 - 1.00e+00 1.00e+00H 1\n", + " 49 5.0751765e-04 3.20e-03 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 50 5.0764151e-04 2.56e+00 1.77e-05 -5.7 6.93e+01 - 1.00e+00 1.00e+00h 1\n", + " 51 5.0740671e-04 2.55e+00 1.88e-05 -5.7 6.81e+01 - 1.00e+00 1.00e+00h 1\n", + " 52 5.0764162e-04 2.54e+00 1.76e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", + " 53 5.0740672e-04 2.55e+00 1.88e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", + " 54 5.0764162e-04 2.54e+00 1.76e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", + " 55 5.0748886e-04 1.91e+00 8.64e-06 -5.7 6.80e+01 - 1.00e+00 5.00e-01h 2\n", + " 56 5.0744550e-04 3.37e-01 1.64e-05 -5.7 2.54e+01 - 1.00e+00 1.00e+00h 1\n", + " 57 5.0763613e-04 1.82e+00 1.43e-05 -5.7 5.79e+01 - 1.00e+00 1.00e+00h 1\n", + " 58 5.0751252e-04 2.25e-02 1.93e-05 -5.7 6.65e+01 - 1.00e+00 1.00e+00H 1\n", + " 59 5.0783220e-04 1.23e-04 1.85e-05 -5.7 6.92e+01 - 1.00e+00 1.00e+00H 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 60 5.0751252e-04 1.60e-02 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", + " 61 5.0783207e-04 3.26e-04 1.85e-05 -5.7 6.92e+01 - 1.00e+00 1.00e+00H 1\n", + " 62 5.0751786e-04 7.95e-05 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", + " 63 5.0754291e-04 6.40e-01 8.69e-06 -5.7 6.93e+01 - 1.00e+00 5.00e-01h 2\n", + " 64 5.0745167e-04 3.00e-01 1.61e-05 -5.7 2.35e+01 - 1.00e+00 1.00e+00h 1\n", + " 65 5.0763437e-04 1.71e+00 1.33e-05 -5.7 5.61e+01 - 1.00e+00 1.00e+00h 1\n", + " 66 5.0751762e-04 2.91e-03 1.93e-05 -5.7 6.60e+01 - 1.00e+00 1.00e+00H 1\n", + " 67 5.0752104e-04 1.62e-01 1.43e-05 -5.7 6.92e+01 - 1.00e+00 2.50e-01h 3\n", + " 68 5.0761295e-04 1.03e+00 2.18e-05 -5.7 4.35e+01 - 1.00e+00 1.00e+00h 1\n", + " 69 5.0751251e-04 2.38e-02 1.92e-05 -5.7 5.95e+01 - 1.00e+00 1.00e+00H 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 70 5.0783210e-04 3.29e-06 1.85e-05 -5.7 6.90e+01 - 1.00e+00 1.00e+00H 1\n", + " 71 5.0751786e-04 7.94e-05 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", + " 72 5.0754292e-04 6.40e-01 8.69e-06 -5.7 6.93e+01 - 1.00e+00 5.00e-01h 2\n", + " 73 5.0749299e-04 3.95e-01 1.21e-05 -5.7 2.35e+01 - 1.00e+00 5.00e-01h 2\n", + " 74 5.0755524e-04 1.36e-01 3.09e-05 -5.7 1.57e+01 - 1.00e+00 1.00e+00h 1\n", + " 75 5.0751308e-04 1.96e-02 1.80e-05 -5.7 3.30e+01 - 1.00e+00 1.00e+00H 1\n", + " 76 5.0754492e-04 5.62e-01 8.19e-06 -5.7 6.42e+01 - 1.00e+00 5.00e-01h 2\n", + " 77 5.0748301e-04 3.98e-01 1.25e-05 -5.7 2.93e+01 - 1.00e+00 5.00e-01h 2\n", + " 78 5.0756455e-04 2.42e-01 3.07e-05 -5.7 2.09e+01 - 1.00e+00 1.00e+00h 1\n", + " 79 5.0751710e-04 1.38e-03 1.87e-05 -5.7 3.98e+01 - 1.00e+00 1.00e+00H 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 80 5.0783077e-04 3.26e-06 1.84e-05 -5.7 6.70e+01 - 1.00e+00 1.00e+00H 1\n", + " 81 5.0726420e-04 1.24e+01 1.85e-05 -8.6 1.34e+02 - 9.93e-01 1.00e+00h 1\n", + " 82 5.0749897e-04 2.75e+00 2.53e-06 -8.6 6.93e+01 - 1.00e+00 1.00e+00h 1\n", + " 83 5.0749686e-04 3.64e-04 6.40e-10 -8.6 4.69e-02 - 1.00e+00 1.00e+00h 1\n", + " 84 5.0749686e-04 7.28e-11 2.51e-14 -8.6 6.86e-05 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 84\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 5.0749685809243843e-04 5.0749685809243843e-04\n", + "Dual infeasibility......: 2.5059195074646584e-14 2.5059195074646584e-14\n", + "Constraint violation....: 1.4104644499482425e-11 7.2759576141834259e-11\n", + "Complementarity.........: 2.5059035596800647e-09 2.5059035596800647e-09\n", + "Overall NLP error.......: 2.5059035596800647e-09 2.5059035596800647e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 260\n", + "Number of objective gradient evaluations = 85\n", + "Number of equality constraint evaluations = 260\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 85\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 84\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.333\n", + "Total CPU secs in NLP function evaluations = 0.095\n", + "\n", + "EXIT: Optimal Solution Found.\n" + ] + } + ], + "source": [ + "obj_value_new, parameters_new = pest_new.theta_est()" + ] }, { "cell_type": "code", @@ -1048,9 +1262,21 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 27, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The SSE at the optimal solution is 0.000507\n", + "\n", + "The values for the parameters are as follows:\n", + "fs.properties.tau[benzene,toluene] = -0.8987624039723882\n", + "fs.properties.tau[toluene,benzene] = 1.4104861106604814\n" + ] + } + ], "source": [ "print(\"The SSE at the optimal solution is %0.6f\" % (obj_value * 1e-4))\n", "print()\n", @@ -1066,6 +1292,32 @@ "Using the data that was provided, we have estimated the binary interaction parameters in the NRTL model for a benzene-toluene mixture. Although the dataset that was provided was temperature dependent, in this example we have estimated a single value that fits best for all temperatures." ] }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The SSE at the optimal solution is 0.000507\n", + "\n", + "The values for the parameters are as follows:\n", + "fs.properties.tau[benzene,toluene] = -0.8987454466579063\n", + "fs.properties.tau[toluene,benzene] = 1.410449514796474\n" + ] + } + ], + "source": [ + "# Repeat with new interface\n", + "print(\"The SSE at the optimal solution is %0.6f\" % (obj_value_new))\n", + "print()\n", + "print(\"The values for the parameters are as follows:\")\n", + "for k, v in parameters_new.items():\n", + " print(k, \"=\", v)" + ] + }, { "cell_type": "markdown", "metadata": {}, From b8584b8ee73c2b4103d0fbf04b8b149dac7b62eb Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Wed, 10 Jun 2026 17:10:06 -0400 Subject: [PATCH 03/23] Ran black --- ...ter_estimation_nrtl_using_unit_model.ipynb | 59 ++++++++++--------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb index 79dec127..304c2f87 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb @@ -375,16 +375,13 @@ "# Build an experiment class to take advantage of new parmest interface\n", "from pyomo.contrib.parmest.experiment import Experiment\n", "\n", + "\n", "class NRTLExperiment(Experiment):\n", - " \"\"\" Experiment class for parameter estimation of NRTL model using parmest\"\"\"\n", - "\n", - " def __init__(self, \n", - " data,\n", - " meas_error = None,\n", - " ):\n", - " \n", - " \"\"\" Initialize the NRTLExperiment class\n", - " \n", + " \"\"\"Experiment class for parameter estimation of NRTL model using parmest\"\"\"\n", + "\n", + " def __init__(self, data, meas_error=None):\n", + " \"\"\"Initialize the NRTLExperiment class\n", + "\n", " Args:\n", " data: DataFrame containing the experimental data\n", " meas_error: Measurement error for the data (optional)\n", @@ -394,45 +391,51 @@ " self.meas_error = meas_error\n", "\n", " def create_model(self):\n", - " \"\"\" Create the Pyomo model for the NRTL parameter estimation problem \"\"\"\n", + " \"\"\"Create the Pyomo model for the NRTL parameter estimation problem\"\"\"\n", " self.model = NRTL_model(self.data)\n", - " \n", + "\n", " def label_model(self):\n", " m = self.model\n", "\n", " # Add experiment outputs to the model for easier access\n", " m.experiment_outputs = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", " m.experiment_outputs.update(\n", - " [(m.fs.flash.liq_outlet.mole_frac_comp[0, \"benzene\"], self.data[\"liq_benzene\"]),\n", - " (m.fs.flash.vap_outlet.mole_frac_comp[0, \"benzene\"], self.data[\"vap_benzene\"])\n", - " ])\n", + " [\n", + " (\n", + " m.fs.flash.liq_outlet.mole_frac_comp[0, \"benzene\"],\n", + " self.data[\"liq_benzene\"],\n", + " ),\n", + " (\n", + " m.fs.flash.vap_outlet.mole_frac_comp[0, \"benzene\"],\n", + " self.data[\"vap_benzene\"],\n", + " ),\n", + " ]\n", + " )\n", "\n", " m.measurement_error = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", " m.measurement_error.update(\n", - " [(m.fs.flash.liq_outlet.mole_frac_comp[0, \"benzene\"], self.meas_error),\n", - " (m.fs.flash.vap_outlet.mole_frac_comp[0, \"benzene\"], self.meas_error)\n", - " ]\n", + " [\n", + " (m.fs.flash.liq_outlet.mole_frac_comp[0, \"benzene\"], self.meas_error),\n", + " (m.fs.flash.vap_outlet.mole_frac_comp[0, \"benzene\"], self.meas_error),\n", + " ]\n", " )\n", "\n", " # Add unknown parameters to the model for easier access\n", " m.unknown_parameters = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", " m.unknown_parameters.update(\n", - " (k, pyo.value(k)) for k in \n", - "\n", - " [m.fs.properties.tau[\"benzene\", \"toluene\"],\n", - " m.fs.properties.tau[\"toluene\", \"benzene\"],\n", + " (k, pyo.value(k))\n", + " for k in [\n", + " m.fs.properties.tau[\"benzene\", \"toluene\"],\n", + " m.fs.properties.tau[\"toluene\", \"benzene\"],\n", " ]\n", - " )\n", - " \n", + " )\n", + "\n", " def get_labeled_model(self):\n", - " \"\"\" Return the labeled model \"\"\"\n", + " \"\"\"Return the labeled model\"\"\"\n", " if self.model is None:\n", " self.create_model()\n", " self.label_model()\n", - " return self.model\n", - "\n", - "\n", - " \n" + " return self.model" ] }, { From b08d24ff9cf07741c97332fbef0cba2afb6811bc Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Wed, 10 Jun 2026 22:17:28 -0400 Subject: [PATCH 04/23] All source files running with new interface --- ...er_estimation_nrtl_using_state_block.ipynb | 1149 ++++++++++++++++- ...ter_estimation_nrtl_using_unit_model.ipynb | 171 +-- .../properties/parameter_estimation_pr.ipynb | 592 ++++++++- 3 files changed, 1698 insertions(+), 214 deletions(-) diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block.ipynb index a9b7b17b..8a33c6a1 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": { "tags": [ "header", @@ -60,7 +60,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": { "tags": [ "exercise" @@ -75,7 +75,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": { "tags": [ "solution" @@ -84,7 +84,7 @@ "outputs": [], "source": [ "# Todo: import ConcreteModel from pyomo.environ\n", - "from pyomo.environ import ConcreteModel, value\n", + "import pyomo.environ as pyo\n", "\n", "# Todo: import FlowsheetBlock from idaes.core\n", "from idaes.core import FlowsheetBlock" @@ -99,7 +99,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": { "tags": [] }, @@ -120,7 +120,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": { "tags": [] }, @@ -151,7 +151,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "metadata": { "tags": [ "exercise" @@ -217,7 +217,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 29, "metadata": { "tags": [ "solution" @@ -228,7 +228,7 @@ "def NRTL_model(data):\n", "\n", " # Todo: Create a ConcreteModel object\n", - " m = ConcreteModel()\n", + " m = pyo.ConcreteModel()\n", "\n", " # Todo: Create FlowsheetBlock object\n", " m.fs = FlowsheetBlock(dynamic=False)\n", @@ -289,7 +289,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 30, "metadata": { "tags": [ "testing" @@ -309,21 +309,400 @@ "assert degrees_of_freedom(m) == 0\n", "\n", "# Check for output values\n", - "assert value(m.fs.state_block.mole_frac_phase_comp[\"Liq\", \"benzene\"]) == pytest.approx(\n", + "assert pyo.value(m.fs.state_block.mole_frac_phase_comp[\"Liq\", \"benzene\"]) == pytest.approx(\n", " 0.389, abs=1e-2\n", ")\n", - "assert value(m.fs.state_block.mole_frac_phase_comp[\"Vap\", \"benzene\"]) == pytest.approx(\n", + "assert pyo.value(m.fs.state_block.mole_frac_phase_comp[\"Vap\", \"benzene\"]) == pytest.approx(\n", " 0.610, abs=1e-2\n", ")\n", "\n", - "assert value(m.fs.state_block.mole_frac_phase_comp[\"Liq\", \"toluene\"]) == pytest.approx(\n", + "assert pyo.value(m.fs.state_block.mole_frac_phase_comp[\"Liq\", \"toluene\"]) == pytest.approx(\n", " 0.610, abs=1e-2\n", ")\n", - "assert value(m.fs.state_block.mole_frac_phase_comp[\"Vap\", \"toluene\"]) == pytest.approx(\n", + "assert pyo.value(m.fs.state_block.mole_frac_phase_comp[\"Vap\", \"toluene\"]) == pytest.approx(\n", " 0.394, abs=1e-2\n", ")" ] }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1 Block Declarations\n", + " fs : Size=1, Index=None, Active=True\n", + " 1 Set Declarations\n", + " _time : Size=1, Index=None, Ordered=Insertion\n", + " Key : Dimen : Domain : Size : Members\n", + " None : 1 : Any : 1 : {0.0,}\n", + "\n", + " 2 Block Declarations\n", + " properties : Size=1, Index=None, Active=True\n", + " 6 Set Declarations\n", + " _phase_component_set : Size=1, Index=None, Ordered=Insertion\n", + " Key : Dimen : Domain : Size : Members\n", + " None : 2 : Any : 4 : {('Liq', 'benzene'), ('Liq', 'toluene'), ('Vap', 'benzene'), ('Vap', 'toluene')}\n", + " component_list : Size=1, Index=None, Ordered=Insertion\n", + " Key : Dimen : Domain : Size : Members\n", + " None : 1 : Any : 2 : {'benzene', 'toluene'}\n", + " component_list_master : Size=1, Index=None, Ordered=Insertion\n", + " Key : Dimen : Domain : Size : Members\n", + " None : 1 : Any : 3 : {'benzene', 'toluene', 'o-xylene'}\n", + " phase_equilibrium_idx : Size=1, Index=None, Ordered=Insertion\n", + " Key : Dimen : Domain : Size : Members\n", + " None : 1 : Any : 2 : {1, 2}\n", + " phase_equilibrium_idx_master : Size=1, Index=None, Ordered=Insertion\n", + " Key : Dimen : Domain : Size : Members\n", + " None : 1 : Any : 3 : {1, 2, 3}\n", + " phase_list : Size=1, Index=None, Ordered=Insertion\n", + " Key : Dimen : Domain : Size : Members\n", + " None : 1 : Any : 2 : {'Liq', 'Vap'}\n", + "\n", + " 18 Param Declarations\n", + " cp_mol_liq_comp_coeff_A : Liquid phase Cp parameter A\n", + " Size=2, Index=fs.properties.component_list, Domain=Any, Default=None, Mutable=True, Units=J/K/kmol\n", + " Key : Value\n", + " benzene : 129000.0\n", + " toluene : 140000.0\n", + " cp_mol_liq_comp_coeff_B : Liquid phase Cp parameter B\n", + " Size=2, Index=fs.properties.component_list, Domain=Any, Default=None, Mutable=True, Units=J/K**2/kmol\n", + " Key : Value\n", + " benzene : -170.0\n", + " toluene : -152.0\n", + " cp_mol_liq_comp_coeff_C : Liquid phase Cp parameter C\n", + " Size=2, Index=fs.properties.component_list, Domain=Any, Default=None, Mutable=True, Units=J/K**3/kmol\n", + " Key : Value\n", + " benzene : 0.648\n", + " toluene : 0.695\n", + " cp_mol_liq_comp_coeff_D : Liquid phase Cp parameter D\n", + " Size=2, Index=fs.properties.component_list, Domain=Any, Default=None, Mutable=True, Units=J/K**4/kmol\n", + " Key : Value\n", + " benzene : 0\n", + " toluene : 0\n", + " cp_mol_liq_comp_coeff_E : Liquid phase Cp parameter E\n", + " Size=2, Index=fs.properties.component_list, Domain=Any, Default=None, Mutable=True, Units=J/K**5/kmol\n", + " Key : Value\n", + " benzene : 0\n", + " toluene : 0\n", + " cp_mol_vap_comp_coeff_A : Vapor phase Cp parameter A\n", + " Size=2, Index=fs.properties.component_list, Domain=Any, Default=None, Mutable=True, Units=J/K/mol\n", + " Key : Value\n", + " benzene : -33.92\n", + " toluene : -24.35\n", + " cp_mol_vap_comp_coeff_B : Vapor phase Cp parameter B\n", + " Size=2, Index=fs.properties.component_list, Domain=Any, Default=None, Mutable=True, Units=J/K**2/mol\n", + " Key : Value\n", + " benzene : 0.4739\n", + " toluene : 0.5125\n", + " cp_mol_vap_comp_coeff_C : Vapor phase Cp parameter C\n", + " Size=2, Index=fs.properties.component_list, Domain=Any, Default=None, Mutable=True, Units=J/K**3/mol\n", + " Key : Value\n", + " benzene : -0.0003017\n", + " toluene : -0.0002765\n", + " cp_mol_vap_comp_coeff_D : Vapor phase Cp parameter D\n", + " Size=2, Index=fs.properties.component_list, Domain=Any, Default=None, Mutable=True, Units=J/K**4/mol\n", + " Key : Value\n", + " benzene : 7.13e-08\n", + " toluene : 4.911e-08\n", + " cp_mol_vap_comp_coeff_E : Vapor phase Cp parameter E\n", + " Size=2, Index=fs.properties.component_list, Domain=Any, Default=None, Mutable=True, Units=J/K**5/mol\n", + " Key : Value\n", + " benzene : 0\n", + " toluene : 0\n", + " dh_form : Standard heats of formation [J/mol]\n", + " Size=4, Index=fs.properties.phase_list*fs.properties.component_list, Domain=Any, Default=None, Mutable=True, Units=J/mol\n", + " Key : Value\n", + " ('Liq', 'benzene') : 49000.0\n", + " ('Liq', 'toluene') : 12000.0\n", + " ('Vap', 'benzene') : 82900.0\n", + " ('Vap', 'toluene') : 50100.0\n", + " ds_form : Standard entropy of formation [J/mol.K]\n", + " Size=4, Index=fs.properties.phase_list*fs.properties.component_list, Domain=Any, Default=None, Mutable=True, Units=J/K/mol\n", + " Key : Value\n", + " ('Liq', 'benzene') : -173\n", + " ('Liq', 'toluene') : -220\n", + " ('Vap', 'benzene') : -269\n", + " ('Vap', 'toluene') : -321\n", + " mw_comp : molecular weight kg/mol\n", + " Size=2, Index=fs.properties.component_list, Domain=Any, Default=None, Mutable=True, Units=kg/mol\n", + " Key : Value\n", + " benzene : 0.0781136\n", + " toluene : 0.0921405\n", + " pressure_critical : Critical pressure [Pa]\n", + " Size=2, Index=fs.properties.component_list, Domain=NonNegativeReals, Default=None, Mutable=True, Units=Pa\n", + " Key : Value\n", + " benzene : 4890000.0\n", + " toluene : 4100000.0\n", + " pressure_reference : Reference pressure [Pa]\n", + " Size=1, Index=None, Domain=Any, Default=101325, Mutable=True, Units=Pa\n", + " Key : Value\n", + " pressure_sat_coeff : parameters to compute P_sat\n", + " Size=8, Index=fs.properties.component_list*{A, B, C, D}, Domain=Any, Default=None, Mutable=False\n", + " Key : Value\n", + " ('benzene', 'A') : -6.98273\n", + " ('benzene', 'B') : 1.33213\n", + " ('benzene', 'C') : -2.62863\n", + " ('benzene', 'D') : -3.33399\n", + " ('toluene', 'A') : -7.28607\n", + " ('toluene', 'B') : 1.38091\n", + " ('toluene', 'C') : -2.83433\n", + " ('toluene', 'D') : -2.79168\n", + " temperature_critical : Critical temperature [K]\n", + " Size=2, Index=fs.properties.component_list, Domain=NonNegativeReals, Default=None, Mutable=True, Units=K\n", + " Key : Value\n", + " benzene : 562.2\n", + " toluene : 591.8\n", + " temperature_reference : Reference temperature [K]\n", + " Size=1, Index=None, Domain=Any, Default=298.15, Mutable=True, Units=K\n", + " Key : Value\n", + "\n", + " 2 Var Declarations\n", + " alpha : Non-randomness parameter for NRTL model\n", + " Size=4, Index=fs.properties.component_list*fs.properties.component_list\n", + " Key : Lower : Value : Upper : Fixed : Stale : Domain\n", + " ('benzene', 'benzene') : None : 0 : None : True : True : Reals\n", + " ('benzene', 'toluene') : None : 0.3 : None : True : True : Reals\n", + " ('toluene', 'benzene') : None : 0.3 : None : True : True : Reals\n", + " ('toluene', 'toluene') : None : 0 : None : True : True : Reals\n", + " tau : Binary interaction parameter for NRTL model\n", + " Size=4, Index=fs.properties.component_list*fs.properties.component_list\n", + " Key : Lower : Value : Upper : Fixed : Stale : Domain\n", + " ('benzene', 'benzene') : None : 0 : None : True : True : Reals\n", + " ('benzene', 'toluene') : -5 : -0.9 : 5 : True : True : Reals\n", + " ('toluene', 'benzene') : -5 : 1.4 : 5 : True : True : Reals\n", + " ('toluene', 'toluene') : None : 0 : None : True : True : Reals\n", + "\n", + " 4 Block Declarations\n", + " Liq : Size=1, Index=None, Active=True\n", + " 0 Declarations: \n", + " Vap : Size=1, Index=None, Active=True\n", + " 0 Declarations: \n", + " benzene : Size=1, Index=None, Active=True\n", + " 0 Declarations: \n", + " toluene : Size=1, Index=None, Active=True\n", + " 0 Declarations: \n", + "\n", + " 30 Declarations: component_list_master benzene component_list toluene Liq phase_list Vap alpha tau phase_equilibrium_idx_master phase_equilibrium_idx pressure_reference temperature_reference pressure_critical temperature_critical mw_comp cp_mol_liq_comp_coeff_A cp_mol_liq_comp_coeff_B cp_mol_liq_comp_coeff_C cp_mol_liq_comp_coeff_D cp_mol_liq_comp_coeff_E cp_mol_vap_comp_coeff_A cp_mol_vap_comp_coeff_B cp_mol_vap_comp_coeff_C cp_mol_vap_comp_coeff_D cp_mol_vap_comp_coeff_E pressure_sat_coeff dh_form ds_form _phase_component_set\n", + " state_block : Size=1, Index=None, Active=True\n", + " 2 Param Declarations\n", + " eps_1 : Smoothing parameter for equilibrium temperature\n", + " Size=1, Index=None, Domain=Any, Default=0.01, Mutable=True, Units=K\n", + " Key : Value\n", + " None : 0.01\n", + " eps_2 : Smoothing parameter for equilibrium temperature\n", + " Size=1, Index=None, Domain=Any, Default=0.0005, Mutable=True, Units=K\n", + " Key : Value\n", + " None : 0.0005\n", + "\n", + " 15 Var Declarations\n", + " A : Intermediate variable to compute activity coefficient\n", + " Size=2, Index=fs.properties.component_list\n", + " Key : Lower : Value : Upper : Fixed : Stale : Domain\n", + " benzene : None : 0.7100260859013878 : None : False : False : Reals\n", + " toluene : None : -0.4099107824679704 : None : False : False : Reals\n", + " B : Intermediate variable to compute activity coefficient\n", + " Size=2, Index=fs.properties.component_list\n", + " Key : Lower : Value : Upper : Fixed : Stale : Domain\n", + " benzene : None : -0.6995248754062293 : None : False : False : Reals\n", + " toluene : None : 0.44664023909664 : None : False : False : Reals\n", + " Gij_coeff : Gij coefficient for use in NRTL model \n", + " Size=4, Index=fs.properties.component_list*fs.properties.component_list\n", + " Key : Lower : Value : Upper : Fixed : Stale : Domain\n", + " ('benzene', 'benzene') : None : 1 : None : True : True : Reals\n", + " ('benzene', 'toluene') : None : 1.3099644507332473 : None : False : False : Reals\n", + " ('toluene', 'benzene') : None : 0.6570468198150567 : None : False : False : Reals\n", + " ('toluene', 'toluene') : None : 1 : None : True : True : Reals\n", + " _t1 : Intermediate temperature for calculating the equilibrium temperature\n", + " Size=1, Index=None, Units=K\n", + " Key : Lower : Value : Upper : Fixed : Stale : Domain\n", + " None : None : 368.0000081121381 : None : False : False : Reals\n", + " _temperature_equilibrium : Temperature for calculating phase equilibrium\n", + " Size=1, Index=None, Units=K\n", + " Key : Lower : Value : Upper : Fixed : Stale : Domain\n", + " None : None : 368.00000809159246 : None : False : False : Reals\n", + " activity_coeff_comp : Activity coefficient of component\n", + " Size=2, Index=fs.properties.component_list\n", + " Key : Lower : Value : Upper : Fixed : Stale : Domain\n", + " benzene : None : 1.010556541718034 : None : False : False : Reals\n", + " toluene : None : 1.0374123178427703 : None : False : False : Reals\n", + " flow_mol : Total molar flowrate [mol/s]\n", + " Size=1, Index=None, Units=mol/s\n", + " Key : Lower : Value : Upper : Fixed : Stale : Domain\n", + " None : 0 : 1 : None : True : True : NonNegativeReals\n", + " flow_mol_phase : Size=2, Index=fs.properties.phase_list, Units=mol/s\n", + " Key : Lower : Value : Upper : Fixed : Stale : Domain\n", + " Liq : None : 0.4895285678452709 : None : False : False : Reals\n", + " Vap : None : 0.5104714321547291 : None : False : False : Reals\n", + " mole_frac_comp : Mixture mole fraction\n", + " Size=2, Index=fs.properties.component_list\n", + " Key : Lower : Value : Upper : Fixed : Stale : Domain\n", + " benzene : 0 : 0.5 : 1 : True : True : Reals\n", + " toluene : 0 : 0.5 : 1 : True : True : Reals\n", + " mole_frac_phase_comp : Size=4, Index=fs.properties._phase_component_set\n", + " Key : Lower : Value : Upper : Fixed : Stale : Domain\n", + " ('Liq', 'benzene') : 0 : 0.3896822835079589 : 1 : False : False : Reals\n", + " ('Liq', 'toluene') : 0 : 0.6103177164920411 : 1 : False : False : Reals\n", + " ('Vap', 'benzene') : 0 : 0.6057917649390352 : 1 : False : False : Reals\n", + " ('Vap', 'toluene') : 0 : 0.3942082350609649 : 1 : False : False : Reals\n", + " pressure : State pressure [Pa]\n", + " Size=1, Index=None, Units=Pa\n", + " Key : Lower : Value : Upper : Fixed : Stale : Domain\n", + " None : 0 : 101325 : None : True : True : NonNegativeReals\n", + " pressure_sat_comp : vapor pressure\n", + " Size=2, Index=fs.properties.component_list, Units=Pa\n", + " Key : Lower : Value : Upper : Fixed : Stale : Domain\n", + " benzene : None : 155872.21194897484 : None : False : False : Reals\n", + " toluene : None : 63086.28122456876 : None : False : False : Reals\n", + " temperature : State temperature [K]\n", + " Size=1, Index=None, Units=K\n", + " Key : Lower : Value : Upper : Fixed : Stale : Domain\n", + " None : 0 : 368.0 : None : True : False : NonNegativeReals\n", + " temperature_bubble : Bubble point temperature (K)\n", + " Size=1, Index=None, Units=K\n", + " Key : Lower : Value : Upper : Fixed : Stale : Domain\n", + " None : None : 364.9182065507927 : None : False : False : Reals\n", + " temperature_dew : Dew point temperature (K)\n", + " Size=1, Index=None, Units=K\n", + " Key : Lower : Value : Upper : Fixed : Stale : Domain\n", + " None : None : 371.0420078019091 : None : False : False : Reals\n", + "\n", + " 12 Expression Declarations\n", + " A_bubble : Size=2, Index=fs.properties.component_list\n", + " Key : Expression\n", + " benzene : (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,benzene]*1 + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,benzene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))\n", + " toluene : (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,toluene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,toluene]*1)/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1)\n", + " A_dew : Size=2, Index=fs.properties.component_list\n", + " Key : Expression\n", + " benzene : (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,benzene]*1 + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,benzene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))\n", + " toluene : (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,toluene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,toluene]*1)/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1)\n", + " B_bubble : Size=2, Index=fs.properties.component_list\n", + " Key : Expression\n", + " benzene : fs.state_block.mole_frac_comp[benzene]*1/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))*(fs.properties.tau[benzene,benzene] - (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,benzene]*1 + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,benzene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))) + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene])/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1)*(fs.properties.tau[benzene,toluene] - (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,toluene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,toluene]*1)/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1))\n", + " toluene : fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene])/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))*(fs.properties.tau[toluene,benzene] - (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,benzene]*1 + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,benzene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))) + fs.state_block.mole_frac_comp[toluene]*1/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1)*(fs.properties.tau[toluene,toluene] - (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,toluene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,toluene]*1)/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1))\n", + " B_dew : Size=2, Index=fs.properties.component_list\n", + " Key : Expression\n", + " benzene : fs.state_block.mole_frac_comp[benzene]*1/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))*(fs.properties.tau[benzene,benzene] - (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,benzene]*1 + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,benzene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))) + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene])/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1)*(fs.properties.tau[benzene,toluene] - (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,toluene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,toluene]*1)/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1))\n", + " toluene : fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene])/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))*(fs.properties.tau[toluene,benzene] - (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,benzene]*1 + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,benzene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))) + fs.state_block.mole_frac_comp[toluene]*1/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1)*(fs.properties.tau[toluene,toluene] - (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,toluene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,toluene]*1)/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1))\n", + " Gij_coeff_bubble : Size=4, Index=fs.properties.component_list*fs.properties.component_list\n", + " Key : Expression\n", + " ('benzene', 'benzene') : 1.0\n", + " ('benzene', 'toluene') : exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene])\n", + " ('toluene', 'benzene') : exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene])\n", + " ('toluene', 'toluene') : 1.0\n", + " Gij_coeff_dew : Size=4, Index=fs.properties.component_list*fs.properties.component_list\n", + " Key : Expression\n", + " ('benzene', 'benzene') : 1.0\n", + " ('benzene', 'toluene') : exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene])\n", + " ('toluene', 'benzene') : exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene])\n", + " ('toluene', 'toluene') : 1.0\n", + " _p_sat_bubbleT : Size=2, Index=fs.properties.component_list\n", + " Key : Expression\n", + " benzene : fs.properties.pressure_critical[benzene]*exp((-6.98273*(1 - 1/fs.properties.temperature_critical[benzene]*fs.state_block.temperature_bubble) + 1.33213*(1 - 1/fs.properties.temperature_critical[benzene]*fs.state_block.temperature_bubble)**1.5 - 2.62863*(1 - 1/fs.properties.temperature_critical[benzene]*fs.state_block.temperature_bubble)**3 - 3.33399*(1 - 1/fs.properties.temperature_critical[benzene]*fs.state_block.temperature_bubble)**6)/(1 - (1 - 1/fs.properties.temperature_critical[benzene]*fs.state_block.temperature_bubble)))\n", + " toluene : fs.properties.pressure_critical[toluene]*exp((-7.28607*(1 - 1/fs.properties.temperature_critical[toluene]*fs.state_block.temperature_bubble) + 1.38091*(1 - 1/fs.properties.temperature_critical[toluene]*fs.state_block.temperature_bubble)**1.5 - 2.83433*(1 - 1/fs.properties.temperature_critical[toluene]*fs.state_block.temperature_bubble)**3 - 2.79168*(1 - 1/fs.properties.temperature_critical[toluene]*fs.state_block.temperature_bubble)**6)/(1 - (1 - 1/fs.properties.temperature_critical[toluene]*fs.state_block.temperature_bubble)))\n", + " _p_sat_dewT : Size=2, Index=fs.properties.component_list\n", + " Key : Expression\n", + " benzene : fs.properties.pressure_critical[benzene]*exp((-6.98273*(1 - 1/fs.properties.temperature_critical[benzene]*fs.state_block.temperature_dew) + 1.33213*(1 - 1/fs.properties.temperature_critical[benzene]*fs.state_block.temperature_dew)**1.5 - 2.62863*(1 - 1/fs.properties.temperature_critical[benzene]*fs.state_block.temperature_dew)**3 - 3.33399*(1 - 1/fs.properties.temperature_critical[benzene]*fs.state_block.temperature_dew)**6)/(1 - (1 - 1/fs.properties.temperature_critical[benzene]*fs.state_block.temperature_dew)))\n", + " toluene : fs.properties.pressure_critical[toluene]*exp((-7.28607*(1 - 1/fs.properties.temperature_critical[toluene]*fs.state_block.temperature_dew) + 1.38091*(1 - 1/fs.properties.temperature_critical[toluene]*fs.state_block.temperature_dew)**1.5 - 2.83433*(1 - 1/fs.properties.temperature_critical[toluene]*fs.state_block.temperature_dew)**3 - 2.79168*(1 - 1/fs.properties.temperature_critical[toluene]*fs.state_block.temperature_dew)**6)/(1 - (1 - 1/fs.properties.temperature_critical[toluene]*fs.state_block.temperature_dew)))\n", + " _reduced_temp : Size=2, Index=fs.properties.component_list\n", + " Key : Expression\n", + " benzene : (fs.properties.temperature_critical[benzene] - fs.state_block._temperature_equilibrium)/fs.properties.temperature_critical[benzene]\n", + " toluene : (fs.properties.temperature_critical[toluene] - fs.state_block._temperature_equilibrium)/fs.properties.temperature_critical[toluene]\n", + " activity_coeff_comp_bubble : Size=2, Index=fs.properties.component_list\n", + " Key : Expression\n", + " benzene : exp(((fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,benzene]*1 + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,benzene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))) + (fs.state_block.mole_frac_comp[benzene]*1/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))*(fs.properties.tau[benzene,benzene] - (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,benzene]*1 + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,benzene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))) + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene])/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1)*(fs.properties.tau[benzene,toluene] - (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,toluene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,toluene]*1)/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1))))\n", + " toluene : exp(((fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,toluene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,toluene]*1)/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1)) + (fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene])/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))*(fs.properties.tau[toluene,benzene] - (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,benzene]*1 + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,benzene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))) + fs.state_block.mole_frac_comp[toluene]*1/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1)*(fs.properties.tau[toluene,toluene] - (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,toluene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,toluene]*1)/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1))))\n", + " activity_coeff_comp_dew : Size=2, Index=fs.properties.component_list\n", + " Key : Expression\n", + " benzene : exp(((fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,benzene]*1 + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,benzene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))) + (fs.state_block.mole_frac_comp[benzene]*1/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))*(fs.properties.tau[benzene,benzene] - (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,benzene]*1 + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,benzene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))) + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene])/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1)*(fs.properties.tau[benzene,toluene] - (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,toluene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,toluene]*1)/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1))))\n", + " toluene : exp(((fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,toluene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,toluene]*1)/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1)) + (fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene])/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))*(fs.properties.tau[toluene,benzene] - (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,benzene]*1 + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,benzene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))) + fs.state_block.mole_frac_comp[toluene]*1/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1)*(fs.properties.tau[toluene,toluene] - (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,toluene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,toluene]*1)/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1))))\n", + " fug_phase_comp : Size=4, Index=fs.properties.phase_list*fs.properties.component_list\n", + " Key : Expression\n", + " ('Liq', 'benzene') : fs.state_block.mole_frac_phase_comp[Liq,benzene]*fs.state_block.activity_coeff_comp[benzene]*fs.state_block.pressure_sat_comp[benzene]\n", + " ('Liq', 'toluene') : fs.state_block.mole_frac_phase_comp[Liq,toluene]*fs.state_block.activity_coeff_comp[toluene]*fs.state_block.pressure_sat_comp[toluene]\n", + " ('Vap', 'benzene') : fs.state_block.mole_frac_phase_comp[Vap,benzene]*fs.state_block.pressure\n", + " ('Vap', 'toluene') : fs.state_block.mole_frac_phase_comp[Vap,toluene]*fs.state_block.pressure\n", + "\n", + " 13 Constraint Declarations\n", + " _t1_constraint : Size=1, Index=None, Active=True\n", + " Key : Lower : Body : Upper : Active\n", + " None : 0.0 : fs.state_block._t1 - 0.5*(fs.state_block.temperature + fs.state_block.temperature_bubble + sqrt((fs.state_block.temperature - fs.state_block.temperature_bubble)**2 + fs.state_block.eps_1**2)) : 0.0 : True\n", + " _teq_constraint : Size=1, Index=None, Active=True\n", + " Key : Lower : Body : Upper : Active\n", + " None : 0.0 : fs.state_block._temperature_equilibrium - 0.5*(fs.state_block._t1 + fs.state_block.temperature_dew - sqrt((fs.state_block._t1 - fs.state_block.temperature_dew)**2 + fs.state_block.eps_2**2)) : 0.0 : True\n", + " eq_A : Size=2, Index=fs.properties.component_list, Active=True\n", + " Key : Lower : Body : Upper : Active\n", + " benzene : 0.0 : fs.state_block.A[benzene] - (fs.state_block.mole_frac_phase_comp[Liq,benzene]*fs.properties.tau[benzene,benzene]*fs.state_block.Gij_coeff[benzene,benzene] + fs.state_block.mole_frac_phase_comp[Liq,toluene]*fs.properties.tau[toluene,benzene]*fs.state_block.Gij_coeff[toluene,benzene])/(fs.state_block.mole_frac_phase_comp[Liq,benzene]*fs.state_block.Gij_coeff[benzene,benzene] + fs.state_block.mole_frac_phase_comp[Liq,toluene]*fs.state_block.Gij_coeff[toluene,benzene]) : 0.0 : True\n", + " toluene : 0.0 : fs.state_block.A[toluene] - (fs.state_block.mole_frac_phase_comp[Liq,benzene]*fs.properties.tau[benzene,toluene]*fs.state_block.Gij_coeff[benzene,toluene] + fs.state_block.mole_frac_phase_comp[Liq,toluene]*fs.properties.tau[toluene,toluene]*fs.state_block.Gij_coeff[toluene,toluene])/(fs.state_block.mole_frac_phase_comp[Liq,benzene]*fs.state_block.Gij_coeff[benzene,toluene] + fs.state_block.mole_frac_phase_comp[Liq,toluene]*fs.state_block.Gij_coeff[toluene,toluene]) : 0.0 : True\n", + " eq_B : Size=2, Index=fs.properties.component_list, Active=True\n", + " Key : Lower : Body : Upper : Active\n", + " benzene : 0.0 : fs.state_block.B[benzene] - (fs.state_block.mole_frac_phase_comp[Liq,benzene]*fs.state_block.Gij_coeff[benzene,benzene]/(fs.state_block.mole_frac_phase_comp[Liq,benzene]*fs.state_block.Gij_coeff[benzene,benzene] + fs.state_block.mole_frac_phase_comp[Liq,toluene]*fs.state_block.Gij_coeff[toluene,benzene])*(fs.properties.tau[benzene,benzene] - (fs.state_block.mole_frac_phase_comp[Liq,benzene]*fs.properties.tau[benzene,benzene]*fs.state_block.Gij_coeff[benzene,benzene] + fs.state_block.mole_frac_phase_comp[Liq,toluene]*fs.properties.tau[toluene,benzene]*fs.state_block.Gij_coeff[toluene,benzene])/(fs.state_block.mole_frac_phase_comp[Liq,benzene]*fs.state_block.Gij_coeff[benzene,benzene] + fs.state_block.mole_frac_phase_comp[Liq,toluene]*fs.state_block.Gij_coeff[toluene,benzene])) + fs.state_block.mole_frac_phase_comp[Liq,toluene]*fs.state_block.Gij_coeff[benzene,toluene]/(fs.state_block.mole_frac_phase_comp[Liq,benzene]*fs.state_block.Gij_coeff[benzene,toluene] + fs.state_block.mole_frac_phase_comp[Liq,toluene]*fs.state_block.Gij_coeff[toluene,toluene])*(fs.properties.tau[benzene,toluene] - (fs.state_block.mole_frac_phase_comp[Liq,benzene]*fs.properties.tau[benzene,toluene]*fs.state_block.Gij_coeff[benzene,toluene] + fs.state_block.mole_frac_phase_comp[Liq,toluene]*fs.properties.tau[toluene,toluene]*fs.state_block.Gij_coeff[toluene,toluene])/(fs.state_block.mole_frac_phase_comp[Liq,benzene]*fs.state_block.Gij_coeff[benzene,toluene] + fs.state_block.mole_frac_phase_comp[Liq,toluene]*fs.state_block.Gij_coeff[toluene,toluene]))) : 0.0 : True\n", + " toluene : 0.0 : fs.state_block.B[toluene] - (fs.state_block.mole_frac_phase_comp[Liq,benzene]*fs.state_block.Gij_coeff[toluene,benzene]/(fs.state_block.mole_frac_phase_comp[Liq,benzene]*fs.state_block.Gij_coeff[benzene,benzene] + fs.state_block.mole_frac_phase_comp[Liq,toluene]*fs.state_block.Gij_coeff[toluene,benzene])*(fs.properties.tau[toluene,benzene] - (fs.state_block.mole_frac_phase_comp[Liq,benzene]*fs.properties.tau[benzene,benzene]*fs.state_block.Gij_coeff[benzene,benzene] + fs.state_block.mole_frac_phase_comp[Liq,toluene]*fs.properties.tau[toluene,benzene]*fs.state_block.Gij_coeff[toluene,benzene])/(fs.state_block.mole_frac_phase_comp[Liq,benzene]*fs.state_block.Gij_coeff[benzene,benzene] + fs.state_block.mole_frac_phase_comp[Liq,toluene]*fs.state_block.Gij_coeff[toluene,benzene])) + fs.state_block.mole_frac_phase_comp[Liq,toluene]*fs.state_block.Gij_coeff[toluene,toluene]/(fs.state_block.mole_frac_phase_comp[Liq,benzene]*fs.state_block.Gij_coeff[benzene,toluene] + fs.state_block.mole_frac_phase_comp[Liq,toluene]*fs.state_block.Gij_coeff[toluene,toluene])*(fs.properties.tau[toluene,toluene] - (fs.state_block.mole_frac_phase_comp[Liq,benzene]*fs.properties.tau[benzene,toluene]*fs.state_block.Gij_coeff[benzene,toluene] + fs.state_block.mole_frac_phase_comp[Liq,toluene]*fs.properties.tau[toluene,toluene]*fs.state_block.Gij_coeff[toluene,toluene])/(fs.state_block.mole_frac_phase_comp[Liq,benzene]*fs.state_block.Gij_coeff[benzene,toluene] + fs.state_block.mole_frac_phase_comp[Liq,toluene]*fs.state_block.Gij_coeff[toluene,toluene]))) : 0.0 : True\n", + " eq_Gij_coeff : Size=2, Index=fs.properties.component_list*fs.properties.component_list, Active=True\n", + " Key : Lower : Body : Upper : Active\n", + " ('benzene', 'toluene') : 0.0 : fs.state_block.Gij_coeff[benzene,toluene] - exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) : 0.0 : True\n", + " ('toluene', 'benzene') : 0.0 : fs.state_block.Gij_coeff[toluene,benzene] - exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]) : 0.0 : True\n", + " eq_P_vap : Size=2, Index=fs.properties.component_list, Active=True\n", + " Key : Lower : Body : Upper : Active\n", + " benzene : 0.0 : (1 - ((fs.properties.temperature_critical[benzene] - fs.state_block._temperature_equilibrium)/fs.properties.temperature_critical[benzene]))*log(1/fs.properties.pressure_critical[benzene]*fs.state_block.pressure_sat_comp[benzene]) - (-6.98273*((fs.properties.temperature_critical[benzene] - fs.state_block._temperature_equilibrium)/fs.properties.temperature_critical[benzene]) + 1.33213*((fs.properties.temperature_critical[benzene] - fs.state_block._temperature_equilibrium)/fs.properties.temperature_critical[benzene])**1.5 - 2.62863*((fs.properties.temperature_critical[benzene] - fs.state_block._temperature_equilibrium)/fs.properties.temperature_critical[benzene])**3 - 3.33399*((fs.properties.temperature_critical[benzene] - fs.state_block._temperature_equilibrium)/fs.properties.temperature_critical[benzene])**6) : 0.0 : True\n", + " toluene : 0.0 : (1 - ((fs.properties.temperature_critical[toluene] - fs.state_block._temperature_equilibrium)/fs.properties.temperature_critical[toluene]))*log(1/fs.properties.pressure_critical[toluene]*fs.state_block.pressure_sat_comp[toluene]) - (-7.28607*((fs.properties.temperature_critical[toluene] - fs.state_block._temperature_equilibrium)/fs.properties.temperature_critical[toluene]) + 1.38091*((fs.properties.temperature_critical[toluene] - fs.state_block._temperature_equilibrium)/fs.properties.temperature_critical[toluene])**1.5 - 2.83433*((fs.properties.temperature_critical[toluene] - fs.state_block._temperature_equilibrium)/fs.properties.temperature_critical[toluene])**3 - 2.79168*((fs.properties.temperature_critical[toluene] - fs.state_block._temperature_equilibrium)/fs.properties.temperature_critical[toluene])**6) : 0.0 : True\n", + " eq_activity_coeff : Size=2, Index=fs.properties.component_list, Active=True\n", + " Key : Lower : Body : Upper : Active\n", + " benzene : 0.0 : log(fs.state_block.activity_coeff_comp[benzene]) - (fs.state_block.A[benzene] + fs.state_block.B[benzene]) : 0.0 : True\n", + " toluene : 0.0 : log(fs.state_block.activity_coeff_comp[toluene]) - (fs.state_block.A[toluene] + fs.state_block.B[toluene]) : 0.0 : True\n", + " eq_comp : Size=2, Index=fs.properties.component_list, Active=True\n", + " Key : Lower : Body : Upper : Active\n", + " benzene : 0.0 : fs.state_block.flow_mol*fs.state_block.mole_frac_comp[benzene] - (fs.state_block.flow_mol_phase[Liq]*fs.state_block.mole_frac_phase_comp[Liq,benzene] + fs.state_block.flow_mol_phase[Vap]*fs.state_block.mole_frac_phase_comp[Vap,benzene]) : 0.0 : True\n", + " toluene : 0.0 : fs.state_block.flow_mol*fs.state_block.mole_frac_comp[toluene] - (fs.state_block.flow_mol_phase[Liq]*fs.state_block.mole_frac_phase_comp[Liq,toluene] + fs.state_block.flow_mol_phase[Vap]*fs.state_block.mole_frac_phase_comp[Vap,toluene]) : 0.0 : True\n", + " eq_phase_equilibrium : Size=2, Index=fs.properties.component_list, Active=True\n", + " Key : Lower : Body : Upper : Active\n", + " benzene : 0.0 : (fs.state_block.mole_frac_phase_comp[Vap,benzene]*fs.state_block.pressure) - (fs.state_block.mole_frac_phase_comp[Liq,benzene]*fs.state_block.activity_coeff_comp[benzene]*fs.state_block.pressure_sat_comp[benzene]) : 0.0 : True\n", + " toluene : 0.0 : (fs.state_block.mole_frac_phase_comp[Vap,toluene]*fs.state_block.pressure) - (fs.state_block.mole_frac_phase_comp[Liq,toluene]*fs.state_block.activity_coeff_comp[toluene]*fs.state_block.pressure_sat_comp[toluene]) : 0.0 : True\n", + " eq_sum_mol_frac : Size=1, Index=None, Active=True\n", + " Key : Lower : Body : Upper : Active\n", + " None : 0.0 : fs.state_block.mole_frac_phase_comp[Liq,benzene] + fs.state_block.mole_frac_phase_comp[Liq,toluene] - (fs.state_block.mole_frac_phase_comp[Vap,benzene] + fs.state_block.mole_frac_phase_comp[Vap,toluene]) : 0.0 : True\n", + " eq_temperature_bubble : Size=1, Index=None, Active=True\n", + " Key : Lower : Body : Upper : Active\n", + " None : 0.0 : fs.state_block.mole_frac_comp[benzene]*exp(((fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,benzene]*1 + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,benzene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))) + (fs.state_block.mole_frac_comp[benzene]*1/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))*(fs.properties.tau[benzene,benzene] - (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,benzene]*1 + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,benzene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))) + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene])/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1)*(fs.properties.tau[benzene,toluene] - (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,toluene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,toluene]*1)/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1))))*(fs.properties.pressure_critical[benzene]*exp((-6.98273*(1 - 1/fs.properties.temperature_critical[benzene]*fs.state_block.temperature_bubble) + 1.33213*(1 - 1/fs.properties.temperature_critical[benzene]*fs.state_block.temperature_bubble)**1.5 - 2.62863*(1 - 1/fs.properties.temperature_critical[benzene]*fs.state_block.temperature_bubble)**3 - 3.33399*(1 - 1/fs.properties.temperature_critical[benzene]*fs.state_block.temperature_bubble)**6)/(1 - (1 - 1/fs.properties.temperature_critical[benzene]*fs.state_block.temperature_bubble)))) + fs.state_block.mole_frac_comp[toluene]*exp(((fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,toluene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,toluene]*1)/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1)) + (fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene])/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))*(fs.properties.tau[toluene,benzene] - (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,benzene]*1 + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,benzene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))) + fs.state_block.mole_frac_comp[toluene]*1/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1)*(fs.properties.tau[toluene,toluene] - (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,toluene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,toluene]*1)/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1))))*(fs.properties.pressure_critical[toluene]*exp((-7.28607*(1 - 1/fs.properties.temperature_critical[toluene]*fs.state_block.temperature_bubble) + 1.38091*(1 - 1/fs.properties.temperature_critical[toluene]*fs.state_block.temperature_bubble)**1.5 - 2.83433*(1 - 1/fs.properties.temperature_critical[toluene]*fs.state_block.temperature_bubble)**3 - 2.79168*(1 - 1/fs.properties.temperature_critical[toluene]*fs.state_block.temperature_bubble)**6)/(1 - (1 - 1/fs.properties.temperature_critical[toluene]*fs.state_block.temperature_bubble)))) - fs.state_block.pressure : 0.0 : True\n", + " eq_temperature_dew : Size=1, Index=None, Active=True\n", + " Key : Lower : Body : Upper : Active\n", + " None : 0.0 : fs.state_block.mole_frac_comp[benzene]*fs.state_block.pressure/(fs.state_block.activity_coeff_comp[benzene]*(fs.properties.pressure_critical[benzene]*exp((-6.98273*(1 - 1/fs.properties.temperature_critical[benzene]*fs.state_block.temperature_dew) + 1.33213*(1 - 1/fs.properties.temperature_critical[benzene]*fs.state_block.temperature_dew)**1.5 - 2.62863*(1 - 1/fs.properties.temperature_critical[benzene]*fs.state_block.temperature_dew)**3 - 3.33399*(1 - 1/fs.properties.temperature_critical[benzene]*fs.state_block.temperature_dew)**6)/(1 - (1 - 1/fs.properties.temperature_critical[benzene]*fs.state_block.temperature_dew))))) + fs.state_block.mole_frac_comp[toluene]*fs.state_block.pressure/(fs.state_block.activity_coeff_comp[toluene]*(fs.properties.pressure_critical[toluene]*exp((-7.28607*(1 - 1/fs.properties.temperature_critical[toluene]*fs.state_block.temperature_dew) + 1.38091*(1 - 1/fs.properties.temperature_critical[toluene]*fs.state_block.temperature_dew)**1.5 - 2.83433*(1 - 1/fs.properties.temperature_critical[toluene]*fs.state_block.temperature_dew)**3 - 2.79168*(1 - 1/fs.properties.temperature_critical[toluene]*fs.state_block.temperature_dew)**6)/(1 - (1 - 1/fs.properties.temperature_critical[toluene]*fs.state_block.temperature_dew))))) - 1 : 0.0 : True\n", + " eq_total : Size=1, Index=None, Active=True\n", + " Key : Lower : Body : Upper : Active\n", + " None : 0.0 : fs.state_block.flow_mol_phase[Liq] + fs.state_block.flow_mol_phase[Vap] - fs.state_block.flow_mol : 0.0 : True\n", + "\n", + " 42 Declarations: flow_mol mole_frac_comp pressure temperature flow_mol_phase mole_frac_phase_comp Gij_coeff activity_coeff_comp A B eq_Gij_coeff eq_A eq_B eq_activity_coeff eq_total eq_comp eq_sum_mol_frac _temperature_equilibrium _t1 eps_1 eps_2 _t1_constraint temperature_bubble _p_sat_bubbleT eq_temperature_bubble Gij_coeff_bubble A_bubble B_bubble activity_coeff_comp_bubble _teq_constraint temperature_dew _p_sat_dewT eq_temperature_dew Gij_coeff_dew A_dew B_dew activity_coeff_comp_dew eq_phase_equilibrium fug_phase_comp pressure_sat_comp _reduced_temp eq_P_vap\n", + "\n", + " 3 Declarations: _time properties state_block\n", + "\n", + "1 Declarations: fs\n" + ] + } + ], + "source": [ + "m.pprint()" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.3896822835079589\n" + ] + } + ], + "source": [ + "print(pyo.value(m.fs.state_block.mole_frac_phase_comp[\"Liq\", \"benzene\"]))" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -359,7 +738,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "metadata": { "tags": [ "exercise" @@ -372,7 +751,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "metadata": { "tags": [ "solution" @@ -403,11 +782,400 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "metadata": { "tags": [] }, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
temperatureliq_benzenevap_benzene
0365.5000000.4809530.692110
1365.6176470.4624440.667699
2365.7352940.4779840.692441
3365.8529410.4405470.640336
4365.9705880.4274210.623328
5366.0882350.4427250.647796
6366.2058820.4343740.637691
7366.3235290.4446420.654933
8366.4411760.4271320.631229
9366.5588240.4463010.661743
10366.6764710.4380040.651591
11366.7941180.4253200.634814
12366.9117650.4394350.658047
13367.0294120.4356550.654539
14367.1470590.4013500.604987
15367.2647060.3978620.601703
16367.3823530.4158210.630930
17367.5000000.4206670.640380
18367.6176470.3916830.598214
19367.7352940.4049030.620432
20367.8529410.4095630.629626
21367.9705880.3894880.600722
22368.0000000.3967890.612483
23368.0882350.3981620.616106
24368.2058820.3623400.562505
25368.3235290.3869580.602680
26368.4411760.3636430.568210
27368.5588240.3681180.577072
28368.6764710.3840980.604078
29368.7941180.3536050.557925
30368.9117650.3464740.548445
31369.0294120.3507410.556996
32369.1470590.3623470.577286
33369.2647060.3625780.579519
34369.3823530.3407650.546411
35369.5000000.3374620.542857
36369.6176470.3557290.574083
37369.7352940.3486790.564513
38369.8529410.3381870.549284
39369.9705880.3243600.528514
40370.0882350.3107530.507964
41370.2058820.3110370.510055
42370.3235290.3112630.512055
43370.4411760.3080810.508437
44370.5588240.3082240.510293
45370.6764710.3181480.528399
46370.7941180.3083340.513728
47370.9117650.3179370.531410
48371.0294120.2891490.484824
49371.1470590.2986370.502318
\n", + "
" + ], + "text/plain": [ + " temperature liq_benzene vap_benzene\n", + "0 365.500000 0.480953 0.692110\n", + "1 365.617647 0.462444 0.667699\n", + "2 365.735294 0.477984 0.692441\n", + "3 365.852941 0.440547 0.640336\n", + "4 365.970588 0.427421 0.623328\n", + "5 366.088235 0.442725 0.647796\n", + "6 366.205882 0.434374 0.637691\n", + "7 366.323529 0.444642 0.654933\n", + "8 366.441176 0.427132 0.631229\n", + "9 366.558824 0.446301 0.661743\n", + "10 366.676471 0.438004 0.651591\n", + "11 366.794118 0.425320 0.634814\n", + "12 366.911765 0.439435 0.658047\n", + "13 367.029412 0.435655 0.654539\n", + "14 367.147059 0.401350 0.604987\n", + "15 367.264706 0.397862 0.601703\n", + "16 367.382353 0.415821 0.630930\n", + "17 367.500000 0.420667 0.640380\n", + "18 367.617647 0.391683 0.598214\n", + "19 367.735294 0.404903 0.620432\n", + "20 367.852941 0.409563 0.629626\n", + "21 367.970588 0.389488 0.600722\n", + "22 368.000000 0.396789 0.612483\n", + "23 368.088235 0.398162 0.616106\n", + "24 368.205882 0.362340 0.562505\n", + "25 368.323529 0.386958 0.602680\n", + "26 368.441176 0.363643 0.568210\n", + "27 368.558824 0.368118 0.577072\n", + "28 368.676471 0.384098 0.604078\n", + "29 368.794118 0.353605 0.557925\n", + "30 368.911765 0.346474 0.548445\n", + "31 369.029412 0.350741 0.556996\n", + "32 369.147059 0.362347 0.577286\n", + "33 369.264706 0.362578 0.579519\n", + "34 369.382353 0.340765 0.546411\n", + "35 369.500000 0.337462 0.542857\n", + "36 369.617647 0.355729 0.574083\n", + "37 369.735294 0.348679 0.564513\n", + "38 369.852941 0.338187 0.549284\n", + "39 369.970588 0.324360 0.528514\n", + "40 370.088235 0.310753 0.507964\n", + "41 370.205882 0.311037 0.510055\n", + "42 370.323529 0.311263 0.512055\n", + "43 370.441176 0.308081 0.508437\n", + "44 370.558824 0.308224 0.510293\n", + "45 370.676471 0.318148 0.528399\n", + "46 370.794118 0.308334 0.513728\n", + "47 370.911765 0.317937 0.531410\n", + "48 371.029412 0.289149 0.484824\n", + "49 371.147059 0.298637 0.502318" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "# Load data from csv\n", "data = pd.read_csv(\"BT_NRTL_dataset.csv\")\n", @@ -430,7 +1198,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "metadata": { "tags": [ "exercise" @@ -449,7 +1217,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "metadata": { "tags": [ "solution" @@ -472,6 +1240,98 @@ " return expr * 1e4" ] }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": {}, + "outputs": [], + "source": [ + "# Build an experiment class to take advantage of new parmest interface\n", + "from pyomo.contrib.parmest.experiment import Experiment\n", + "\n", + "\n", + "class NRTLExperiment(Experiment):\n", + " \"\"\"Experiment class for parameter estimation of NRTL model using parmest\"\"\"\n", + "\n", + " def __init__(self, data, meas_error=None):\n", + " \"\"\"Initialize the NRTLExperiment class\n", + "\n", + " Args:\n", + " data: DataFrame containing the experimental data\n", + " meas_error: Measurement error for the data (optional)\n", + " \"\"\"\n", + " self.model = None\n", + " self.data = data\n", + " self.meas_error = meas_error\n", + "\n", + " def create_model(self):\n", + " \"\"\"Create the Pyomo model for the NRTL parameter estimation problem\"\"\"\n", + " self.model = NRTL_model(self.data)\n", + "\n", + " # # Add objective scaling to help with convergence\n", + " # self.model.obj_scaling_factor = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + " # self.model.obj_scaling_factor.update(\n", + " # [(self.model.obj, 1e4)]\n", + " # ) # Scale the objective by 1e4 to help with convergence\n", + "\n", + " def label_model(self):\n", + " import pyomo.environ as pyo\n", + " import pandas as pd\n", + "\n", + " m = self.model\n", + "\n", + " # Extract the first row of data to label the model\n", + " if isinstance(self.data, pd.DataFrame):\n", + " row = self.data.iloc[0]\n", + " else:\n", + " row = self.data\n", + "\n", + " # Parmest expects the first index of experiment outputs to be the data point\n", + " m.data_point = pyo.Set(initialize=[0])\n", + "\n", + " # Wrap IDAES variables in Expressions indexed by data point\n", + " m.liq_benzene_out = pyo.Expression(\n", + " m.data_point,\n", + " rule=lambda m, i: m.fs.state_block.mole_frac_phase_comp[\"Liq\", \"benzene\"],\n", + " )\n", + "\n", + " m.vap_benzene_out = pyo.Expression(\n", + " m.data_point,\n", + " rule=lambda m, i: m.fs.state_block.mole_frac_phase_comp[\"Vap\", \"benzene\"],\n", + " )\n", + "\n", + " m.experiment_outputs = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + "\n", + " m.experiment_outputs[m.liq_benzene_out[0]] = float(row[\"liq_benzene\"])\n", + " m.experiment_outputs[m.vap_benzene_out[0]] = float(row[\"vap_benzene\"])\n", + "\n", + "\n", + " m.measurement_error = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + " m.measurement_error.update(\n", + " [\n", + " (m.liq_benzene_out[0], self.meas_error),\n", + " (m.vap_benzene_out[0], self.meas_error),\n", + " ]\n", + " )\n", + "\n", + " # Add unknown parameters to the model for easier access\n", + " m.unknown_parameters = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + " m.unknown_parameters.update(\n", + " (k, pyo.value(k))\n", + " for k in [\n", + " m.fs.properties.tau[\"benzene\", \"toluene\"],\n", + " m.fs.properties.tau[\"toluene\", \"benzene\"],\n", + " ]\n", + " )\n", + "\n", + " def get_labeled_model(self):\n", + " \"\"\"Return the labeled model\"\"\"\n", + " if self.model is None:\n", + " self.create_model()\n", + " self.label_model()\n", + " return self.model" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -491,9 +1351,88 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 49, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3746\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2200\n", + "\n", + "Total number of variables............................: 1100\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 300\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1098\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 6.0671019e+01 3.15e+00 4.84e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 5.2961050e+00 1.76e+03 5.05e+00 -1.0 1.37e+04 - 9.74e-01 1.00e+00f 1\n", + " 2 5.2586169e+00 4.01e+02 1.09e+00 -1.0 5.15e+02 - 1.00e+00 1.00e+00h 1\n", + " 3 5.1450958e+00 7.04e+01 2.27e-01 -1.0 4.11e+01 - 1.00e+00 1.00e+00h 1\n", + " 4 5.0748980e+00 1.25e+02 2.08e-01 -1.7 5.74e+02 - 1.00e+00 1.00e+00h 1\n", + " 5 5.0775194e+00 7.87e+00 1.92e-01 -1.7 8.44e+01 - 1.00e+00 1.00e+00h 1\n", + " 6 5.0726692e+00 1.37e+01 1.90e-01 -2.5 1.38e+02 - 1.00e+00 1.00e+00h 1\n", + " 7 5.0750377e+00 2.85e+00 2.60e-02 -2.5 6.99e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 5.0749670e+00 7.36e-02 2.81e-03 -3.8 9.72e+00 - 1.00e+00 1.00e+00h 1\n", + " 9 5.0749687e+00 4.51e-04 4.80e-06 -3.8 1.01e+00 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 5.0749686e+00 2.91e-04 1.36e-06 -5.7 5.81e-01 - 1.00e+00 1.00e+00h 1\n", + " 11 5.0749686e+00 4.78e-08 2.18e-10 -8.6 7.65e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 11\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 5.0749685783046257e+00 5.0749685783046257e+00\n", + "Dual infeasibility......: 2.1827323102666636e-10 2.1827323102666636e-10\n", + "Constraint violation....: 1.6625508263665860e-10 4.7832145355641842e-08\n", + "Complementarity.........: 2.5076274461670377e-09 2.5076274461670377e-09\n", + "Overall NLP error.......: 2.5076274461670377e-09 4.7832145355641842e-08\n", + "\n", + "\n", + "Number of objective function evaluations = 12\n", + "Number of objective gradient evaluations = 12\n", + "Number of equality constraint evaluations = 12\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 12\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 11\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.012\n", + "Total CPU secs in NLP function evaluations = 0.004\n", + "\n", + "EXIT: Optimal Solution Found.\n" + ] + } + ], "source": [ "import logging\n", "\n", @@ -507,7 +1446,124 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 45, + "metadata": {}, + "outputs": [], + "source": [ + "# Update to new interface\n", + "exp_list = []\n", + "for i in range(data.shape[0]):\n", + " exp_list.append(NRTLExperiment(data.iloc[i]))" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3750\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2200\n", + "\n", + "Total number of variables............................: 1102\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 300\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1100\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 6.0671019e-03 3.15e+00 1.97e-05 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 8.6249856e-04 1.40e+03 2.15e-01 -1.0 1.37e+04 - 9.95e-01 1.00e+00h 1\n", + " 2 1.1627234e-03 9.11e+03 8.21e-01 -1.7 4.74e+02 - 8.66e-01 1.00e+00h 1\n", + " 3 1.0978149e-03 9.02e+03 7.99e-01 -1.7 5.89e+00 -4.0 5.44e-01 2.64e-02h 6\n", + " 4 8.5702670e-04 8.63e+02 3.17e-02 -1.7 6.93e-01 -2.7 1.00e+00 1.00e+00h 1\n", + " 5 1.3332724e-03 3.57e+03 7.92e-03 -1.7 7.75e-01 - 1.00e+00 1.00e+00h 1\n", + " 6 1.5692588e-03 1.64e+02 2.34e-04 -1.7 1.98e-01 - 1.00e+00 1.00e+00h 1\n", + " 7 1.5828905e-03 1.20e+01 1.13e-05 -1.7 4.29e-02 - 1.00e+00 1.00e+00h 1\n", + " 8 1.4366151e-03 9.18e-01 2.34e-04 -2.5 5.49e-02 - 1.00e+00 1.00e+00h 1\n", + " 9 8.9194043e-04 2.19e+01 2.00e-04 -3.8 2.51e-01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 5.9835646e-04 3.72e+01 2.34e-05 -3.8 3.13e-01 - 1.00e+00 1.00e+00h 1\n", + " 11 5.9839648e-04 1.26e+00 4.06e-08 -3.8 2.87e-02 - 1.00e+00 1.00e+00h 1\n", + " 12 5.9838953e-04 4.33e-05 1.60e-12 -3.8 9.40e-05 - 1.00e+00 1.00e+00h 1\n", + " 13 5.9077073e-04 1.21e+01 2.96e-06 -5.7 4.79e-02 - 1.00e+00 1.00e+00h 1\n", + " 14 5.9066394e-04 1.19e-03 4.25e-07 -5.7 5.98e-04 -3.1 1.00e+00 1.00e+00h 1\n", + " 15 5.9059984e-04 1.08e-02 2.96e-07 -8.6 1.25e-03 -3.6 1.00e+00 1.00e+00h 1\n", + " 16 5.9042438e-04 9.67e-02 2.92e-07 -8.6 3.70e-03 -4.1 1.00e+00 1.00e+00h 1\n", + " 17 5.8992758e-04 8.72e-01 2.91e-07 -8.6 1.11e-02 -4.6 1.00e+00 1.00e+00h 1\n", + " 18 5.8840706e-04 8.23e+00 3.09e-07 -8.6 3.40e-02 -5.1 1.00e+00 1.00e+00h 1\n", + " 19 5.8319289e-04 9.25e+01 1.97e-06 -8.6 1.15e-01 -5.5 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 5.4836946e-04 3.88e+03 1.22e-04 -8.6 7.95e-01 -6.0 1.00e+00 1.00e+00h 1\n", + " 21 5.0847689e-04 4.45e+02 1.04e-04 -8.6 3.55e-01 -5.6 1.00e+00 1.00e+00h 1\n", + " 22 5.0727291e-04 4.20e+00 1.54e-05 -8.6 6.20e+02 - 1.00e+00 1.00e+00h 1\n", + " 23 5.0749772e-04 1.36e+00 1.44e-06 -8.6 5.13e+01 - 1.00e+00 1.00e+00h 1\n", + " 24 5.0749686e-04 6.93e-06 4.21e-11 -8.6 3.55e-01 - 1.00e+00 1.00e+00h 1\n", + " 25 5.0749686e-04 3.36e-06 1.49e-12 -9.0 6.25e-02 - 1.00e+00 1.00e+00h 1\n", + " 26 5.0749686e-04 1.02e-10 2.36e-18 -9.0 5.08e-06 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 26\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 5.0749685787934424e-04 5.0749685787934424e-04\n", + "Dual infeasibility......: 2.3583858113882067e-18 2.3583858113882067e-18\n", + "Constraint violation....: 3.5405706676501683e-13 1.0186340659856796e-10\n", + "Complementarity.........: 9.0909090909091344e-10 9.0909090909091344e-10\n", + "Overall NLP error.......: 9.0909090909091344e-10 9.0909090909091344e-10\n", + "\n", + "\n", + "Number of objective function evaluations = 33\n", + "Number of objective gradient evaluations = 27\n", + "Number of equality constraint evaluations = 34\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 27\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 26\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.034\n", + "Total CPU secs in NLP function evaluations = 0.009\n", + "\n", + "EXIT: Optimal Solution Found.\n" + ] + } + ], + "source": [ + "pest_new = parmest.Estimator(exp_list, obj_function=\"SSE\", tee=True)\n", + "obj_value_new, parameters_new = pest_new.theta_est()" + ] + }, + { + "cell_type": "code", + "execution_count": 16, "metadata": { "tags": [ "testing" @@ -530,9 +1586,21 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 50, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The SSE at the optimal solution is 0.000507\n", + "\n", + "The values for the parameters are as follows:\n", + "fs.properties.tau[benzene,toluene] = -0.8987624036283817\n", + "fs.properties.tau[toluene,benzene] = 1.4104861099366175\n" + ] + } + ], "source": [ "print(\"The SSE at the optimal solution is %0.6f\" % (obj_value * 1e-4))\n", "print()\n", @@ -541,6 +1609,31 @@ " print(k, \"=\", v)" ] }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The SSE at the optimal solution is 0.000000\n", + "\n", + "The values for the parameters are as follows:\n", + "fs.properties.tau[benzene,toluene] = -0.8987550041842163\n", + "fs.properties.tau[toluene,benzene] = 1.4104702103547941\n" + ] + } + ], + "source": [ + "print(\"The SSE at the optimal solution is %0.6f\" % (obj_value_new * 1e-4))\n", + "print()\n", + "print(\"The values for the parameters are as follows:\")\n", + "for k, v in parameters_new.items():\n", + " print(k, \"=\", v)" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -567,7 +1660,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 18, "metadata": {}, "outputs": [], "source": [ @@ -583,7 +1676,7 @@ "metadata": { "celltoolbar": "Tags", "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "idaes-examples-dev-py313-macmini", "language": "python", "name": "python3" }, @@ -597,7 +1690,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.19" + "version": "3.13.13" } }, "nbformat": 4, diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb index 304c2f87..606face9 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb @@ -1063,178 +1063,11 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "pest_new = parmest.Estimator(exp_list, obj_function=\"SSE\", tee=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 10950\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 6600\n", - "\n", - "Total number of variables............................: 2952\n", - " variables with only lower bounds: 150\n", - " variables with lower and upper bounds: 600\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 2950\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 6.0671019e-03 5.63e+02 1.20e-08 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 9.0714942e-04 1.37e+03 1.61e+01 -1.0 1.37e+04 - 9.82e-01 1.00e+00h 1\n", - " 2 1.3219937e-03 1.17e+04 1.62e+01 -1.0 5.23e+03 - 3.41e-01 1.65e-01h 3\n", - " 3 1.3161671e-03 1.11e+04 4.02e+01 -1.0 3.96e+02 -4.0 8.19e-01 1.25e-01h 4\n", - " 4 1.3154170e-03 1.11e+04 4.32e+01 -1.0 3.47e+02 -4.5 9.90e-01 4.43e-02h 5\n", - " 5 9.4424343e-04 1.04e+04 4.05e+01 -1.0 1.16e+04 - 9.33e-01 5.61e-02h 5\n", - " 6 9.4571258e-04 1.11e+04 4.85e+01 -1.0 3.13e+02 -5.0 8.74e-01 1.25e-01h 4\n", - " 7 9.4862862e-04 1.11e+04 4.84e+01 -1.0 2.41e+03 -5.4 1.72e-01 1.50e-03h 8\n", - " 8 9.5448936e-04 1.10e+04 4.81e+01 -1.0 4.11e+02 -5.0 1.00e+00 1.97e-02h 6\n", - " 9 9.5650047e-04 1.10e+04 4.81e+01 -1.0 5.14e+02 -4.6 3.46e-01 5.24e-03h 7\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 9.5730419e-04 1.10e+04 4.81e+01 -1.0 9.78e+02 -4.2 4.40e-01 1.08e-03h 8\n", - " 11 9.5774182e-04 1.10e+04 4.84e+01 -1.0 2.76e+02 -3.7 2.91e-01 2.99e-03h 7\n", - " 12 9.4292855e-04 7.77e+04 4.09e+04 -1.0 5.38e+02 -2.4 5.48e-02 6.44e-02w 1\n", - " 13 2.4318219e-01 2.38e+07 4.22e+14 -1.0 1.28e+06 - 2.55e-02 3.49e-02w 1\n", - " 14 2.8902019e-01 1.64e+07 2.92e+14 -1.0 1.11e+05 -2.9 9.54e-01 3.01e-01w 1\n", - " 15 9.5768293e-04 1.10e+04 4.85e+01 -1.0 2.80e+05 -3.4 5.48e-02 2.52e-04h 8\n", - " 16 9.5769345e-04 1.10e+04 4.85e+01 -1.0 4.33e+02 -2.9 7.95e-02 1.91e-04h 9\n", - " 17 9.5763809e-04 1.10e+04 4.85e+01 -1.0 6.35e+02 -2.5 4.94e-02 2.08e-04h 9\n", - " 18 9.5734836e-04 1.10e+04 4.87e+01 -1.0 3.22e+02 -3.0 1.00e+00 1.22e-03h 8\n", - " 19 9.3628114e-04 1.09e+04 4.62e+01 -1.0 4.22e+02 -3.5 5.16e-01 5.87e-02h 5\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 7.1894543e-04 4.02e+03 4.95e+02 -1.0 3.49e+02 -3.9 1.00e+00 1.00e+00h 1\n", - " 21 6.7062834e-04 1.58e+02 2.21e+02 -1.0 1.78e+02 -4.4 1.00e+00 1.00e+00h 1\n", - " 22 6.6635123e-04 4.17e+01 1.12e+01 -1.0 2.44e+02 -4.9 1.00e+00 1.00e+00h 1\n", - " 23 6.6729070e-04 1.43e+00 9.69e-01 -1.0 1.08e+01 -5.4 1.00e+00 1.00e+00h 1\n", - " 24 6.6785681e-04 3.58e-01 5.25e-03 -1.7 6.65e+00 -5.8 1.00e+00 1.00e+00h 1\n", - " 25 6.2552355e-04 9.80e+02 6.48e-02 -3.8 7.92e+02 - 9.22e-01 1.00e+00h 1\n", - " 26 5.9105707e-04 8.13e+00 6.13e-04 -3.8 5.66e+02 - 1.00e+00 1.00e+00h 1\n", - " 27 6.1313801e-04 6.24e+01 8.08e-06 -3.8 1.70e+02 - 1.00e+00 1.00e+00h 1\n", - " 28 6.1208051e-04 3.58e-01 1.18e-08 -3.8 1.88e+00 - 1.00e+00 1.00e+00h 1\n", - " 29 5.9010560e-04 1.58e+01 1.00e-05 -5.7 1.08e+02 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30 5.9008319e-04 2.74e-02 7.90e-07 -5.7 7.54e-02 -6.3 1.00e+00 1.00e+00h 1\n", - " 31 5.3570104e-04 1.48e+04 8.70e-04 -5.7 1.81e+02 - 1.00e+00 1.00e+00h 1\n", - " 32 5.1618763e-04 6.29e+02 8.06e-05 -5.7 2.55e+02 - 1.00e+00 1.00e+00h 1\n", - " 33 5.5250565e-04 2.88e+01 2.58e-04 -5.7 1.81e+04 - 6.26e-01 6.25e-02h 5\n", - " 34 5.2209909e-04 2.88e+02 2.02e-04 -5.7 1.89e+03 - 1.00e+00 1.00e+00h 1\n", - " 35 5.0707798e-04 5.60e+01 2.02e-04 -5.7 2.93e+03 - 1.00e+00 1.00e+00h 1\n", - " 36 5.0765648e-04 7.87e+00 1.91e-05 -5.7 1.02e+02 - 1.00e+00 1.00e+00h 1\n", - " 37 5.0740606e-04 2.57e+00 1.88e-05 -5.7 6.96e+01 - 1.00e+00 1.00e+00h 1\n", - " 38 5.0764164e-04 2.55e+00 1.76e-05 -5.7 6.81e+01 - 1.00e+00 1.00e+00h 1\n", - " 39 5.0740672e-04 2.55e+00 1.88e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 40 5.0764162e-04 2.54e+00 1.76e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", - " 41 5.0740672e-04 2.55e+00 1.88e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", - " 42 5.0782847e-04 1.43e-01 1.83e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00H 1\n", - " 43 5.0751252e-04 1.58e-02 1.93e-05 -5.7 6.88e+01 - 1.00e+00 1.00e+00H 1\n", - " 44 5.0783218e-04 4.79e-03 1.85e-05 -5.7 6.92e+01 - 1.00e+00 1.00e+00H 1\n", - " 45 5.0751252e-04 1.60e-02 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", - " 46 5.0783222e-04 1.23e-04 1.85e-05 -5.7 6.92e+01 - 1.00e+00 1.00e+00H 1\n", - " 47 5.0751252e-04 1.60e-02 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", - " 48 5.0783216e-04 1.24e-04 1.85e-05 -5.7 6.92e+01 - 1.00e+00 1.00e+00H 1\n", - " 49 5.0751765e-04 3.20e-03 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 50 5.0764151e-04 2.56e+00 1.77e-05 -5.7 6.93e+01 - 1.00e+00 1.00e+00h 1\n", - " 51 5.0740671e-04 2.55e+00 1.88e-05 -5.7 6.81e+01 - 1.00e+00 1.00e+00h 1\n", - " 52 5.0764162e-04 2.54e+00 1.76e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", - " 53 5.0740672e-04 2.55e+00 1.88e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", - " 54 5.0764162e-04 2.54e+00 1.76e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", - " 55 5.0748886e-04 1.91e+00 8.64e-06 -5.7 6.80e+01 - 1.00e+00 5.00e-01h 2\n", - " 56 5.0744550e-04 3.37e-01 1.64e-05 -5.7 2.54e+01 - 1.00e+00 1.00e+00h 1\n", - " 57 5.0763613e-04 1.82e+00 1.43e-05 -5.7 5.79e+01 - 1.00e+00 1.00e+00h 1\n", - " 58 5.0751252e-04 2.25e-02 1.93e-05 -5.7 6.65e+01 - 1.00e+00 1.00e+00H 1\n", - " 59 5.0783220e-04 1.23e-04 1.85e-05 -5.7 6.92e+01 - 1.00e+00 1.00e+00H 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 60 5.0751252e-04 1.60e-02 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", - " 61 5.0783207e-04 3.26e-04 1.85e-05 -5.7 6.92e+01 - 1.00e+00 1.00e+00H 1\n", - " 62 5.0751786e-04 7.95e-05 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", - " 63 5.0754291e-04 6.40e-01 8.69e-06 -5.7 6.93e+01 - 1.00e+00 5.00e-01h 2\n", - " 64 5.0745167e-04 3.00e-01 1.61e-05 -5.7 2.35e+01 - 1.00e+00 1.00e+00h 1\n", - " 65 5.0763437e-04 1.71e+00 1.33e-05 -5.7 5.61e+01 - 1.00e+00 1.00e+00h 1\n", - " 66 5.0751762e-04 2.91e-03 1.93e-05 -5.7 6.60e+01 - 1.00e+00 1.00e+00H 1\n", - " 67 5.0752104e-04 1.62e-01 1.43e-05 -5.7 6.92e+01 - 1.00e+00 2.50e-01h 3\n", - " 68 5.0761295e-04 1.03e+00 2.18e-05 -5.7 4.35e+01 - 1.00e+00 1.00e+00h 1\n", - " 69 5.0751251e-04 2.38e-02 1.92e-05 -5.7 5.95e+01 - 1.00e+00 1.00e+00H 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 70 5.0783210e-04 3.29e-06 1.85e-05 -5.7 6.90e+01 - 1.00e+00 1.00e+00H 1\n", - " 71 5.0751786e-04 7.94e-05 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", - " 72 5.0754292e-04 6.40e-01 8.69e-06 -5.7 6.93e+01 - 1.00e+00 5.00e-01h 2\n", - " 73 5.0749299e-04 3.95e-01 1.21e-05 -5.7 2.35e+01 - 1.00e+00 5.00e-01h 2\n", - " 74 5.0755524e-04 1.36e-01 3.09e-05 -5.7 1.57e+01 - 1.00e+00 1.00e+00h 1\n", - " 75 5.0751308e-04 1.96e-02 1.80e-05 -5.7 3.30e+01 - 1.00e+00 1.00e+00H 1\n", - " 76 5.0754492e-04 5.62e-01 8.19e-06 -5.7 6.42e+01 - 1.00e+00 5.00e-01h 2\n", - " 77 5.0748301e-04 3.98e-01 1.25e-05 -5.7 2.93e+01 - 1.00e+00 5.00e-01h 2\n", - " 78 5.0756455e-04 2.42e-01 3.07e-05 -5.7 2.09e+01 - 1.00e+00 1.00e+00h 1\n", - " 79 5.0751710e-04 1.38e-03 1.87e-05 -5.7 3.98e+01 - 1.00e+00 1.00e+00H 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 80 5.0783077e-04 3.26e-06 1.84e-05 -5.7 6.70e+01 - 1.00e+00 1.00e+00H 1\n", - " 81 5.0726420e-04 1.24e+01 1.85e-05 -8.6 1.34e+02 - 9.93e-01 1.00e+00h 1\n", - " 82 5.0749897e-04 2.75e+00 2.53e-06 -8.6 6.93e+01 - 1.00e+00 1.00e+00h 1\n", - " 83 5.0749686e-04 3.64e-04 6.40e-10 -8.6 4.69e-02 - 1.00e+00 1.00e+00h 1\n", - " 84 5.0749686e-04 7.28e-11 2.51e-14 -8.6 6.86e-05 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 84\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 5.0749685809243843e-04 5.0749685809243843e-04\n", - "Dual infeasibility......: 2.5059195074646584e-14 2.5059195074646584e-14\n", - "Constraint violation....: 1.4104644499482425e-11 7.2759576141834259e-11\n", - "Complementarity.........: 2.5059035596800647e-09 2.5059035596800647e-09\n", - "Overall NLP error.......: 2.5059035596800647e-09 2.5059035596800647e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 260\n", - "Number of objective gradient evaluations = 85\n", - "Number of equality constraint evaluations = 260\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 85\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 84\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.333\n", - "Total CPU secs in NLP function evaluations = 0.095\n", - "\n", - "EXIT: Optimal Solution Found.\n" - ] - } - ], - "source": [ + "pest_new = parmest.Estimator(exp_list, obj_function=\"SSE\", tee=True)\n", "obj_value_new, parameters_new = pest_new.theta_est()" ] }, diff --git a/idaes_examples/notebooks/docs/properties/parameter_estimation_pr.ipynb b/idaes_examples/notebooks/docs/properties/parameter_estimation_pr.ipynb index 1d0fcf3e..64d6b2d1 100644 --- a/idaes_examples/notebooks/docs/properties/parameter_estimation_pr.ipynb +++ b/idaes_examples/notebooks/docs/properties/parameter_estimation_pr.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "metadata": { "tags": [ "header", @@ -57,12 +57,12 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "# Import objects from pyomo package\n", - "from pyomo.environ import ConcreteModel, SolverFactory, units as pyunits\n", + "from pyomo.environ import ConcreteModel, SolverFactory, value, Var, Suffix \n", "\n", "# Import the main FlowsheetBlock from IDAES. The flowsheet block will contain the unit model\n", "from idaes.core import FlowsheetBlock\n", @@ -83,7 +83,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": {}, "outputs": [], "source": [ @@ -99,7 +99,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ @@ -121,7 +121,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "metadata": {}, "outputs": [], "source": [ @@ -146,7 +146,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "metadata": {}, "outputs": [], "source": [ @@ -229,9 +229,23 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2026-06-10 22:12:38 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-10 22:12:39 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:12:39 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-10 22:12:39 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-10 22:12:39 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:12:39 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:12:39 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n" + ] + } + ], "source": [ "from idaes.core.util.model_statistics import degrees_of_freedom\n", "import pytest\n", @@ -262,7 +276,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "metadata": {}, "outputs": [], "source": [ @@ -272,6 +286,73 @@ "]" ] }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "from pyomo.contrib.parmest.experiment import Experiment\n", + "# Create experiment class for parameter estimation\n", + "class PRExperiment(Experiment):\n", + "\n", + " def __init__(self, data, meas_error=None):\n", + " \"\"\"Initialize the PR Experiment class\n", + "\n", + " Args:\n", + " data: DataFrame containing the experimental data\n", + " meas_error: Measurement error for the data (optional)\n", + " \"\"\"\n", + " self.model = None\n", + " self.data = data\n", + " self.meas_error = meas_error\n", + "\n", + " def create_model(self):\n", + " \"\"\"Create the Pyomo model for the PR parameter estimation problem\"\"\"\n", + " self.model = PR_model(self.data)\n", + "\n", + " def label_model(self):\n", + " m = self.model\n", + "\n", + " # Add Suffixes to label the outputs, parameters, and measurement error in the model\n", + " m.experiment_outputs = Suffix(direction=Suffix.LOCAL)\n", + " m.experiment_outputs.update(\n", + " [\n", + " (\n", + " m.fs.state_block[1].pressure,\n", + " self.data[\"pressure\"],\n", + " ),\n", + " ]\n", + " )\n", + "\n", + " m.measurement_error = Suffix(direction=Suffix.LOCAL)\n", + " m.measurement_error.update(\n", + " [\n", + " (m.fs.state_block[1].pressure, self.meas_error),\n", + " ]\n", + " )\n", + "\n", + " # Add unknown parameters to the model for easier access\n", + " m.unknown_parameters = Suffix(direction=Suffix.LOCAL)\n", + " m.unknown_parameters.update(\n", + " (k, value(k))\n", + " for k in [\n", + " m.fs.properties.PR_kappa['bmimPF6', 'carbon_dioxide'],\n", + " m.fs.properties.PR_kappa['carbon_dioxide', 'bmimPF6'],\n", + " ]\n", + " )\n", + "\n", + " def get_labeled_model(self):\n", + " \"\"\"Return the labeled model\"\"\"\n", + " if self.model is None:\n", + " self.create_model()\n", + " self.label_model()\n", + " return self.model\n", + "\n", + "\n", + "\n" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -283,7 +364,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "metadata": {}, "outputs": [], "source": [ @@ -303,15 +384,449 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 16, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "WARNING: DEPRECATED: You're using the deprecated parmest interface\n", + "(model_function, data, theta_names). This interface will be removed in a\n", + "future release, please update to the new parmest interface using experiment\n", + "lists. (deprecated in 6.7.2) (called from /Applications/anaconda3/envs/idaes-\n", + "examples-dev-py313-macmini/lib/python3.13/functools.py:974)\n", + "2026-06-10 22:13:45 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-10 22:13:45 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:45 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-10 22:13:45 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-10 22:13:45 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:45 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:45 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:45 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:49 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:49 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:49 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-10 22:13:49 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:49 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-10 22:13:49 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-10 22:13:49 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:49 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:49 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 842\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 720\n", + "\n", + "Total number of variables............................: 360\n", + " variables with only lower bounds: 72\n", + " variables with lower and upper bounds: 270\n", + " variables with only upper bounds: 18\n", + "Total number of equality constraints.................: 358\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 5.00e-01 3.80e-14 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 1.1422489e+01 2.60e-01 2.37e+03 -1.0 3.35e+04 - 3.39e-01 6.89e-01h 1\n", + " 2 2.8781463e+01 1.27e-01 1.10e+03 -1.0 1.36e+04 - 8.22e-02 9.90e-01h 1\n", + " 3 2.9814423e+01 1.87e-01 6.44e+02 -1.0 4.87e+02 - 8.73e-01 9.90e-01h 1\n", + " 4 2.9709661e+01 4.26e-02 1.57e+03 -1.0 5.50e+02 - 9.85e-01 9.90e-01h 1\n", + " 5 2.9285199e+01 7.98e-03 9.52e+04 -1.0 2.77e+03 - 9.87e-01 1.00e+00h 1\n", + " 6 2.9283590e+01 1.42e-04 9.49e+04 -1.0 3.48e+02 - 9.90e-01 1.00e+00h 1\n", + " 7 2.9283603e+01 7.45e-08 9.06e+02 -1.0 5.94e-01 - 9.90e-01 1.00e+00h 1\n", + " 8 2.9282891e+01 3.35e-07 1.47e+04 -2.5 1.24e+02 - 9.98e-01 1.00e+00f 1\n", + " 9 2.9282892e+01 1.72e-12 4.97e-08 -2.5 2.39e-01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 2.9282891e+01 2.85e-10 3.05e+00 -8.6 3.61e+00 - 1.00e+00 1.00e+00h 1\n", + " 11 2.9282891e+01 1.26e-12 9.06e-12 -8.6 2.03e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 11\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.9282891309651692e+01 2.9282891309651692e+01\n", + "Dual infeasibility......: 9.0591404729482314e-12 9.0591404729482314e-12\n", + "Constraint violation....: 1.2554475105183152e-12 1.2554475105183152e-12\n", + "Complementarity.........: 2.5059037693871210e-09 2.5059037693871210e-09\n", + "Overall NLP error.......: 2.5059037693871210e-09 2.5059037693871210e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 12\n", + "Number of objective gradient evaluations = 12\n", + "Number of equality constraint evaluations = 12\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 12\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 11\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.006\n", + "Total CPU secs in NLP function evaluations = 0.024\n", + "\n", + "EXIT: Optimal Solution Found.\n" + ] + } + ], "source": [ "pest = parmest.Estimator(PR_model, data, variable_name, SSE, tee=True)\n", "\n", "obj_value, parameters = pest.theta_est()" ] }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "# Update to new interface\n", + "exp_list = []\n", + "for i in range(data.shape[0]):\n", + " exp_list.append(PRExperiment(data.iloc[i]))" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-10 22:13:58 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:58 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-10 22:13:58 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-10 22:13:58 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:58 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:58 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:58 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-10 22:13:58 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:58 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-10 22:13:58 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-10 22:13:58 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:58 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:58 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:58 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-10 22:13:58 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:58 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-10 22:13:58 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-10 22:13:58 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:58 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-10 22:13:58 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 846\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 720\n", + "\n", + "Total number of variables............................: 362\n", + " variables with only lower bounds: 72\n", + " variables with lower and upper bounds: 270\n", + " variables with only upper bounds: 18\n", + "Total number of equality constraints.................: 360\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 5.00e-01 2.44e-15 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 6.9602464e+06 4.12e-01 1.82e+07 -1.0 2.99e+04 - 3.39e-01 1.72e-01h 3\n", + " 2 1.6667677e+08 2.58e-01 2.70e+08 -1.0 2.58e+04 - 6.19e-01 7.79e-01h 1\n", + " 3 2.8786912e+08 1.32e-01 4.98e+07 -1.0 8.26e+03 - 8.13e-01 9.90e-01h 1\n", + " 4 2.9277551e+08 1.44e-01 5.76e+05 -1.0 3.05e+02 - 9.77e-01 9.90e-01h 1\n", + " 5 2.9282842e+08 3.31e-02 5.28e+03 -1.0 3.24e+00 - 9.90e-01 9.91e-01h 1\n", + " 6 2.9282891e+08 4.65e-03 8.12e+04 -1.0 1.08e+00 - 9.90e-01 1.00e+00h 1\n", + " 7 2.9282891e+08 3.59e-05 2.33e+04 -2.5 9.23e-02 - 9.97e-01 1.00e+00h 1\n", + " 8 2.9282891e+08 3.17e-09 2.26e-05 -3.8 8.65e-04 - 1.00e+00 1.00e+00h 1\n", + " 9 2.9282891e+08 1.29e-12 2.38e-05 -8.6 6.67e-08 - 1.00e+00 1.00e+00f 1\n", + "\n", + "Number of Iterations....: 9\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.9282891309627521e+08 2.9282891309627521e+08\n", + "Dual infeasibility......: 2.3841853781623475e-05 2.3841853781623475e-05\n", + "Constraint violation....: 1.2910152591875072e-12 1.2910152591875072e-12\n", + "Complementarity.........: 2.5062901281861244e-09 2.5062901281861244e-09\n", + "Overall NLP error.......: 2.5062901281861244e-09 2.3841853781623475e-05\n", + "\n", + "\n", + "Number of objective function evaluations = 12\n", + "Number of objective gradient evaluations = 10\n", + "Number of equality constraint evaluations = 12\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 10\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 9\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.006\n", + "Total CPU secs in NLP function evaluations = 0.020\n", + "\n", + "EXIT: Optimal Solution Found.\n" + ] + } + ], + "source": [ + "pest_new = parmest.Estimator(exp_list, obj_function=\"SSE\", tee=True)\n", + "obj_value_new, parameters_new = pest_new.theta_est()" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -323,9 +838,21 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 19, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The SSE at the optimal solution is 29.282891\n", + "\n", + "The values for the parameters are as follows:\n", + "fs.properties.PR_kappa[bmimPF6,carbon_dioxide] = -0.40714284002971035\n", + "fs.properties.PR_kappa[carbon_dioxide,bmimPF6] = 0.020593684002514167\n" + ] + } + ], "source": [ "print(\"The SSE at the optimal solution is %0.6f\" % obj_value)\n", "print()\n", @@ -334,6 +861,37 @@ " print(k, \"=\", v)" ] }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "Using new interface:\n", + "\n", + "The SSE at the optimal solution is 292828913.096275\n", + "\n", + "The values for the parameters are as follows:\n", + "fs.properties.PR_kappa[bmimPF6,carbon_dioxide] = -0.40714284008565715\n", + "fs.properties.PR_kappa[carbon_dioxide,bmimPF6] = 0.02059368400143062\n" + ] + } + ], + "source": [ + "# Repeat for new interface\n", + "print(\"\\n\\nUsing new interface:\\n\")\n", + "print(\"The SSE at the optimal solution is %0.6f\" % obj_value_new)\n", + "print()\n", + "print(\"The values for the parameters are as follows:\")\n", + "for k, v in parameters_new.items():\n", + " print(k, \"=\", v)" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -351,7 +909,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "idaes-examples-dev-py313-macmini", "language": "python", "name": "python3" }, @@ -365,7 +923,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.19" + "version": "3.13.13" } }, "nbformat": 4, From 45479c6c93fa36699bf19bf61696e2e804585ff7 Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Wed, 10 Jun 2026 22:18:07 -0400 Subject: [PATCH 05/23] Ran black --- ...er_estimation_nrtl_using_state_block.ipynb | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block.ipynb index 8a33c6a1..1111c3cb 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block.ipynb @@ -309,19 +309,19 @@ "assert degrees_of_freedom(m) == 0\n", "\n", "# Check for output values\n", - "assert pyo.value(m.fs.state_block.mole_frac_phase_comp[\"Liq\", \"benzene\"]) == pytest.approx(\n", - " 0.389, abs=1e-2\n", - ")\n", - "assert pyo.value(m.fs.state_block.mole_frac_phase_comp[\"Vap\", \"benzene\"]) == pytest.approx(\n", - " 0.610, abs=1e-2\n", - ")\n", - "\n", - "assert pyo.value(m.fs.state_block.mole_frac_phase_comp[\"Liq\", \"toluene\"]) == pytest.approx(\n", - " 0.610, abs=1e-2\n", - ")\n", - "assert pyo.value(m.fs.state_block.mole_frac_phase_comp[\"Vap\", \"toluene\"]) == pytest.approx(\n", - " 0.394, abs=1e-2\n", - ")" + "assert pyo.value(\n", + " m.fs.state_block.mole_frac_phase_comp[\"Liq\", \"benzene\"]\n", + ") == pytest.approx(0.389, abs=1e-2)\n", + "assert pyo.value(\n", + " m.fs.state_block.mole_frac_phase_comp[\"Vap\", \"benzene\"]\n", + ") == pytest.approx(0.610, abs=1e-2)\n", + "\n", + "assert pyo.value(\n", + " m.fs.state_block.mole_frac_phase_comp[\"Liq\", \"toluene\"]\n", + ") == pytest.approx(0.610, abs=1e-2)\n", + "assert pyo.value(\n", + " m.fs.state_block.mole_frac_phase_comp[\"Vap\", \"toluene\"]\n", + ") == pytest.approx(0.394, abs=1e-2)" ] }, { @@ -1305,7 +1305,6 @@ " m.experiment_outputs[m.liq_benzene_out[0]] = float(row[\"liq_benzene\"])\n", " m.experiment_outputs[m.vap_benzene_out[0]] = float(row[\"vap_benzene\"])\n", "\n", - "\n", " m.measurement_error = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", " m.measurement_error.update(\n", " [\n", From 42b3098a730eedc4156b8e738290f80ce8e90f49 Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Wed, 10 Jun 2026 22:50:23 -0400 Subject: [PATCH 06/23] Updating formatting and links --- ...er_estimation_nrtl_using_state_block.ipynb | 2 +- ...ter_estimation_nrtl_using_unit_model.ipynb | 194 ++++++++++++++++-- 2 files changed, 182 insertions(+), 14 deletions(-) diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block.ipynb index 1111c3cb..5dcc0ddc 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block.ipynb @@ -45,7 +45,7 @@ "\n", "## Key links to documentation:\n", "* NRTL Model - https://idaes-pse.readthedocs.io/en/stable/reference_guides/model_libraries/generic/property_models/activity_coefficient.html\n", - "* parmest - https://pyomo.readthedocs.io/en/stable/contributed_packages/parmest/index.html\n" + "* parmest - https://pyomo.readthedocs.io/en/stable/explanation/analysis/parmest/index.html\n" ] }, { diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb index 606face9..9b26ee0e 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb @@ -48,7 +48,7 @@ "\n", "## Key links to documentation:\n", "* NRTL Model - https://idaes-pse.readthedocs.io/en/stable/reference_guides/model_libraries/generic/property_models/activity_coefficient.html\n", - "* parmest - https://pyomo.readthedocs.io/en/stable/contributed_packages/parmest/index.html\n" + "* parmest - https://pyomo.readthedocs.io/en/stable/explanation/analysis/parmest/index.html" ] }, { @@ -348,7 +348,11 @@ "* List of variable names to be estimated\n", "* Dataset with multiple scenarios\n", "* Expression to compute the sum of squared errors\n", - "\n" + "\n", + "\n", + "Updated list:\n", + "* Dataset with multiple scenarios - organized into an experiment list\n", + "* Experiment class to set up and label model with suffixes\n" ] }, { @@ -368,7 +372,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ @@ -484,7 +488,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 12, "metadata": {}, "outputs": [ { @@ -959,13 +963,18 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ + "WARNING: DEPRECATED: You're using the deprecated parmest interface\n", + "(model_function, data, theta_names). This interface will be removed in a\n", + "future release, please update to the new parmest interface using experiment\n", + "lists. (deprecated in 6.7.2) (called from /Applications/anaconda3/envs/idaes-\n", + "examples-dev-py313-macmini/lib/python3.13/functools.py:974)\n", "Ipopt 3.13.2: \n", "\n", "******************************************************************************\n", @@ -1034,7 +1043,7 @@ "Number of equality constraint Jacobian evaluations = 12\n", "Number of inequality constraint Jacobian evaluations = 0\n", "Number of Lagrangian Hessian evaluations = 11\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.043\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.042\n", "Total CPU secs in NLP function evaluations = 0.009\n", "\n", "EXIT: Optimal Solution Found.\n" @@ -1051,7 +1060,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 16, "metadata": {}, "outputs": [], "source": [ @@ -1063,9 +1072,168 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 17, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 10950\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 6600\n", + "\n", + "Total number of variables............................: 2952\n", + " variables with only lower bounds: 150\n", + " variables with lower and upper bounds: 600\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 2950\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 6.0671019e-03 5.63e+02 1.20e-08 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 9.0714942e-04 1.37e+03 1.61e+01 -1.0 1.37e+04 - 9.82e-01 1.00e+00h 1\n", + " 2 1.3219937e-03 1.17e+04 1.62e+01 -1.0 5.23e+03 - 3.41e-01 1.65e-01h 3\n", + " 3 1.3161671e-03 1.11e+04 4.02e+01 -1.0 3.96e+02 -4.0 8.19e-01 1.25e-01h 4\n", + " 4 1.3154170e-03 1.11e+04 4.32e+01 -1.0 3.47e+02 -4.5 9.90e-01 4.43e-02h 5\n", + " 5 9.4424343e-04 1.04e+04 4.05e+01 -1.0 1.16e+04 - 9.33e-01 5.61e-02h 5\n", + " 6 9.4571258e-04 1.11e+04 4.85e+01 -1.0 3.13e+02 -5.0 8.74e-01 1.25e-01h 4\n", + " 7 9.4862862e-04 1.11e+04 4.84e+01 -1.0 2.41e+03 -5.4 1.72e-01 1.50e-03h 8\n", + " 8 9.5448936e-04 1.10e+04 4.81e+01 -1.0 4.11e+02 -5.0 1.00e+00 1.97e-02h 6\n", + " 9 9.5650047e-04 1.10e+04 4.81e+01 -1.0 5.14e+02 -4.6 3.46e-01 5.24e-03h 7\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 9.5730419e-04 1.10e+04 4.81e+01 -1.0 9.78e+02 -4.2 4.40e-01 1.08e-03h 8\n", + " 11 9.5774182e-04 1.10e+04 4.84e+01 -1.0 2.76e+02 -3.7 2.91e-01 2.99e-03h 7\n", + " 12 9.4292855e-04 7.77e+04 4.09e+04 -1.0 5.38e+02 -2.4 5.48e-02 6.44e-02w 1\n", + " 13 2.4318219e-01 2.38e+07 4.22e+14 -1.0 1.28e+06 - 2.55e-02 3.49e-02w 1\n", + " 14 2.8902019e-01 1.64e+07 2.92e+14 -1.0 1.11e+05 -2.9 9.54e-01 3.01e-01w 1\n", + " 15 9.5768293e-04 1.10e+04 4.85e+01 -1.0 2.80e+05 -3.4 5.48e-02 2.52e-04h 8\n", + " 16 9.5769345e-04 1.10e+04 4.85e+01 -1.0 4.33e+02 -2.9 7.95e-02 1.91e-04h 9\n", + " 17 9.5763809e-04 1.10e+04 4.85e+01 -1.0 6.35e+02 -2.5 4.94e-02 2.08e-04h 9\n", + " 18 9.5734836e-04 1.10e+04 4.87e+01 -1.0 3.22e+02 -3.0 1.00e+00 1.22e-03h 8\n", + " 19 9.3628114e-04 1.09e+04 4.62e+01 -1.0 4.22e+02 -3.5 5.16e-01 5.87e-02h 5\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 7.1894543e-04 4.02e+03 4.95e+02 -1.0 3.49e+02 -3.9 1.00e+00 1.00e+00h 1\n", + " 21 6.7062834e-04 1.58e+02 2.21e+02 -1.0 1.78e+02 -4.4 1.00e+00 1.00e+00h 1\n", + " 22 6.6635123e-04 4.17e+01 1.12e+01 -1.0 2.44e+02 -4.9 1.00e+00 1.00e+00h 1\n", + " 23 6.6729070e-04 1.43e+00 9.69e-01 -1.0 1.08e+01 -5.4 1.00e+00 1.00e+00h 1\n", + " 24 6.6785681e-04 3.58e-01 5.25e-03 -1.7 6.65e+00 -5.8 1.00e+00 1.00e+00h 1\n", + " 25 6.2552355e-04 9.80e+02 6.48e-02 -3.8 7.92e+02 - 9.22e-01 1.00e+00h 1\n", + " 26 5.9105707e-04 8.13e+00 6.13e-04 -3.8 5.66e+02 - 1.00e+00 1.00e+00h 1\n", + " 27 6.1313801e-04 6.24e+01 8.08e-06 -3.8 1.70e+02 - 1.00e+00 1.00e+00h 1\n", + " 28 6.1208051e-04 3.58e-01 1.18e-08 -3.8 1.88e+00 - 1.00e+00 1.00e+00h 1\n", + " 29 5.9010560e-04 1.58e+01 1.00e-05 -5.7 1.08e+02 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30 5.9008319e-04 2.74e-02 7.90e-07 -5.7 7.54e-02 -6.3 1.00e+00 1.00e+00h 1\n", + " 31 5.3570104e-04 1.48e+04 8.70e-04 -5.7 1.81e+02 - 1.00e+00 1.00e+00h 1\n", + " 32 5.1618763e-04 6.29e+02 8.06e-05 -5.7 2.55e+02 - 1.00e+00 1.00e+00h 1\n", + " 33 5.5250565e-04 2.88e+01 2.58e-04 -5.7 1.81e+04 - 6.26e-01 6.25e-02h 5\n", + " 34 5.2209909e-04 2.88e+02 2.02e-04 -5.7 1.89e+03 - 1.00e+00 1.00e+00h 1\n", + " 35 5.0707798e-04 5.60e+01 2.02e-04 -5.7 2.93e+03 - 1.00e+00 1.00e+00h 1\n", + " 36 5.0765648e-04 7.87e+00 1.91e-05 -5.7 1.02e+02 - 1.00e+00 1.00e+00h 1\n", + " 37 5.0740606e-04 2.57e+00 1.88e-05 -5.7 6.96e+01 - 1.00e+00 1.00e+00h 1\n", + " 38 5.0764164e-04 2.55e+00 1.76e-05 -5.7 6.81e+01 - 1.00e+00 1.00e+00h 1\n", + " 39 5.0740672e-04 2.55e+00 1.88e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 40 5.0764162e-04 2.54e+00 1.76e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", + " 41 5.0740672e-04 2.55e+00 1.88e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", + " 42 5.0782847e-04 1.43e-01 1.83e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00H 1\n", + " 43 5.0751252e-04 1.58e-02 1.93e-05 -5.7 6.88e+01 - 1.00e+00 1.00e+00H 1\n", + " 44 5.0783218e-04 4.79e-03 1.85e-05 -5.7 6.92e+01 - 1.00e+00 1.00e+00H 1\n", + " 45 5.0751252e-04 1.60e-02 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", + " 46 5.0783222e-04 1.23e-04 1.85e-05 -5.7 6.92e+01 - 1.00e+00 1.00e+00H 1\n", + " 47 5.0751252e-04 1.60e-02 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", + " 48 5.0783216e-04 1.24e-04 1.85e-05 -5.7 6.92e+01 - 1.00e+00 1.00e+00H 1\n", + " 49 5.0751765e-04 3.20e-03 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 50 5.0764151e-04 2.56e+00 1.77e-05 -5.7 6.93e+01 - 1.00e+00 1.00e+00h 1\n", + " 51 5.0740671e-04 2.55e+00 1.88e-05 -5.7 6.81e+01 - 1.00e+00 1.00e+00h 1\n", + " 52 5.0764162e-04 2.54e+00 1.76e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", + " 53 5.0740672e-04 2.55e+00 1.88e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", + " 54 5.0764162e-04 2.54e+00 1.76e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", + " 55 5.0748886e-04 1.91e+00 8.64e-06 -5.7 6.80e+01 - 1.00e+00 5.00e-01h 2\n", + " 56 5.0744550e-04 3.37e-01 1.64e-05 -5.7 2.54e+01 - 1.00e+00 1.00e+00h 1\n", + " 57 5.0763613e-04 1.82e+00 1.43e-05 -5.7 5.79e+01 - 1.00e+00 1.00e+00h 1\n", + " 58 5.0751252e-04 2.25e-02 1.93e-05 -5.7 6.65e+01 - 1.00e+00 1.00e+00H 1\n", + " 59 5.0783220e-04 1.23e-04 1.85e-05 -5.7 6.92e+01 - 1.00e+00 1.00e+00H 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 60 5.0751252e-04 1.60e-02 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", + " 61 5.0783207e-04 3.26e-04 1.85e-05 -5.7 6.92e+01 - 1.00e+00 1.00e+00H 1\n", + " 62 5.0751786e-04 7.95e-05 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", + " 63 5.0754291e-04 6.40e-01 8.69e-06 -5.7 6.93e+01 - 1.00e+00 5.00e-01h 2\n", + " 64 5.0745167e-04 3.00e-01 1.61e-05 -5.7 2.35e+01 - 1.00e+00 1.00e+00h 1\n", + " 65 5.0763437e-04 1.71e+00 1.33e-05 -5.7 5.61e+01 - 1.00e+00 1.00e+00h 1\n", + " 66 5.0751762e-04 2.91e-03 1.93e-05 -5.7 6.60e+01 - 1.00e+00 1.00e+00H 1\n", + " 67 5.0752104e-04 1.62e-01 1.43e-05 -5.7 6.92e+01 - 1.00e+00 2.50e-01h 3\n", + " 68 5.0761295e-04 1.03e+00 2.18e-05 -5.7 4.35e+01 - 1.00e+00 1.00e+00h 1\n", + " 69 5.0751251e-04 2.38e-02 1.92e-05 -5.7 5.95e+01 - 1.00e+00 1.00e+00H 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 70 5.0783210e-04 3.29e-06 1.85e-05 -5.7 6.90e+01 - 1.00e+00 1.00e+00H 1\n", + " 71 5.0751786e-04 7.94e-05 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", + " 72 5.0754292e-04 6.40e-01 8.69e-06 -5.7 6.93e+01 - 1.00e+00 5.00e-01h 2\n", + " 73 5.0749299e-04 3.95e-01 1.21e-05 -5.7 2.35e+01 - 1.00e+00 5.00e-01h 2\n", + " 74 5.0755524e-04 1.36e-01 3.09e-05 -5.7 1.57e+01 - 1.00e+00 1.00e+00h 1\n", + " 75 5.0751308e-04 1.96e-02 1.80e-05 -5.7 3.30e+01 - 1.00e+00 1.00e+00H 1\n", + " 76 5.0754492e-04 5.62e-01 8.19e-06 -5.7 6.42e+01 - 1.00e+00 5.00e-01h 2\n", + " 77 5.0748301e-04 3.98e-01 1.25e-05 -5.7 2.93e+01 - 1.00e+00 5.00e-01h 2\n", + " 78 5.0756455e-04 2.42e-01 3.07e-05 -5.7 2.09e+01 - 1.00e+00 1.00e+00h 1\n", + " 79 5.0751710e-04 1.38e-03 1.87e-05 -5.7 3.98e+01 - 1.00e+00 1.00e+00H 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 80 5.0783077e-04 3.26e-06 1.84e-05 -5.7 6.70e+01 - 1.00e+00 1.00e+00H 1\n", + " 81 5.0726420e-04 1.24e+01 1.85e-05 -8.6 1.34e+02 - 9.93e-01 1.00e+00h 1\n", + " 82 5.0749897e-04 2.75e+00 2.53e-06 -8.6 6.93e+01 - 1.00e+00 1.00e+00h 1\n", + " 83 5.0749686e-04 3.64e-04 6.40e-10 -8.6 4.69e-02 - 1.00e+00 1.00e+00h 1\n", + " 84 5.0749686e-04 7.28e-11 2.51e-14 -8.6 6.86e-05 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 84\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 5.0749685809243843e-04 5.0749685809243843e-04\n", + "Dual infeasibility......: 2.5059195074646584e-14 2.5059195074646584e-14\n", + "Constraint violation....: 1.4104644499482425e-11 7.2759576141834259e-11\n", + "Complementarity.........: 2.5059035596800647e-09 2.5059035596800647e-09\n", + "Overall NLP error.......: 2.5059035596800647e-09 2.5059035596800647e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 260\n", + "Number of objective gradient evaluations = 85\n", + "Number of equality constraint evaluations = 260\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 85\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 84\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.333\n", + "Total CPU secs in NLP function evaluations = 0.092\n", + "\n", + "EXIT: Optimal Solution Found.\n" + ] + } + ], "source": [ "pest_new = parmest.Estimator(exp_list, obj_function=\"SSE\", tee=True)\n", "obj_value_new, parameters_new = pest_new.theta_est()" @@ -1073,7 +1241,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 18, "metadata": { "tags": [ "testing" @@ -1098,7 +1266,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 19, "metadata": {}, "outputs": [ { @@ -1130,7 +1298,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 20, "metadata": {}, "outputs": [ { @@ -1173,7 +1341,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 21, "metadata": {}, "outputs": [], "source": [ From 14291aa435d182bba5dec045cbb652a08d9e5e58 Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Wed, 10 Jun 2026 23:38:00 -0400 Subject: [PATCH 07/23] Checked bootstrap with new against old interface, updated docs link --- ...ter_estimation_nrtl_using_unit_model.ipynb | 886 +++++++++++++++++- 1 file changed, 877 insertions(+), 9 deletions(-) diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb index 9b26ee0e..423476b3 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb @@ -1043,8 +1043,8 @@ "Number of equality constraint Jacobian evaluations = 12\n", "Number of inequality constraint Jacobian evaluations = 0\n", "Number of Lagrangian Hessian evaluations = 11\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.042\n", - "Total CPU secs in NLP function evaluations = 0.009\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.045\n", + "Total CPU secs in NLP function evaluations = 0.010\n", "\n", "EXIT: Optimal Solution Found.\n" ] @@ -1072,7 +1072,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 23, "metadata": {}, "outputs": [ { @@ -1227,8 +1227,8 @@ "Number of equality constraint Jacobian evaluations = 85\n", "Number of inequality constraint Jacobian evaluations = 0\n", "Number of Lagrangian Hessian evaluations = 84\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.333\n", - "Total CPU secs in NLP function evaluations = 0.092\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.346\n", + "Total CPU secs in NLP function evaluations = 0.097\n", "\n", "EXIT: Optimal Solution Found.\n" ] @@ -1334,7 +1334,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Pyomo's `parmest` tool allows for bootstrapping where the parameter estimation is repeated over `n` samples with resampling from the original data set. Parameter estimation with bootstrap resampling can be used to identify confidence regions around each parameter estimate. This analysis can be slow given the increased number of model instances that need to be solved. Please refer to https://pyomo.readthedocs.io/en/stable/contributed_packages/parmest/driver.html for more details. \n", + "Pyomo's `parmest` tool allows for bootstrapping where the parameter estimation is repeated over `n` samples with resampling from the original data set. Parameter estimation with bootstrap resampling can be used to identify confidence regions around each parameter estimate. This analysis can be slow given the increased number of model instances that need to be solved. Please refer to https://pyomo.readthedocs.io/en/stable/explanation/analysis/parmest/covariance.html#bootstrapping for more details. \n", "\n", "For the example above, the bootstrapping can be run by uncommenting the code in the following cell:" ] @@ -1343,15 +1343,883 @@ "cell_type": "code", "execution_count": 21, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 10946\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 6600\n", + "\n", + "Total number of variables............................: 2950\n", + " variables with only lower bounds: 150\n", + " variables with lower and upper bounds: 600\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 2948\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.6536093e+01 5.63e+02 8.94e-05 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.9655429e+00 1.55e+03 7.54e+01 -1.0 1.37e+04 - 9.45e-01 1.00e+00h 1\n", + " 2 5.2504754e+00 1.81e+02 4.22e+02 -1.0 5.26e+02 -4.0 9.90e-01 1.00e+00h 1\n", + " 3 5.2261387e+00 9.62e-01 3.18e+01 -1.0 9.00e+01 -4.5 9.92e-01 1.00e+00h 1\n", + " 4 5.0173696e+00 1.34e+03 6.28e+01 -1.0 1.56e+03 - 1.00e+00 1.00e+00f 1\n", + " 5 5.0148066e+00 1.52e+02 7.82e-01 -1.0 1.12e+03 - 1.00e+00 1.00e+00h 1\n", + " 6 4.9235551e+00 1.18e+03 5.90e-01 -1.7 1.52e+02 - 1.00e+00 1.00e+00h 1\n", + " 7 4.9223558e+00 1.18e+02 1.87e-01 -1.7 3.27e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 4.9190596e+00 8.79e+00 3.32e-02 -1.7 2.73e+01 - 1.00e+00 1.00e+00h 1\n", + " 9 4.9166308e+00 7.38e+00 4.12e-03 -2.5 1.72e+01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 4.9165551e+00 8.08e-02 3.52e-04 -3.8 2.20e+00 - 1.00e+00 1.00e+00h 1\n", + " 11 4.9165547e+00 6.24e-04 7.79e-06 -5.7 1.62e-01 - 1.00e+00 1.00e+00h 1\n", + " 12 4.9165547e+00 1.29e-07 1.85e-09 -8.6 2.35e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 12\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 4.9165546791664232e+00 4.9165546791664232e+00\n", + "Dual infeasibility......: 1.8546585645584926e-09 1.8546585645584926e-09\n", + "Constraint violation....: 4.4904551981997418e-10 1.2922100722789764e-07\n", + "Complementarity.........: 2.5084427386564811e-09 2.5084427386564811e-09\n", + "Overall NLP error.......: 2.5084427386564811e-09 1.2922100722789764e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 13\n", + "Number of objective gradient evaluations = 13\n", + "Number of equality constraint evaluations = 13\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 13\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 12\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.047\n", + "Total CPU secs in NLP function evaluations = 0.010\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 10946\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 6600\n", + "\n", + "Total number of variables............................: 2950\n", + " variables with only lower bounds: 150\n", + " variables with lower and upper bounds: 600\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 2948\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 4.7550067e+01 5.41e+02 1.18e-04 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 3.8782296e+00 1.55e+03 7.05e+01 -1.0 1.32e+04 - 9.58e-01 1.00e+00h 1\n", + " 2 4.0280011e+00 1.20e+02 2.62e+02 -1.0 2.91e+02 -4.0 9.90e-01 1.00e+00h 1\n", + " 3 4.0213935e+00 4.77e-01 1.58e+01 -1.0 1.15e+01 -4.5 9.92e-01 1.00e+00h 1\n", + " 4 4.0659444e+00 1.17e+02 1.86e+00 -1.0 4.88e+02 - 1.00e+00 1.00e+00h 1\n", + " 5 4.0569748e+00 4.50e-02 4.81e-03 -1.0 2.73e+01 - 1.00e+00 1.00e+00h 1\n", + " 6 4.0151231e+00 1.14e+02 6.02e-02 -2.5 3.63e+02 - 1.00e+00 1.00e+00h 1\n", + " 7 4.0145579e+00 1.46e+00 9.55e-04 -2.5 2.10e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 4.0144812e+00 4.75e-02 2.56e-05 -3.8 8.88e+00 - 1.00e+00 1.00e+00h 1\n", + " 9 4.0144810e+00 1.47e-04 8.01e-08 -5.7 4.88e-01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 4.0144810e+00 2.42e-08 1.32e-11 -8.6 6.15e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 10\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 4.0144809745145293e+00 4.0144809745145293e+00\n", + "Dual infeasibility......: 1.3235991345144155e-11 1.3235991345144155e-11\n", + "Constraint violation....: 8.3962104404275412e-11 2.4156179279088974e-08\n", + "Complementarity.........: 2.5071885683769132e-09 2.5071885683769132e-09\n", + "Overall NLP error.......: 2.5071885683769132e-09 2.4156179279088974e-08\n", + "\n", + "\n", + "Number of objective function evaluations = 11\n", + "Number of objective gradient evaluations = 11\n", + "Number of equality constraint evaluations = 11\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 11\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 10\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.041\n", + "Total CPU secs in NLP function evaluations = 0.008\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 10946\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 6600\n", + "\n", + "Total number of variables............................: 2950\n", + " variables with only lower bounds: 150\n", + " variables with lower and upper bounds: 600\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 2948\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 7.7751928e+01 5.63e+02 1.77e-04 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 3.6258012e+00 1.56e+03 7.05e+01 -1.0 1.37e+04 - 9.35e-01 1.00e+00h 1\n", + " 2 3.8259201e+00 1.17e+02 7.78e+02 -1.0 1.07e+03 -4.0 9.90e-01 1.00e+00h 1\n", + " 3 3.7935297e+00 2.61e-01 3.68e+01 -1.0 9.46e+01 -4.5 9.92e-01 1.00e+00h 1\n", + " 4 3.7581605e+00 3.00e+02 3.58e+01 -1.0 8.82e+02 - 1.00e+00 1.00e+00f 1\n", + " 5 3.7397696e+00 1.93e-01 7.15e-02 -1.0 2.41e+01 - 1.00e+00 1.00e+00h 1\n", + " 6 3.6958865e+00 9.59e+01 5.32e-02 -2.5 3.46e+02 - 1.00e+00 1.00e+00h 1\n", + " 7 3.6954293e+00 9.42e-01 6.26e-04 -2.5 1.65e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 3.6953637e+00 4.41e-02 2.49e-05 -3.8 8.65e+00 - 1.00e+00 1.00e+00h 1\n", + " 9 3.6953635e+00 1.33e-04 7.57e-08 -5.7 4.75e-01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 3.6953635e+00 2.17e-08 1.24e-11 -8.6 5.97e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 10\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 3.6953634629145982e+00 3.6953634629145982e+00\n", + "Dual infeasibility......: 1.2431270208802497e-11 1.2431270208802497e-11\n", + "Constraint violation....: 7.5414155220948578e-11 2.1696905605494976e-08\n", + "Complementarity.........: 2.5071430842635661e-09 2.5071430842635661e-09\n", + "Overall NLP error.......: 2.5071430842635661e-09 2.1696905605494976e-08\n", + "\n", + "\n", + "Number of objective function evaluations = 11\n", + "Number of objective gradient evaluations = 11\n", + "Number of equality constraint evaluations = 11\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 11\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 10\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.042\n", + "Total CPU secs in NLP function evaluations = 0.009\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 10946\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 6600\n", + "\n", + "Total number of variables............................: 2950\n", + " variables with only lower bounds: 150\n", + " variables with lower and upper bounds: 600\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 2948\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 6.8031043e+01 5.63e+02 1.14e-04 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 5.0185338e+00 1.55e+03 7.39e+01 -1.0 1.37e+04 - 9.42e-01 1.00e+00h 1\n", + " 2 5.0608118e+00 1.78e+02 5.15e+02 -1.0 6.27e+02 -4.0 9.90e-01 1.00e+00h 1\n", + " 3 5.0653499e+00 1.54e+00 4.04e+02 -1.0 2.54e+01 -4.5 9.92e-01 1.00e+00h 1\n", + " 4 5.0589066e+00 1.79e-02 1.06e+01 -1.0 1.47e+01 -5.0 1.00e+00 1.00e+00h 1\n", + " 5 5.0361352e+00 1.17e+02 1.40e+00 -1.0 5.48e+02 - 1.00e+00 1.00e+00f 1\n", + " 6 5.0407158e+00 1.43e+00 2.51e-02 -1.0 2.24e+01 - 1.00e+00 1.00e+00h 1\n", + " 7 4.9971707e+00 9.71e+01 1.60e-01 -2.5 3.48e+02 - 1.00e+00 1.00e+00h 1\n", + " 8 5.0177775e+00 1.28e+01 5.58e-02 -2.5 1.67e+02 - 1.00e+00 1.00e+00h 1\n", + " 9 5.0175879e+00 1.24e-02 2.99e-05 -2.5 1.30e+00 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 5.0175562e+00 5.25e-02 3.70e-05 -3.8 8.96e+00 - 1.00e+00 1.00e+00h 1\n", + " 11 5.0175560e+00 1.45e-04 1.02e-07 -5.7 4.86e-01 - 1.00e+00 1.00e+00h 1\n", + " 12 5.0175560e+00 2.41e-08 1.70e-11 -8.6 6.12e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 12\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 5.0175559693199334e+00 5.0175559693199334e+00\n", + "Dual infeasibility......: 1.6954380424451648e-11 1.6954380424451648e-11\n", + "Constraint violation....: 8.3709206499443261e-11 2.4097971618175503e-08\n", + "Complementarity.........: 2.5071793787018949e-09 2.5071793787018949e-09\n", + "Overall NLP error.......: 2.5071793787018949e-09 2.4097971618175503e-08\n", + "\n", + "\n", + "Number of objective function evaluations = 13\n", + "Number of objective gradient evaluations = 13\n", + "Number of equality constraint evaluations = 13\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 13\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 12\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.050\n", + "Total CPU secs in NLP function evaluations = 0.010\n", + "\n", + "EXIT: Optimal Solution Found.\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
fs.properties.tau[benzene,toluene]fs.properties.tau[toluene,benzene]
0-0.7795401.167155
1-0.9396911.509965
2-0.9563611.545695
3-0.9410871.501137
\n", + "
" + ], + "text/plain": [ + " fs.properties.tau[benzene,toluene] fs.properties.tau[toluene,benzene]\n", + "0 -0.779540 1.167155\n", + "1 -0.939691 1.509965\n", + "2 -0.956361 1.545695\n", + "3 -0.941087 1.501137" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "# Run parameter estimation using bootstrap resample of the data (10 samples),\n", "# plot results along with confidence regions\n", "\n", "# Uncomment the following lines\n", "\n", - "# bootstrap_theta = pest.theta_est_bootstrap(4)\n", - "# display(bootstrap_theta)" + "bootstrap_theta = pest.theta_est_bootstrap(4)\n", + "display(bootstrap_theta)" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 10950\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 6600\n", + "\n", + "Total number of variables............................: 2952\n", + " variables with only lower bounds: 150\n", + " variables with lower and upper bounds: 600\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 2950\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.5039152e-03 5.63e+02 1.21e-08 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 9.9499827e-04 1.27e+03 1.56e+01 -1.0 1.37e+04 - 9.82e-01 1.00e+00h 1\n", + " 2 1.2925762e-03 1.17e+04 1.68e+01 -1.0 1.58e+04 - 1.20e-01 5.40e-02h 3\n", + " 3 1.2860094e-03 1.10e+04 4.29e+01 -1.0 4.48e+02 -4.0 8.03e-01 1.25e-01h 4\n", + " 4 8.9491243e-03 7.73e+04 5.80e+04 -1.0 3.92e+02 -4.5 8.08e-01 1.00e+00H 1\n", + " 5 2.1691585e-03 1.45e+04 4.08e+04 -1.0 6.67e+03 -5.0 9.92e-01 1.00e+00h 1\n", + " 6 6.1358159e-03 1.38e+04 3.94e+04 -1.0 1.75e+05 - 2.27e-01 3.61e-02h 4\n", + " 7 6.9284654e-03 5.65e+02 8.11e+03 -1.0 5.49e+03 -5.4 1.00e+00 1.00e+00h 1\n", + " 8 4.5286851e-03 9.90e+01 2.10e+03 -1.0 6.81e+03 -5.9 1.00e+00 1.00e+00h 1\n", + " 9 4.5000575e-03 4.26e+02 6.04e+03 -1.0 3.95e+02 -2.8 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 4.2972057e-03 3.61e+02 4.86e+03 -1.0 5.30e+01 - 1.00e+00 1.00e+00h 1\n", + " 11 4.2972497e-03 7.00e+01 2.76e+01 -1.0 2.49e+00 -2.3 1.00e+00 1.00e+00h 1\n", + " 12 4.2966473e-03 6.60e+01 2.16e+01 -1.0 9.32e+00 -2.8 1.00e+00 1.25e-01h 4\n", + " 13 4.2962487e-03 6.31e+01 1.53e+01 -1.0 6.14e+00 -2.4 1.00e+00 1.25e-01h 4\n", + " 14 4.2962058e-03 6.31e+01 1.52e+01 -1.0 4.53e+01 -2.0 1.00e+00 1.95e-03h 10\n", + " 15 4.2960970e-03 6.20e+01 1.03e+01 -1.0 3.31e+00 -1.5 1.00e+00 6.25e-02h 5\n", + " 16 4.2960972e-03 6.15e+01 1.09e+01 -1.0 5.99e-01 -0.2 1.00e+00 1.56e-02h 7\n", + " 17 4.2961140e-03 6.13e+01 2.27e+01 -1.0 4.56e+00 0.2 1.00e+00 7.81e-03h 8\n", + " 18 4.2981828e-03 4.32e+02 2.13e+04 -1.0 4.65e+00 -0.3 1.00e+00 1.00e+00h 1\n", + " 19 4.3006732e-03 5.69e+01 5.77e+03 -1.0 4.58e+00 -0.7 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 4.3021197e-03 2.80e+00 4.23e+02 -1.0 3.55e+00 -1.2 1.00e+00 1.00e+00h 1\n", + " 21 4.3021593e-03 8.51e-03 8.36e+00 -1.0 8.06e-02 -1.7 1.00e+00 1.00e+00h 1\n", + " 22 4.3021706e-03 3.74e-04 1.14e-02 -1.0 2.52e-02 -2.2 1.00e+00 1.00e+00h 1\n", + " 23 4.3021715e-03 2.76e-06 1.12e-04 -2.5 2.17e-03 -2.7 1.00e+00 1.00e+00h 1\n", + " 24 4.3021715e-03 4.86e-08 4.11e-07 -3.8 3.93e-04 -3.1 1.00e+00 1.00e+00h 1\n", + " 25 3.4514655e-03 5.60e+03 2.98e-01 -5.7 1.05e+04 - 8.16e-01 1.00e+00f 1\n", + " 26 2.5110719e-03 1.01e+04 2.24e+05 -5.7 1.00e+04 -3.6 8.00e-01 1.00e+00h 1\n", + " 27 2.5218883e-03 3.02e+03 2.15e+05 -5.7 1.02e+03 -2.3 1.00e+00 1.00e+00h 1\n", + " 28 3.5653354e-03 1.83e+02 3.22e+04 -5.7 5.25e+02 - 1.00e+00 1.00e+00h 1\n", + " 29 3.5612958e-03 1.87e+00 9.97e+01 -5.7 1.92e+01 -2.8 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30 3.5612874e-03 3.13e-06 3.49e-02 -5.7 3.82e-02 -3.2 1.00e+00 1.00e+00h 1\n", + " 31 3.5612869e-03 3.49e-10 1.52e-07 -5.7 2.32e-04 -3.7 1.00e+00 1.00e+00h 1\n", + " 32 5.6562035e-04 1.13e+04 1.06e-03 -8.6 2.57e+03 - 6.57e-01 1.00e+00f 1\n", + " 33 5.3709230e-04 6.64e+02 2.03e-04 -8.6 1.50e+03 - 8.61e-01 1.00e+00h 1\n", + " 34 5.2969341e-04 1.04e+04 3.30e-04 -8.6 5.76e+02 - 8.23e-01 1.00e+00h 1\n", + " 35 5.2731451e-04 1.14e+02 4.87e+00 -8.6 1.20e+01 -4.2 1.00e+00 1.00e+00h 1\n", + " 36 5.2540830e-04 6.23e+02 2.92e+00 -8.6 6.48e+00 -4.7 1.00e+00 1.00e+00h 1\n", + " 37 5.2516465e-04 3.58e+01 2.72e-01 -8.6 7.04e-01 -5.1 1.00e+00 1.00e+00h 1\n", + " 38 5.2511621e-04 7.11e-02 3.15e-04 -8.6 2.11e-01 -5.6 1.00e+00 1.00e+00h 1\n", + " 39 5.1942063e-04 4.85e+01 1.03e-03 -8.6 3.25e+01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 40 5.1940758e-04 2.00e-01 1.03e-05 -8.6 1.21e-01 -6.1 1.00e+00 1.00e+00h 1\n", + " 41 5.0706803e-04 3.93e+02 4.81e-04 -8.6 1.06e+02 - 1.00e+00 1.00e+00h 1\n", + " 42 5.0484181e-04 6.05e+01 1.92e-05 -8.6 8.11e+01 - 1.00e+00 1.00e+00h 1\n", + " 43 5.0321977e-04 6.96e-01 5.12e-06 -8.6 2.68e+02 - 1.00e+00 1.00e+00h 1\n", + " 44 5.0321816e-04 2.22e-05 6.64e-11 -8.6 2.74e-01 - 1.00e+00 1.00e+00h 1\n", + " 45 5.0321815e-04 2.83e-06 1.87e-13 -9.0 5.66e-02 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 45\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 5.0321815482191131e-04 5.0321815482191131e-04\n", + "Dual infeasibility......: 1.8736280629389788e-13 1.8736280629389788e-13\n", + "Constraint violation....: 9.8306979362164903e-09 2.8283393476158381e-06\n", + "Complementarity.........: 9.0910208979411485e-10 9.0910208979411485e-10\n", + "Overall NLP error.......: 9.8306979362164903e-09 2.8283393476158381e-06\n", + "\n", + "\n", + "Number of objective function evaluations = 102\n", + "Number of objective gradient evaluations = 46\n", + "Number of equality constraint evaluations = 102\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 46\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 45\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.254\n", + "Total CPU secs in NLP function evaluations = 0.047\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 10950\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 6600\n", + "\n", + "Total number of variables............................: 2952\n", + " variables with only lower bounds: 150\n", + " variables with lower and upper bounds: 600\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 2950\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 6.1189504e-03 5.63e+02 1.47e-08 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 1.1779279e-03 1.29e+03 1.58e+01 -1.0 1.37e+04 - 9.82e-01 1.00e+00h 1\n", + " 2 1.1340302e-03 7.48e+00 7.68e+01 -1.0 4.74e+02 -4.0 9.90e-01 1.00e+00h 1\n", + " 3 1.1339115e-03 3.96e-03 1.69e+00 -1.0 2.89e+00 -4.5 9.95e-01 1.00e+00h 1\n", + " 4 1.1342835e-03 4.81e-02 8.71e-03 -1.0 1.53e+00 -5.0 1.00e+00 1.00e+00h 1\n", + " 5 1.1343090e-03 3.64e-04 4.03e-05 -2.5 1.31e-01 -5.4 1.00e+00 1.00e+00h 1\n", + " 6 1.1342943e-03 7.15e-06 1.56e-07 -3.8 2.71e-02 -5.9 1.00e+00 1.00e+00h 1\n", + " 7 1.1342350e-03 6.98e-07 1.30e-08 -5.7 3.15e-02 -6.4 1.00e+00 1.00e+00h 1\n", + " 8 4.6007010e-04 9.99e+01 1.99e-04 -8.6 7.09e+02 - 9.51e-01 1.00e+00f 1\n", + " 9 4.5743136e-04 7.92e+00 1.58e-05 -8.6 5.32e+02 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 4.5742268e-04 2.23e-04 3.08e-09 -8.6 9.76e-01 - 1.00e+00 1.00e+00h 1\n", + " 11 4.5742268e-04 1.91e-08 5.98e-14 -8.6 6.14e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 11\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 4.5742267974963584e-04 4.5742267974963584e-04\n", + "Dual infeasibility......: 5.9847447620240048e-14 5.9847447620240048e-14\n", + "Constraint violation....: 6.6461569389890306e-11 1.9121216610074043e-08\n", + "Complementarity.........: 2.5059035597140184e-09 2.5059035597140184e-09\n", + "Overall NLP error.......: 2.5059035597140184e-09 1.9121216610074043e-08\n", + "\n", + "\n", + "Number of objective function evaluations = 12\n", + "Number of objective gradient evaluations = 12\n", + "Number of equality constraint evaluations = 12\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 12\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 11\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.054\n", + "Total CPU secs in NLP function evaluations = 0.009\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 10950\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 6600\n", + "\n", + "Total number of variables............................: 2952\n", + " variables with only lower bounds: 150\n", + " variables with lower and upper bounds: 600\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 2950\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 7.3140480e-03 4.99e+02 1.73e-08 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 1.3207560e-03 1.51e+03 1.71e+01 -1.0 1.22e+04 - 9.80e-01 1.00e+00h 1\n", + " 2 1.8154463e-03 1.17e+04 1.79e+01 -1.0 6.32e+03 - 2.80e-01 1.33e-01h 3\n", + " 3 1.8019859e-03 1.15e+04 1.68e+02 -1.0 3.24e+02 -4.0 8.33e-01 2.50e-01h 3\n", + " 4 9.1607115e-04 1.14e+04 1.67e+02 -1.0 5.66e+04 - 1.86e-01 1.21e-02h 5\n", + " 5 9.1689129e-04 1.15e+04 1.68e+02 -1.0 2.40e+02 -4.5 2.90e-01 8.20e-03h 6\n", + " 6 9.1779570e-04 1.15e+04 1.68e+02 -1.0 3.09e+02 -4.1 3.68e-01 4.46e-03h 7\n", + " 7 9.1783813e-04 1.15e+04 1.68e+02 -1.0 2.66e+02 -2.7 9.91e-01 8.10e-04h 8\n", + " 8 9.1750565e-04 1.16e+04 1.69e+02 -1.0 4.79e+02 -1.4 5.55e-02 2.05e-03h 6\n", + " 9 9.1580217e-04 1.14e+04 4.52e+02 -1.0 2.36e+02 -1.9 6.09e-01 2.40e-02h 6\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 5.8569305e-04 4.67e+02 1.96e+04 -1.0 4.28e+02 -2.3 1.00e+00 1.00e+00h 1\n", + " 11 5.8102621e-04 7.59e-01 2.13e+03 -1.0 4.93e+01 -2.8 1.00e+00 1.00e+00h 1\n", + " 12 5.8104491e-04 4.95e-04 4.24e-01 -1.0 1.38e-01 -3.3 1.00e+00 1.00e+00h 1\n", + " 13 6.5261872e-04 4.25e+01 2.41e-01 -1.7 2.45e+02 - 1.00e+00 1.00e+00f 1\n", + " 14 3.0298036e-03 5.64e+02 1.93e-02 -1.7 9.30e+02 - 1.00e+00 1.00e+00H 1\n", + " 15 3.3279331e-03 1.65e+03 8.87e-03 -1.7 7.85e+02 - 1.00e+00 1.00e+00h 1\n", + " 16 3.2805595e-03 1.10e+01 3.81e-05 -1.7 3.88e+02 - 1.00e+00 1.00e+00h 1\n", + " 17 3.0656018e-03 6.69e-01 4.98e-04 -2.5 1.94e+02 - 1.00e+00 1.00e+00h 1\n", + " 18 1.8976854e-03 2.88e+01 5.46e-04 -3.8 1.27e+03 - 1.00e+00 1.00e+00h 1\n", + " 19 6.3352994e-04 1.33e+02 1.31e-03 -3.8 1.09e+03 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 6.3635621e-04 1.03e+01 4.92e-06 -3.8 2.33e+01 - 1.00e+00 1.00e+00h 1\n", + " 21 6.3629587e-04 1.62e-03 1.50e-09 -3.8 1.70e-01 - 1.00e+00 1.00e+00h 1\n", + " 22 6.0131604e-04 2.48e+01 1.40e-05 -5.7 1.36e+02 - 1.00e+00 1.00e+00h 1\n", + " 23 6.0129826e-04 7.17e-02 6.26e-04 -5.7 1.21e-01 -3.8 1.00e+00 1.00e+00h 1\n", + " 24 6.0000985e-04 2.32e+00 3.59e-03 -5.7 5.65e+00 - 1.00e+00 1.00e+00h 1\n", + " 25 6.0000928e-04 3.98e-04 3.57e-07 -5.7 1.69e-03 -4.3 1.00e+00 1.00e+00h 1\n", + " 26 5.6683620e-04 2.63e+03 9.94e-04 -8.6 7.02e+01 - 8.93e-01 1.00e+00h 1\n", + " 27 5.6671075e-04 2.00e+02 4.83e-02 -8.6 8.57e-01 -4.7 9.61e-01 1.00e+00h 1\n", + " 28 5.6635393e-04 1.08e-01 1.03e-03 -8.6 1.42e+00 -5.2 1.00e+00 1.00e+00h 1\n", + " 29 5.6570294e-04 7.69e+00 6.61e-03 -8.6 4.44e+01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30 5.6570173e-04 9.41e-03 5.90e-07 -8.6 1.19e-02 -5.7 1.00e+00 1.00e+00h 1\n", + " 31 5.1008979e-04 2.08e+04 1.33e-03 -8.6 6.79e+02 - 1.00e+00 1.00e+00h 1\n", + " 32 5.5137735e-04 1.22e+04 1.22e-03 -8.6 4.98e+02 - 1.00e+00 5.00e-01h 2\n", + " 33 5.5548664e-04 1.07e+04 1.07e-03 -8.6 4.01e+03 - 1.00e+00 1.25e-01h 4\n", + " 34 5.6114479e-04 1.00e+04 1.01e-03 -8.6 4.69e+03 - 1.00e+00 6.25e-02h 5\n", + " 35 5.6120142e-04 1.00e+04 1.01e-03 -8.6 2.11e+03 - 1.00e+00 4.88e-04h 12\n", + " 36 5.6120851e-04 1.00e+04 1.01e-03 -8.6 2.02e+03 - 1.00e+00 6.10e-05h 15\n", + " 37 9.4903015e-04 1.02e+04 3.53e-03 -8.6 2.03e+03 - 1.00e+00 1.00e+00H 1\n", + " 38 2.0775542e-03 3.23e+03 5.67e-03 -8.6 1.17e+04 - 1.00e+00 1.00e+00h 1\n", + " 39 5.1793815e-04 5.47e+02 2.09e-03 -8.6 7.94e+03 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 40 4.8972355e-04 8.79e+00 1.17e+00 -8.6 1.75e+02 -6.2 1.00e+00 1.00e+00h 1\n", + " 41 4.8962098e-04 2.78e-04 1.07e-02 -8.6 1.35e+00 -6.6 1.00e+00 1.00e+00h 1\n", + " 42 4.8560679e-04 7.45e-01 2.20e-04 -8.6 5.57e+01 - 1.00e+00 1.00e+00h 1\n", + " 43 4.8552396e-04 1.48e+00 2.93e-07 -8.6 1.25e+01 - 1.00e+00 1.00e+00h 1\n", + " 44 4.8552248e-04 2.11e-04 1.96e-11 -8.6 7.01e-02 - 1.00e+00 1.00e+00h 1\n", + " 45 4.8552248e-04 2.91e-11 2.51e-14 -8.6 6.63e-06 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 45\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 4.8552248114450776e-04 4.8552248114450776e-04\n", + "Dual infeasibility......: 2.5059195075060174e-14 2.5059195075060174e-14\n", + "Constraint violation....: 1.4104644499482425e-11 2.9103830456733704e-11\n", + "Complementarity.........: 2.5059035596800626e-09 2.5059035596800626e-09\n", + "Overall NLP error.......: 2.5059035596800626e-09 2.5059035596800626e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 135\n", + "Number of objective gradient evaluations = 46\n", + "Number of equality constraint evaluations = 135\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 46\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 45\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.195\n", + "Total CPU secs in NLP function evaluations = 0.049\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 10950\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 6600\n", + "\n", + "Total number of variables............................: 2952\n", + " variables with only lower bounds: 150\n", + " variables with lower and upper bounds: 600\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 2950\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0677766e-03 5.63e+02 1.45e-08 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 1.2386433e-03 1.21e+03 1.53e+01 -1.0 1.37e+04 - 9.82e-01 1.00e+00h 1\n", + " 2 1.5378810e-03 1.17e+04 1.65e+01 -1.0 8.44e+03 - 2.10e-01 9.65e-02h 3\n", + " 3 1.5219384e-03 1.15e+04 1.43e+02 -1.0 4.28e+02 -4.0 8.32e-01 2.50e-01h 3\n", + " 4 1.4766018e-03 1.27e+04 1.65e+02 -1.0 4.22e+02 -4.5 7.83e-01 1.12e-01h 4\n", + " 5 1.2351015e-03 6.46e+03 1.26e+02 -1.0 3.04e+02 -5.0 9.92e-01 1.00e+00h 1\n", + " 6 1.0582927e-03 1.79e+02 3.10e+01 -1.0 2.69e+02 -5.4 1.00e+00 1.00e+00h 1\n", + " 7 1.0490172e-03 3.18e+01 9.91e-01 -1.0 1.85e+01 -5.9 1.00e+00 1.00e+00h 1\n", + " 8 1.0555296e-03 5.85e+01 8.23e-02 -1.7 1.74e+01 -6.4 1.00e+00 1.00e+00h 1\n", + " 9 1.1004866e-03 3.29e+03 1.25e-01 -1.7 1.97e+02 -6.9 1.00e+00 5.00e-01h 2\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 8.8032955e-04 3.07e+03 1.03e-01 -1.7 5.68e+02 - 1.00e+00 2.50e-01h 3\n", + " 11 8.8045892e-04 3.22e+03 1.65e-01 -1.7 3.98e+01 -3.7 1.73e-01 5.73e-03h 6\n", + " 12 8.8051975e-04 3.22e+03 1.60e-01 -1.7 3.38e+01 -4.2 4.83e-01 4.56e-03h 8\n", + " 13 8.8057935e-04 3.22e+03 1.49e-01 -1.7 3.75e+01 -3.8 1.00e+00 4.07e-03h 8\n", + " 14 8.8060503e-04 3.21e+03 1.34e-01 -1.7 1.88e+01 -3.4 5.19e-01 3.98e-03h 8\n", + " 15 8.8061557e-04 3.21e+03 1.25e-01 -1.7 3.97e+01 -2.9 1.00e+00 8.65e-04h 9\n", + " 16 8.8060713e-04 3.21e+03 1.52e-01 -1.7 2.85e+01 -3.4 3.45e-01 6.44e-04h 10\n", + " 17 8.7770168e-04 2.94e+03 1.74e+00 -1.7 5.61e+01 -3.9 1.00e+00 1.25e-01h 4\n", + " 18 8.6121257e-04 2.48e+03 8.19e+00 -1.7 4.27e+01 -4.4 1.00e+00 1.00e+00h 1\n", + " 19 8.6095409e-04 1.82e+03 3.63e+00 -1.7 2.43e+00 -3.0 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 8.5999505e-04 4.58e+02 5.98e+00 -1.7 1.84e+00 -3.5 1.00e+00 1.00e+00h 1\n", + " 21 8.5844790e-04 4.87e+01 5.64e-01 -1.7 6.05e+00 -4.0 1.00e+00 1.00e+00H 1\n", + " 22 8.5805152e-04 7.17e+00 1.51e-01 -1.7 1.29e+00 -4.5 1.00e+00 1.00e+00h 1\n", + " 23 8.5806689e-04 4.14e-02 1.39e-03 -2.5 4.48e-02 -4.9 1.00e+00 1.00e+00h 1\n", + " 24 7.5665824e-04 2.46e+00 4.37e-04 -3.8 8.97e+01 - 1.00e+00 1.00e+00h 1\n", + " 25 5.9297453e-04 1.27e+01 1.44e-05 -3.8 2.37e+02 - 1.00e+00 1.00e+00h 1\n", + " 26 5.9393463e-04 4.23e+00 1.51e-07 -3.8 5.47e+00 - 1.00e+00 1.00e+00h 1\n", + " 27 5.9392799e-04 7.49e-05 1.50e-09 -3.8 2.44e-02 - 1.00e+00 1.00e+00h 1\n", + " 28 5.6387763e-04 8.78e+00 1.24e-05 -5.7 1.30e+02 - 1.00e+00 1.00e+00h 1\n", + " 29 5.2791567e-04 2.29e+04 9.63e-04 -5.7 1.95e+02 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30 5.2972980e-04 2.25e+04 9.48e-04 -5.7 5.59e+02 - 1.00e+00 1.56e-02h 7\n", + " 31 5.2973343e-04 2.25e+04 9.48e-04 -5.7 5.68e+02 - 1.00e+00 3.05e-05h 16\n", + " 32 8.2329598e-04 8.66e+03 1.13e-03 -5.7 5.55e+02 - 1.00e+00 1.00e+00s 22\n", + " 33r 8.2329598e-04 8.66e+03 9.99e+02 1.5 0.00e+00 - 0.00e+00 0.00e+00R 1\n", + " 34r 7.9209116e-04 7.01e+03 9.97e+02 1.5 3.00e+04 - 6.19e-03 9.93e-04f 1\n", + " 35r 7.5544383e-04 6.51e+03 9.96e+02 0.8 1.01e+01 2.0 5.97e-01 3.67e-02f 1\n", + " 36r 7.9027035e-04 4.83e+03 9.90e+02 0.8 7.57e+03 - 5.80e-03 4.85e-03f 1\n", + " 37r 7.8455905e-04 3.81e+03 9.84e+02 0.8 3.89e+03 - 5.64e-03 5.17e-03f 1\n", + " 38r 7.6578409e-04 3.71e+03 9.57e+02 0.8 3.58e+00 2.4 1.00e+00 1.88e-02f 1\n", + " 39r 7.1088777e-04 3.24e+03 9.74e+02 0.8 1.37e+00 2.9 1.00e+00 2.35e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 40r 7.4188221e-04 1.70e+03 9.51e+02 0.8 2.44e+03 - 2.35e-02 2.48e-02f 1\n", + " 41r 7.5471085e-04 1.65e+03 9.03e+02 0.8 3.80e+03 - 5.06e-02 3.35e-03f 1\n", + " 42r 9.4431463e-04 1.84e+03 8.89e+02 0.8 1.44e+03 - 1.56e-02 8.66e-02f 1\n", + " 43r 1.0046477e-03 1.81e+03 1.10e+03 0.8 7.94e+02 - 1.92e-01 1.77e-02f 1\n", + " 44r 9.5162959e-04 1.72e+03 1.06e+03 0.8 7.88e+02 - 7.27e-02 4.79e-02f 1\n", + " 45r 9.3273350e-04 1.64e+03 9.86e+02 0.8 7.35e+02 - 1.91e-01 5.05e-02f 1\n", + " 46r 1.1071537e-03 1.45e+03 8.69e+02 0.8 5.68e+02 - 1.26e-01 1.15e-01f 1\n", + " 47r 1.3530616e-03 1.28e+03 6.56e+02 0.8 9.35e+02 - 2.45e-01 1.43e-01f 1\n", + " 48r 1.3628911e-03 1.27e+03 6.48e+02 0.8 1.67e+03 - 8.90e-02 5.90e-03f 1\n", + " 49r 1.2626360e-03 1.03e+03 7.49e+02 0.8 6.94e+02 - 7.00e-01 2.08e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 50r 1.1913421e-03 9.63e+02 9.31e+02 0.8 6.80e+02 - 1.00e+00 6.90e-02f 1\n", + " 51r 6.6266079e-04 4.64e+02 6.04e+01 0.8 2.51e+02 - 1.00e+00 9.26e-01f 1\n", + " 52r 6.6241288e-04 1.72e+02 3.34e+02 -0.6 1.42e-01 3.3 1.00e+00 6.30e-01f 1\n", + " 53r 6.6378543e-04 4.22e+01 1.71e+02 -0.6 2.35e-01 2.8 1.00e+00 7.62e-01f 1\n", + " 54r 6.5368318e-04 1.48e+01 6.63e+01 -0.6 2.24e-01 2.3 8.34e-01 7.31e-01f 1\n", + " 55r 6.5247649e-04 1.48e+01 5.37e+02 -0.6 6.45e-01 1.8 9.95e-01 4.56e-01f 1\n", + " 56r 6.4895541e-04 1.72e+01 8.39e+02 -0.6 1.61e+00 1.4 1.00e+00 1.77e-01f 1\n", + " 57r 6.4081200e-04 3.77e+01 1.06e+03 -0.6 5.02e+00 0.9 7.82e-01 1.31e-01f 1\n", + " 58r 6.7359020e-04 5.24e+01 1.00e+03 -0.6 5.87e+03 - 6.77e-02 1.88e-02f 1\n", + " 59r 6.6450297e-04 5.10e+01 1.17e+03 -0.6 2.23e+03 - 6.64e-01 5.03e-02f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 60r 6.5378620e-04 4.83e+01 1.54e+03 -0.6 9.69e+02 - 7.06e-01 7.03e-02f 1\n", + " 61r 6.1059197e-04 5.82e+01 4.80e+02 -0.6 5.24e+02 - 1.00e+00 5.04e-01f 1\n", + " 62r 6.0576333e-04 9.20e+01 1.54e+02 -0.6 2.80e+02 - 1.00e+00 7.93e-01f 1\n", + " 63r 6.0345577e-04 1.35e+02 1.30e+02 -0.6 3.00e+02 - 1.00e+00 6.35e-01f 1\n", + " 64r 6.0579638e-04 8.67e+00 2.49e+00 -0.6 1.75e+02 - 1.00e+00 1.00e+00H 1\n", + " 65r 6.0443224e-04 1.23e+01 6.17e-01 -2.0 4.95e+01 - 1.00e+00 9.86e-01f 1\n", + " 66r 6.0419074e-04 9.54e-03 1.24e+00 -2.0 1.90e+01 - 1.00e+00 1.00e+00f 1\n", + " 67r 6.0358870e-04 1.06e-03 1.53e-01 -2.0 3.94e+00 - 1.00e+00 1.00e+00H 1\n", + " 68r 6.0348593e-04 1.16e-05 3.91e-02 -3.0 2.59e-01 - 1.00e+00 1.00e+00f 1\n", + " 69r 6.0348566e-04 7.46e-06 1.47e-02 -4.5 5.94e-02 - 1.00e+00 1.00e+00f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 70r 6.0348492e-04 3.17e-08 1.31e-05 -4.5 2.14e-02 - 1.00e+00 1.00e+00f 1\n", + " 71 5.2477981e-04 2.02e+03 4.70e-04 -5.7 3.67e+02 - 1.00e+00 1.00e+00h 1\n", + " 72 5.2174319e-04 4.07e+00 1.82e-05 -5.7 3.96e+01 - 1.00e+00 1.00e+00h 1\n", + " 73 5.2120375e-04 3.25e+00 2.31e-06 -5.7 7.98e+01 - 1.00e+00 1.00e+00h 1\n", + " 74 5.2120888e-04 4.72e-03 2.02e-09 -5.7 1.22e+00 - 1.00e+00 1.00e+00h 1\n", + " 75 5.2103883e-04 6.40e+00 3.90e-07 -8.6 7.10e+01 - 9.95e-01 1.00e+00h 1\n", + " 76 5.2103457e-04 8.42e-03 5.17e-10 -8.6 1.23e+00 - 1.00e+00 1.00e+00h 1\n", + " 77 5.2103455e-04 1.05e-08 2.51e-14 -8.6 1.18e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 77\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 5.2103454872737373e-04 5.2103454872737373e-04\n", + "Dual infeasibility......: 2.5059195075060174e-14 2.5059195075060174e-14\n", + "Constraint violation....: 3.6366718714863869e-11 1.0462827049195768e-08\n", + "Complementarity.........: 2.5059035633214610e-09 2.5059035633214610e-09\n", + "Overall NLP error.......: 2.5059035633214610e-09 1.0462827049195768e-08\n", + "\n", + "\n", + "Number of objective function evaluations = 198\n", + "Number of objective gradient evaluations = 42\n", + "Number of equality constraint evaluations = 198\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 79\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 77\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.324\n", + "Total CPU secs in NLP function evaluations = 0.080\n", + "\n", + "EXIT: Optimal Solution Found.\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
fs.properties.tau[benzene,toluene]fs.properties.tau[toluene,benzene]
0-0.8816491.364704
1-0.9146791.440070
2-0.9506061.528018
3-0.8250951.254646
\n", + "
" + ], + "text/plain": [ + " fs.properties.tau[benzene,toluene] fs.properties.tau[toluene,benzene]\n", + "0 -0.881649 1.364704\n", + "1 -0.914679 1.440070\n", + "2 -0.950606 1.528018\n", + "3 -0.825095 1.254646" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "bootstrap_theta_new = pest_new.theta_est_bootstrap(4)\n", + "display(bootstrap_theta_new)" ] } ], From 9cf8c2f4bb0358882679bdc6c4c07b1d32d025fe Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Thu, 11 Jun 2026 00:10:39 -0400 Subject: [PATCH 08/23] Reran notebooks and ran black --- ...er_estimation_nrtl_using_state_block.ipynb | 61 +- ...ter_estimation_nrtl_using_unit_model.ipynb | 830 ++++++++++-------- .../properties/parameter_estimation_pr.ipynb | 572 ++++++------ 3 files changed, 783 insertions(+), 680 deletions(-) diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block.ipynb index 5dcc0ddc..cb184a96 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block.ipynb @@ -217,7 +217,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 7, "metadata": { "tags": [ "solution" @@ -289,7 +289,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 8, "metadata": { "tags": [ "testing" @@ -326,7 +326,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 9, "metadata": {}, "outputs": [ { @@ -688,7 +688,7 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 10, "metadata": {}, "outputs": [ { @@ -738,7 +738,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 11, "metadata": { "tags": [ "exercise" @@ -751,7 +751,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 12, "metadata": { "tags": [ "solution" @@ -782,7 +782,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 13, "metadata": { "tags": [] }, @@ -1198,7 +1198,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 14, "metadata": { "tags": [ "exercise" @@ -1217,7 +1217,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 15, "metadata": { "tags": [ "solution" @@ -1242,7 +1242,7 @@ }, { "cell_type": "code", - "execution_count": 48, + "execution_count": 16, "metadata": {}, "outputs": [], "source": [ @@ -1350,13 +1350,18 @@ }, { "cell_type": "code", - "execution_count": 49, + "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ + "WARNING: DEPRECATED: You're using the deprecated parmest interface\n", + "(model_function, data, theta_names). This interface will be removed in a\n", + "future release, please update to the new parmest interface using experiment\n", + "lists. (deprecated in 6.7.2) (called from /Applications/anaconda3/envs/idaes-\n", + "examples-dev-py313-macmini/lib/python3.13/functools.py:974)\n", "Ipopt 3.13.2: \n", "\n", "******************************************************************************\n", @@ -1445,7 +1450,7 @@ }, { "cell_type": "code", - "execution_count": 45, + "execution_count": 18, "metadata": {}, "outputs": [], "source": [ @@ -1457,7 +1462,7 @@ }, { "cell_type": "code", - "execution_count": 46, + "execution_count": 19, "metadata": {}, "outputs": [ { @@ -1548,7 +1553,7 @@ "Number of equality constraint Jacobian evaluations = 27\n", "Number of inequality constraint Jacobian evaluations = 0\n", "Number of Lagrangian Hessian evaluations = 26\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.034\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.035\n", "Total CPU secs in NLP function evaluations = 0.009\n", "\n", "EXIT: Optimal Solution Found.\n" @@ -1562,7 +1567,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 20, "metadata": { "tags": [ "testing" @@ -1585,7 +1590,7 @@ }, { "cell_type": "code", - "execution_count": 50, + "execution_count": 21, "metadata": {}, "outputs": [ { @@ -1610,14 +1615,14 @@ }, { "cell_type": "code", - "execution_count": 52, + "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "The SSE at the optimal solution is 0.000000\n", + "The SSE at the optimal solution is 0.000507\n", "\n", "The values for the parameters are as follows:\n", "fs.properties.tau[benzene,toluene] = -0.8987550041842163\n", @@ -1626,7 +1631,7 @@ } ], "source": [ - "print(\"The SSE at the optimal solution is %0.6f\" % (obj_value_new * 1e-4))\n", + "print(\"The SSE at the optimal solution is %0.6f\" % (obj_value_new))\n", "print()\n", "print(\"The values for the parameters are as follows:\")\n", "for k, v in parameters_new.items():\n", @@ -1652,23 +1657,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Pyomo's `parmest` tool allows for bootstrapping where the parameter estimation is repeated over `n` samples with resampling from the original data set. Parameter estimation with bootstrap resampling can be used to identify confidence regions around each parameter estimate. This analysis can be slow given the increased number of model instances that need to be solved. Please refer to https://pyomo.readthedocs.io/en/stable/contributed_packages/parmest/driver.html for more details. \n", - "\n", - "For the example above, the bootstrapping can be run by uncommenting the code in the following cell:" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [], - "source": [ - "# Run parameter estimation using bootstrap resample of the data (10 samples),\n", - "# plot results along with confidence regions\n", - "\n", - "# Uncomment the following code:\n", - "# bootstrap_theta = pest.theta_est_bootstrap(4)\n", - "# display(bootstrap_theta)" + "Pyomo's `parmest` tool allows for bootstrapping where the parameter estimation is repeated over `n` samples with resampling from the original data set. Parameter estimation with bootstrap resampling can be used to identify confidence regions around each parameter estimate. This analysis can be slow given the increased number of model instances that need to be solved. Please refer to https://pyomo.readthedocs.io/en/stable/contributed_packages/parmest/driver.html for more details. " ] } ], diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb index 423476b3..315202cb 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb @@ -1043,8 +1043,8 @@ "Number of equality constraint Jacobian evaluations = 12\n", "Number of inequality constraint Jacobian evaluations = 0\n", "Number of Lagrangian Hessian evaluations = 11\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.045\n", - "Total CPU secs in NLP function evaluations = 0.010\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.048\n", + "Total CPU secs in NLP function evaluations = 0.012\n", "\n", "EXIT: Optimal Solution Found.\n" ] @@ -1072,7 +1072,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 17, "metadata": {}, "outputs": [ { @@ -1227,8 +1227,8 @@ "Number of equality constraint Jacobian evaluations = 85\n", "Number of inequality constraint Jacobian evaluations = 0\n", "Number of Lagrangian Hessian evaluations = 84\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.346\n", - "Total CPU secs in NLP function evaluations = 0.097\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.341\n", + "Total CPU secs in NLP function evaluations = 0.092\n", "\n", "EXIT: Optimal Solution Found.\n" ] @@ -1385,34 +1385,34 @@ " inequality constraints with only upper bounds: 0\n", "\n", "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.6536093e+01 5.63e+02 8.94e-05 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.9655429e+00 1.55e+03 7.54e+01 -1.0 1.37e+04 - 9.45e-01 1.00e+00h 1\n", - " 2 5.2504754e+00 1.81e+02 4.22e+02 -1.0 5.26e+02 -4.0 9.90e-01 1.00e+00h 1\n", - " 3 5.2261387e+00 9.62e-01 3.18e+01 -1.0 9.00e+01 -4.5 9.92e-01 1.00e+00h 1\n", - " 4 5.0173696e+00 1.34e+03 6.28e+01 -1.0 1.56e+03 - 1.00e+00 1.00e+00f 1\n", - " 5 5.0148066e+00 1.52e+02 7.82e-01 -1.0 1.12e+03 - 1.00e+00 1.00e+00h 1\n", - " 6 4.9235551e+00 1.18e+03 5.90e-01 -1.7 1.52e+02 - 1.00e+00 1.00e+00h 1\n", - " 7 4.9223558e+00 1.18e+02 1.87e-01 -1.7 3.27e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 4.9190596e+00 8.79e+00 3.32e-02 -1.7 2.73e+01 - 1.00e+00 1.00e+00h 1\n", - " 9 4.9166308e+00 7.38e+00 4.12e-03 -2.5 1.72e+01 - 1.00e+00 1.00e+00h 1\n", + " 0 5.4201486e+01 5.41e+02 1.18e-04 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.7673838e+00 1.41e+03 6.59e+01 -1.0 1.32e+04 - 9.54e-01 1.00e+00h 1\n", + " 2 4.9120868e+00 6.82e+01 2.88e+02 -1.0 4.05e+02 -4.0 9.90e-01 1.00e+00h 1\n", + " 3 4.9155706e+00 8.04e+01 2.69e+02 -1.0 1.21e+03 - 9.92e-01 6.25e-02h 5\n", + " 4 4.9153937e+00 2.36e-01 1.11e+01 -1.0 6.25e+00 -4.5 1.00e+00 1.00e+00h 1\n", + " 5 4.8229519e+00 3.75e+02 2.02e+00 -1.0 9.74e+02 - 1.00e+00 1.00e+00f 1\n", + " 6 4.8411927e+00 4.77e+00 2.98e-01 -1.0 7.21e+02 - 1.00e+00 1.00e+00h 1\n", + " 7 4.7910663e+00 1.37e+02 5.72e-02 -1.7 7.95e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 4.7919173e+00 2.79e+00 1.40e-03 -1.7 6.83e+00 - 1.00e+00 1.00e+00h 1\n", + " 9 4.7900483e+00 4.41e+00 2.03e-03 -3.8 1.67e+01 - 1.00e+00 1.00e+00h 1\n", "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 4.9165551e+00 8.08e-02 3.52e-04 -3.8 2.20e+00 - 1.00e+00 1.00e+00h 1\n", - " 11 4.9165547e+00 6.24e-04 7.79e-06 -5.7 1.62e-01 - 1.00e+00 1.00e+00h 1\n", - " 12 4.9165547e+00 1.29e-07 1.85e-09 -8.6 2.35e-03 - 1.00e+00 1.00e+00h 1\n", + " 10 4.7900437e+00 3.00e-03 1.57e-06 -3.8 2.23e-01 - 1.00e+00 1.00e+00h 1\n", + " 11 4.7900435e+00 2.26e-04 1.06e-07 -5.7 1.22e-01 - 1.00e+00 1.00e+00h 1\n", + " 12 4.7900435e+00 3.37e-08 1.59e-11 -8.6 1.51e-03 - 1.00e+00 1.00e+00h 1\n", "\n", "Number of Iterations....: 12\n", "\n", " (scaled) (unscaled)\n", - "Objective...............: 4.9165546791664232e+00 4.9165546791664232e+00\n", - "Dual infeasibility......: 1.8546585645584926e-09 1.8546585645584926e-09\n", - "Constraint violation....: 4.4904551981997418e-10 1.2922100722789764e-07\n", - "Complementarity.........: 2.5084427386564811e-09 2.5084427386564811e-09\n", - "Overall NLP error.......: 2.5084427386564811e-09 1.2922100722789764e-07\n", + "Objective...............: 4.7900435100207801e+00 4.7900435100207801e+00\n", + "Dual infeasibility......: 1.5883423092616088e-11 1.5883423092616088e-11\n", + "Constraint violation....: 1.1714230951825415e-10 3.3716787584125996e-08\n", + "Complementarity.........: 2.5073461565202905e-09 2.5073461565202905e-09\n", + "Overall NLP error.......: 2.5073461565202905e-09 3.3716787584125996e-08\n", "\n", "\n", - "Number of objective function evaluations = 13\n", + "Number of objective function evaluations = 18\n", "Number of objective gradient evaluations = 13\n", - "Number of equality constraint evaluations = 13\n", + "Number of equality constraint evaluations = 18\n", "Number of inequality constraint evaluations = 0\n", "Number of equality constraint Jacobian evaluations = 13\n", "Number of inequality constraint Jacobian evaluations = 0\n", @@ -1458,38 +1458,41 @@ " inequality constraints with only upper bounds: 0\n", "\n", "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 4.7550067e+01 5.41e+02 1.18e-04 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 3.8782296e+00 1.55e+03 7.05e+01 -1.0 1.32e+04 - 9.58e-01 1.00e+00h 1\n", - " 2 4.0280011e+00 1.20e+02 2.62e+02 -1.0 2.91e+02 -4.0 9.90e-01 1.00e+00h 1\n", - " 3 4.0213935e+00 4.77e-01 1.58e+01 -1.0 1.15e+01 -4.5 9.92e-01 1.00e+00h 1\n", - " 4 4.0659444e+00 1.17e+02 1.86e+00 -1.0 4.88e+02 - 1.00e+00 1.00e+00h 1\n", - " 5 4.0569748e+00 4.50e-02 4.81e-03 -1.0 2.73e+01 - 1.00e+00 1.00e+00h 1\n", - " 6 4.0151231e+00 1.14e+02 6.02e-02 -2.5 3.63e+02 - 1.00e+00 1.00e+00h 1\n", - " 7 4.0145579e+00 1.46e+00 9.55e-04 -2.5 2.10e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 4.0144812e+00 4.75e-02 2.56e-05 -3.8 8.88e+00 - 1.00e+00 1.00e+00h 1\n", - " 9 4.0144810e+00 1.47e-04 8.01e-08 -5.7 4.88e-01 - 1.00e+00 1.00e+00h 1\n", + " 0 7.9385398e+01 5.63e+02 1.41e-04 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 3.6732844e+00 1.51e+03 7.25e+01 -1.0 1.37e+04 - 9.30e-01 1.00e+00h 1\n", + " 2 3.8447731e+00 2.72e+02 8.62e+02 -1.0 8.03e+02 -4.0 9.90e-01 1.00e+00h 1\n", + " 3 3.8455364e+00 2.83e+02 8.25e+02 -1.0 1.47e+04 - 9.91e-01 3.12e-02h 6\n", + " 4 3.7510500e+00 2.19e+00 7.88e+01 -1.0 4.17e+02 -4.5 1.00e+00 1.00e+00h 1\n", + " 5 4.0251556e+00 1.04e+02 2.95e+02 -1.0 9.58e+02 - 1.00e+00 1.00e+00H 1\n", + " 6 3.7747250e+00 5.10e+02 2.92e+00 -1.0 1.29e+02 - 1.00e+00 1.00e+00h 1\n", + " 7 3.7456697e+00 4.11e+00 1.08e-01 -1.0 3.92e+02 - 1.00e+00 1.00e+00h 1\n", + " 8 3.6977549e+00 1.24e+02 1.72e-01 -2.5 3.61e+02 - 9.99e-01 1.00e+00h 1\n", + " 9 3.7086634e+00 1.56e+01 5.90e-02 -2.5 1.44e+02 - 1.00e+00 1.00e+00h 1\n", "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 4.0144810e+00 2.42e-08 1.32e-11 -8.6 6.15e-03 - 1.00e+00 1.00e+00h 1\n", + " 10 3.7083820e+00 1.78e-02 2.33e-05 -2.5 1.22e+00 - 1.00e+00 1.00e+00h 1\n", + " 11 3.7083472e+00 6.16e-02 2.81e-05 -3.8 9.06e+00 - 1.00e+00 1.00e+00h 1\n", + " 12 3.7083469e+00 1.70e-04 7.71e-08 -5.7 4.93e-01 - 1.00e+00 1.00e+00h 1\n", + " 13 3.7083469e+00 2.81e-08 1.28e-11 -8.6 6.19e-03 - 1.00e+00 1.00e+00h 1\n", "\n", - "Number of Iterations....: 10\n", + "Number of Iterations....: 13\n", "\n", " (scaled) (unscaled)\n", - "Objective...............: 4.0144809745145293e+00 4.0144809745145293e+00\n", - "Dual infeasibility......: 1.3235991345144155e-11 1.3235991345144155e-11\n", - "Constraint violation....: 8.3962104404275412e-11 2.4156179279088974e-08\n", - "Complementarity.........: 2.5071885683769132e-09 2.5071885683769132e-09\n", - "Overall NLP error.......: 2.5071885683769132e-09 2.4156179279088974e-08\n", + "Objective...............: 3.7083468741502537e+00 3.7083468741502537e+00\n", + "Dual infeasibility......: 1.2842477470779329e-11 1.2842477470779329e-11\n", + "Constraint violation....: 9.7618591265211775e-11 2.8114300221204758e-08\n", + "Complementarity.........: 2.5072445933176966e-09 2.5072445933176966e-09\n", + "Overall NLP error.......: 2.5072445933176966e-09 2.8114300221204758e-08\n", "\n", "\n", - "Number of objective function evaluations = 11\n", - "Number of objective gradient evaluations = 11\n", - "Number of equality constraint evaluations = 11\n", + "Number of objective function evaluations = 22\n", + "Number of objective gradient evaluations = 14\n", + "Number of equality constraint evaluations = 22\n", "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 11\n", + "Number of equality constraint Jacobian evaluations = 14\n", "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 10\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.041\n", - "Total CPU secs in NLP function evaluations = 0.008\n", + "Number of Lagrangian Hessian evaluations = 13\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.051\n", + "Total CPU secs in NLP function evaluations = 0.012\n", "\n", "EXIT: Optimal Solution Found.\n", "Ipopt 3.13.2: \n", @@ -1529,27 +1532,27 @@ " inequality constraints with only upper bounds: 0\n", "\n", "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 7.7751928e+01 5.63e+02 1.77e-04 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 3.6258012e+00 1.56e+03 7.05e+01 -1.0 1.37e+04 - 9.35e-01 1.00e+00h 1\n", - " 2 3.8259201e+00 1.17e+02 7.78e+02 -1.0 1.07e+03 -4.0 9.90e-01 1.00e+00h 1\n", - " 3 3.7935297e+00 2.61e-01 3.68e+01 -1.0 9.46e+01 -4.5 9.92e-01 1.00e+00h 1\n", - " 4 3.7581605e+00 3.00e+02 3.58e+01 -1.0 8.82e+02 - 1.00e+00 1.00e+00f 1\n", - " 5 3.7397696e+00 1.93e-01 7.15e-02 -1.0 2.41e+01 - 1.00e+00 1.00e+00h 1\n", - " 6 3.6958865e+00 9.59e+01 5.32e-02 -2.5 3.46e+02 - 1.00e+00 1.00e+00h 1\n", - " 7 3.6954293e+00 9.42e-01 6.26e-04 -2.5 1.65e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 3.6953637e+00 4.41e-02 2.49e-05 -3.8 8.65e+00 - 1.00e+00 1.00e+00h 1\n", - " 9 3.6953635e+00 1.33e-04 7.57e-08 -5.7 4.75e-01 - 1.00e+00 1.00e+00h 1\n", + " 0 6.4678342e+01 5.63e+02 1.26e-04 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.1403827e+00 1.61e+03 7.48e+01 -1.0 1.37e+04 - 9.43e-01 1.00e+00h 1\n", + " 2 4.1979019e+00 3.36e+02 5.20e+02 -1.0 4.73e+02 -4.0 9.90e-01 1.00e+00h 1\n", + " 3 4.1897805e+00 4.07e+00 5.45e+01 -1.0 1.99e+01 -4.5 9.92e-01 1.00e+00h 1\n", + " 4 4.2236487e+00 1.94e+01 1.43e+00 -1.0 1.88e+02 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2197088e+00 7.33e-02 1.51e-03 -1.0 1.39e+01 - 1.00e+00 1.00e+00h 1\n", + " 6 4.1776383e+00 9.05e+01 4.70e-02 -2.5 3.45e+02 - 1.00e+00 1.00e+00h 1\n", + " 7 4.1770010e+00 7.87e-01 5.51e-04 -2.5 1.54e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 4.1769404e+00 4.33e-02 2.37e-05 -3.8 8.71e+00 - 1.00e+00 1.00e+00h 1\n", + " 9 4.1769400e+00 1.29e-04 7.07e-08 -5.7 4.78e-01 - 1.00e+00 1.00e+00h 1\n", "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 3.6953635e+00 2.17e-08 1.24e-11 -8.6 5.97e-03 - 1.00e+00 1.00e+00h 1\n", + " 10 4.1769400e+00 2.12e-08 1.16e-11 -8.6 6.00e-03 - 1.00e+00 1.00e+00h 1\n", "\n", "Number of Iterations....: 10\n", "\n", " (scaled) (unscaled)\n", - "Objective...............: 3.6953634629145982e+00 3.6953634629145982e+00\n", - "Dual infeasibility......: 1.2431270208802497e-11 1.2431270208802497e-11\n", - "Constraint violation....: 7.5414155220948578e-11 2.1696905605494976e-08\n", - "Complementarity.........: 2.5071430842635661e-09 2.5071430842635661e-09\n", - "Overall NLP error.......: 2.5071430842635661e-09 2.1696905605494976e-08\n", + "Objective...............: 4.1769399649268752e+00 4.1769399649268752e+00\n", + "Dual infeasibility......: 1.1596265104711192e-11 1.1596265104711192e-11\n", + "Constraint violation....: 7.3492131144224205e-11 2.1158484742045403e-08\n", + "Complementarity.........: 2.5071334548934459e-09 2.5071334548934459e-09\n", + "Overall NLP error.......: 2.5071334548934459e-09 2.1158484742045403e-08\n", "\n", "\n", "Number of objective function evaluations = 11\n", @@ -1600,40 +1603,39 @@ " inequality constraints with only upper bounds: 0\n", "\n", "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 6.8031043e+01 5.63e+02 1.14e-04 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 5.0185338e+00 1.55e+03 7.39e+01 -1.0 1.37e+04 - 9.42e-01 1.00e+00h 1\n", - " 2 5.0608118e+00 1.78e+02 5.15e+02 -1.0 6.27e+02 -4.0 9.90e-01 1.00e+00h 1\n", - " 3 5.0653499e+00 1.54e+00 4.04e+02 -1.0 2.54e+01 -4.5 9.92e-01 1.00e+00h 1\n", - " 4 5.0589066e+00 1.79e-02 1.06e+01 -1.0 1.47e+01 -5.0 1.00e+00 1.00e+00h 1\n", - " 5 5.0361352e+00 1.17e+02 1.40e+00 -1.0 5.48e+02 - 1.00e+00 1.00e+00f 1\n", - " 6 5.0407158e+00 1.43e+00 2.51e-02 -1.0 2.24e+01 - 1.00e+00 1.00e+00h 1\n", - " 7 4.9971707e+00 9.71e+01 1.60e-01 -2.5 3.48e+02 - 1.00e+00 1.00e+00h 1\n", - " 8 5.0177775e+00 1.28e+01 5.58e-02 -2.5 1.67e+02 - 1.00e+00 1.00e+00h 1\n", - " 9 5.0175879e+00 1.24e-02 2.99e-05 -2.5 1.30e+00 - 1.00e+00 1.00e+00h 1\n", + " 0 5.0571322e+01 5.63e+02 1.24e-04 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.8510547e+00 1.63e+03 7.35e+01 -1.0 1.37e+04 - 9.58e-01 1.00e+00h 1\n", + " 2 4.9028623e+00 1.65e+02 3.29e+02 -1.0 3.80e+02 -4.0 9.90e-01 1.00e+00h 1\n", + " 3 4.8974465e+00 8.69e-01 2.74e+01 -1.0 1.46e+01 -4.5 9.92e-01 1.00e+00h 1\n", + " 4 4.9435751e+00 5.44e+01 1.70e+00 -1.0 3.05e+02 - 1.00e+00 1.00e+00h 1\n", + " 5 4.9400183e+00 1.14e-02 4.72e-02 -1.0 6.32e+00 - 1.00e+00 1.00e+00h 1\n", + " 6 4.9022807e+00 4.38e+01 1.86e+00 -2.5 2.05e+02 - 1.00e+00 1.00e+00h 1\n", + " 7 4.8938710e+00 9.79e+00 1.17e+00 -2.5 1.68e+02 - 1.00e+00 1.00e+00h 1\n", + " 8 4.8938840e+00 5.24e-03 9.38e-05 -2.5 7.99e-01 - 1.00e+00 1.00e+00h 1\n", + " 9 4.8938537e+00 5.00e-02 3.64e-05 -3.8 8.98e+00 - 1.00e+00 1.00e+00h 1\n", "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 5.0175562e+00 5.25e-02 3.70e-05 -3.8 8.96e+00 - 1.00e+00 1.00e+00h 1\n", - " 11 5.0175560e+00 1.45e-04 1.02e-07 -5.7 4.86e-01 - 1.00e+00 1.00e+00h 1\n", - " 12 5.0175560e+00 2.41e-08 1.70e-11 -8.6 6.12e-03 - 1.00e+00 1.00e+00h 1\n", + " 10 4.8938533e+00 1.39e-04 1.01e-07 -5.7 4.88e-01 - 1.00e+00 1.00e+00h 1\n", + " 11 4.8938533e+00 2.30e-08 1.67e-11 -8.6 6.13e-03 - 1.00e+00 1.00e+00h 1\n", "\n", - "Number of Iterations....: 12\n", + "Number of Iterations....: 11\n", "\n", " (scaled) (unscaled)\n", - "Objective...............: 5.0175559693199334e+00 5.0175559693199334e+00\n", - "Dual infeasibility......: 1.6954380424451648e-11 1.6954380424451648e-11\n", - "Constraint violation....: 8.3709206499443261e-11 2.4097971618175503e-08\n", - "Complementarity.........: 2.5071793787018949e-09 2.5071793787018949e-09\n", - "Overall NLP error.......: 2.5071793787018949e-09 2.4097971618175503e-08\n", + "Objective...............: 4.8938532544429725e+00 4.8938532544429725e+00\n", + "Dual infeasibility......: 1.6721247418921680e-11 1.6721247418921680e-11\n", + "Constraint violation....: 7.9763999184061651e-11 2.2962922230362892e-08\n", + "Complementarity.........: 2.5071700149320549e-09 2.5071700149320549e-09\n", + "Overall NLP error.......: 2.5071700149320549e-09 2.2962922230362892e-08\n", "\n", "\n", - "Number of objective function evaluations = 13\n", - "Number of objective gradient evaluations = 13\n", - "Number of equality constraint evaluations = 13\n", + "Number of objective function evaluations = 12\n", + "Number of objective gradient evaluations = 12\n", + "Number of equality constraint evaluations = 12\n", "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 13\n", + "Number of equality constraint Jacobian evaluations = 12\n", "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 12\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.050\n", - "Total CPU secs in NLP function evaluations = 0.010\n", + "Number of Lagrangian Hessian evaluations = 11\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.044\n", + "Total CPU secs in NLP function evaluations = 0.009\n", "\n", "EXIT: Optimal Solution Found.\n" ] @@ -1666,23 +1668,23 @@ " \n", " \n", " 0\n", - " -0.779540\n", - " 1.167155\n", + " -0.900162\n", + " 1.400445\n", " \n", " \n", " 1\n", - " -0.939691\n", - " 1.509965\n", + " -0.913245\n", + " 1.440885\n", " \n", " \n", " 2\n", - " -0.956361\n", - " 1.545695\n", + " -0.962779\n", + " 1.562557\n", " \n", " \n", " 3\n", - " -0.941087\n", - " 1.501137\n", + " -0.953052\n", + " 1.534538\n", " \n", " \n", "\n", @@ -1690,10 +1692,10 @@ ], "text/plain": [ " fs.properties.tau[benzene,toluene] fs.properties.tau[toluene,benzene]\n", - "0 -0.779540 1.167155\n", - "1 -0.939691 1.509965\n", - "2 -0.956361 1.545695\n", - "3 -0.941087 1.501137" + "0 -0.900162 1.400445\n", + "1 -0.913245 1.440885\n", + "2 -0.962779 1.562557\n", + "3 -0.953052 1.534538" ] }, "metadata": {}, @@ -1712,7 +1714,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 22, "metadata": {}, "outputs": [ { @@ -1756,76 +1758,97 @@ " inequality constraints with only upper bounds: 0\n", "\n", "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.5039152e-03 5.63e+02 1.21e-08 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 9.9499827e-04 1.27e+03 1.56e+01 -1.0 1.37e+04 - 9.82e-01 1.00e+00h 1\n", - " 2 1.2925762e-03 1.17e+04 1.68e+01 -1.0 1.58e+04 - 1.20e-01 5.40e-02h 3\n", - " 3 1.2860094e-03 1.10e+04 4.29e+01 -1.0 4.48e+02 -4.0 8.03e-01 1.25e-01h 4\n", - " 4 8.9491243e-03 7.73e+04 5.80e+04 -1.0 3.92e+02 -4.5 8.08e-01 1.00e+00H 1\n", - " 5 2.1691585e-03 1.45e+04 4.08e+04 -1.0 6.67e+03 -5.0 9.92e-01 1.00e+00h 1\n", - " 6 6.1358159e-03 1.38e+04 3.94e+04 -1.0 1.75e+05 - 2.27e-01 3.61e-02h 4\n", - " 7 6.9284654e-03 5.65e+02 8.11e+03 -1.0 5.49e+03 -5.4 1.00e+00 1.00e+00h 1\n", - " 8 4.5286851e-03 9.90e+01 2.10e+03 -1.0 6.81e+03 -5.9 1.00e+00 1.00e+00h 1\n", - " 9 4.5000575e-03 4.26e+02 6.04e+03 -1.0 3.95e+02 -2.8 1.00e+00 1.00e+00h 1\n", + " 0 5.5931873e-03 5.63e+02 1.07e-08 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 7.2040815e-04 1.42e+03 1.66e+01 -1.0 1.37e+04 - 9.82e-01 1.00e+00h 1\n", + " 2 1.0777759e-03 1.17e+04 1.69e+01 -1.0 5.37e+03 - 3.28e-01 1.56e-01h 3\n", + " 3 1.0673210e-03 1.17e+04 1.70e+02 -1.0 4.00e+02 -4.0 8.36e-01 2.50e-01h 3\n", + " 4 7.6613103e-04 1.17e+04 1.70e+02 -1.0 6.68e+05 - 1.61e-02 4.95e-04h 6\n", + " 5 8.0909902e-04 1.16e+04 1.68e+02 -1.0 2.82e+04 - 9.90e-01 1.14e-02h 6\n", + " 6 9.0975669e-04 1.14e+04 1.65e+02 -1.0 7.82e+03 - 1.00e+00 1.56e-02h 7\n", + " 7 9.5018858e-04 1.14e+04 1.64e+02 -1.0 9.59e+03 - 1.00e+00 3.91e-03h 9\n", + " 8 9.5086210e-04 1.14e+04 1.64e+02 -1.0 9.68e+03 - 1.00e+00 6.10e-05h 15\n", + " 9 9.5101836e-04 1.14e+04 1.64e+02 -1.0 8.96e+03 - 1.00e+00 1.53e-05h 17\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 4.2672867e-03 1.08e+04 1.33e+02 -1.0 8.95e+03 - 1.00e+00 1.25e-01h 4\n", + " 11 1.8528984e-03 5.51e+02 1.85e+02 -1.0 2.19e+03 - 1.00e+00 1.00e+00h 1\n", + " 12 9.5355596e-04 2.97e+03 2.94e+01 -1.0 5.79e+03 - 1.00e+00 1.00e+00h 1\n", + " 13 1.3370336e-03 2.53e+02 3.41e+00 -1.0 5.05e+03 - 1.00e+00 1.00e+00h 1\n", + " 14 1.4965357e-03 4.03e+02 1.30e-01 -1.0 1.57e+02 - 1.00e+00 1.00e+00h 1\n", + " 15 1.4793308e-03 2.95e+01 2.10e-04 -1.0 7.18e+00 - 1.00e+00 1.00e+00h 1\n", + " 16 1.4616765e-03 1.13e-02 3.29e-04 -2.5 7.50e+00 - 1.00e+00 1.00e+00h 1\n", + " 17 1.0077106e-03 1.03e+01 3.56e-04 -3.8 2.27e+02 - 1.00e+00 1.00e+00h 1\n", + " 18 4.7653562e-04 5.81e+01 6.95e-05 -3.8 5.29e+02 - 1.00e+00 1.00e+00h 1\n", + " 19 4.7650361e-04 1.65e+00 7.96e-08 -3.8 8.32e+00 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 4.7649639e-04 1.50e-04 1.50e-09 -3.8 2.81e-02 - 1.00e+00 1.00e+00h 1\n", + " 21 4.5811965e-04 7.13e+00 9.49e-06 -5.7 1.01e+02 - 1.00e+00 1.00e+00h 1\n", + " 22 4.2418207e-04 1.57e+04 4.28e-04 -5.7 2.89e+02 - 1.00e+00 5.00e-01h 2\n", + " 23 4.3806397e-04 1.19e+04 3.36e-04 -5.7 2.07e+02 - 1.00e+00 2.50e-01h 3\n", + " 24 4.4112546e-04 1.16e+04 3.26e-04 -5.7 3.38e+02 - 1.00e+00 3.12e-02h 6\n", + " 25 4.4234498e-04 1.15e+04 3.24e-04 -5.7 5.50e+02 - 1.00e+00 7.81e-03h 8\n", + " 26 4.4320922e-04 1.14e+04 3.23e-04 -5.7 7.80e+02 - 1.00e+00 3.91e-03h 9\n", + " 27 4.4327937e-04 1.14e+04 3.23e-04 -5.7 1.02e+03 - 1.00e+00 2.44e-04h 13\n", + " 28 5.6179673e-04 1.08e+04 3.65e-04 -5.7 1.06e+03 - 1.00e+00 2.50e-01h 3\n", + " 29 5.6096848e-04 1.05e+04 1.40e+00 -5.7 4.90e+01 -4.5 1.00e+00 1.25e-01h 4\n", "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 4.2972057e-03 3.61e+02 4.86e+03 -1.0 5.30e+01 - 1.00e+00 1.00e+00h 1\n", - " 11 4.2972497e-03 7.00e+01 2.76e+01 -1.0 2.49e+00 -2.3 1.00e+00 1.00e+00h 1\n", - " 12 4.2966473e-03 6.60e+01 2.16e+01 -1.0 9.32e+00 -2.8 1.00e+00 1.25e-01h 4\n", - " 13 4.2962487e-03 6.31e+01 1.53e+01 -1.0 6.14e+00 -2.4 1.00e+00 1.25e-01h 4\n", - " 14 4.2962058e-03 6.31e+01 1.52e+01 -1.0 4.53e+01 -2.0 1.00e+00 1.95e-03h 10\n", - " 15 4.2960970e-03 6.20e+01 1.03e+01 -1.0 3.31e+00 -1.5 1.00e+00 6.25e-02h 5\n", - " 16 4.2960972e-03 6.15e+01 1.09e+01 -1.0 5.99e-01 -0.2 1.00e+00 1.56e-02h 7\n", - " 17 4.2961140e-03 6.13e+01 2.27e+01 -1.0 4.56e+00 0.2 1.00e+00 7.81e-03h 8\n", - " 18 4.2981828e-03 4.32e+02 2.13e+04 -1.0 4.65e+00 -0.3 1.00e+00 1.00e+00h 1\n", - " 19 4.3006732e-03 5.69e+01 5.77e+03 -1.0 4.58e+00 -0.7 1.00e+00 1.00e+00h 1\n", + " 30 4.1881048e-04 6.28e+03 7.11e+01 -5.7 3.62e+02 -5.0 1.00e+00 1.00e+00h 1\n", + " 31 4.1932000e-04 6.10e+03 6.27e+01 -5.7 9.12e+01 -3.6 1.00e+00 6.25e-02h 5\n", + " 32 4.1932819e-04 6.10e+03 6.25e+01 -5.7 6.94e+02 -3.2 1.32e-01 4.36e-04h 9\n", + " 33 4.1950035e-04 6.08e+03 5.90e+01 -5.7 2.63e+02 -2.8 4.27e-01 8.44e-03h 7\n", + " 34 4.2253095e-04 5.79e+03 7.09e+01 -5.7 1.83e+02 -3.3 1.00e+00 1.25e-01h 4\n", + " 35 3.5340029e-03 3.88e+02 3.15e+02 -5.7 1.41e+03 - 1.00e+00 1.00e+00h 1\n", + " 36 3.5370353e-03 3.78e+02 2.97e+02 -5.7 1.16e+03 -2.8 8.09e-01 2.69e-02h 6\n", + " 37 3.5371394e-03 3.78e+02 2.97e+02 -5.7 1.13e+03 -3.3 1.00e+00 9.77e-04h 11\n", + " 38r 3.5371394e-03 3.78e+02 9.99e+02 -0.4 0.00e+00 -3.8 0.00e+00 2.98e-07R 20\n", + " 39r 3.4772716e-03 8.90e+01 9.96e+02 -0.4 2.13e+04 - 1.87e-02 1.72e-03f 1\n", "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 4.3021197e-03 2.80e+00 4.23e+02 -1.0 3.55e+00 -1.2 1.00e+00 1.00e+00h 1\n", - " 21 4.3021593e-03 8.51e-03 8.36e+00 -1.0 8.06e-02 -1.7 1.00e+00 1.00e+00h 1\n", - " 22 4.3021706e-03 3.74e-04 1.14e-02 -1.0 2.52e-02 -2.2 1.00e+00 1.00e+00h 1\n", - " 23 4.3021715e-03 2.76e-06 1.12e-04 -2.5 2.17e-03 -2.7 1.00e+00 1.00e+00h 1\n", - " 24 4.3021715e-03 4.86e-08 4.11e-07 -3.8 3.93e-04 -3.1 1.00e+00 1.00e+00h 1\n", - " 25 3.4514655e-03 5.60e+03 2.98e-01 -5.7 1.05e+04 - 8.16e-01 1.00e+00f 1\n", - " 26 2.5110719e-03 1.01e+04 2.24e+05 -5.7 1.00e+04 -3.6 8.00e-01 1.00e+00h 1\n", - " 27 2.5218883e-03 3.02e+03 2.15e+05 -5.7 1.02e+03 -2.3 1.00e+00 1.00e+00h 1\n", - " 28 3.5653354e-03 1.83e+02 3.22e+04 -5.7 5.25e+02 - 1.00e+00 1.00e+00h 1\n", - " 29 3.5612958e-03 1.87e+00 9.97e+01 -5.7 1.92e+01 -2.8 1.00e+00 1.00e+00h 1\n", + " 40r 3.2915567e-03 4.36e+01 9.84e+02 -0.4 2.56e+04 - 4.96e-03 1.29e-02f 1\n", + " 41 4.0706315e-04 4.77e+03 5.33e-04 -5.7 4.22e+03 - 1.00e+00 1.00e+00H 1\n", + " 42 4.2691926e-04 3.94e+03 1.50e-04 -5.7 2.38e+03 - 1.00e+00 1.00e+00h 1\n", + " 43 4.2769306e-04 3.86e+03 1.42e-04 -5.7 3.68e+02 - 1.00e+00 6.25e-02h 5\n", + " 44 4.2759384e-04 3.85e+03 4.47e-02 -5.7 3.39e+01 -4.3 6.55e-01 1.29e-02h 7\n", + " 45 4.4578401e-04 3.83e+03 4.37e-02 -5.7 4.30e+03 - 1.00e+00 3.12e-02h 6\n", + " 46 4.4576474e-04 3.82e+03 4.54e-02 -5.7 2.92e+01 -4.7 5.17e-01 4.11e-03h 8\n", + " 47 4.4899517e-04 3.82e+03 4.53e-02 -5.7 7.59e+03 - 4.54e-01 1.41e-03h 9\n", + " 48 4.5019143e-04 3.82e+03 4.53e-02 -5.7 1.42e+04 - 1.00e+00 2.64e-04h 10\n", + " 49r 4.5019143e-04 3.82e+03 9.99e+02 1.1 0.00e+00 - 0.00e+00 2.64e-07R 18\n", "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30 3.5612874e-03 3.13e-06 3.49e-02 -5.7 3.82e-02 -3.2 1.00e+00 1.00e+00h 1\n", - " 31 3.5612869e-03 3.49e-10 1.52e-07 -5.7 2.32e-04 -3.7 1.00e+00 1.00e+00h 1\n", - " 32 5.6562035e-04 1.13e+04 1.06e-03 -8.6 2.57e+03 - 6.57e-01 1.00e+00f 1\n", - " 33 5.3709230e-04 6.64e+02 2.03e-04 -8.6 1.50e+03 - 8.61e-01 1.00e+00h 1\n", - " 34 5.2969341e-04 1.04e+04 3.30e-04 -8.6 5.76e+02 - 8.23e-01 1.00e+00h 1\n", - " 35 5.2731451e-04 1.14e+02 4.87e+00 -8.6 1.20e+01 -4.2 1.00e+00 1.00e+00h 1\n", - " 36 5.2540830e-04 6.23e+02 2.92e+00 -8.6 6.48e+00 -4.7 1.00e+00 1.00e+00h 1\n", - " 37 5.2516465e-04 3.58e+01 2.72e-01 -8.6 7.04e-01 -5.1 1.00e+00 1.00e+00h 1\n", - " 38 5.2511621e-04 7.11e-02 3.15e-04 -8.6 2.11e-01 -5.6 1.00e+00 1.00e+00h 1\n", - " 39 5.1942063e-04 4.85e+01 1.03e-03 -8.6 3.25e+01 - 1.00e+00 1.00e+00h 1\n", + " 50r 4.5032678e-04 3.05e+03 7.64e+02 1.1 1.33e+04 - 1.00e+00 9.92e-04f 1\n", + " 51 7.1722392e-04 1.63e+02 1.44e-03 -5.7 5.15e+03 - 1.00e+00 1.00e+00h 1\n", + " 52 6.1392121e-04 2.38e+02 1.11e-03 -5.7 5.08e+03 - 1.00e+00 2.50e-01h 3\n", + " 53 4.4508936e-04 8.17e+02 4.28e-04 -5.7 3.84e+03 - 1.00e+00 1.00e+00H 1\n", + " 54 4.4422322e-04 4.34e+01 1.66e-01 -5.7 1.54e+01 -5.2 1.00e+00 1.00e+00h 1\n", + " 55 4.4417956e-04 2.05e-02 4.15e-03 -5.7 3.49e-01 -5.7 1.00e+00 1.00e+00h 1\n", + " 56 4.4109546e-04 2.99e+01 9.89e-04 -5.7 1.18e+01 - 1.00e+00 1.00e+00h 1\n", + " 57 4.4108663e-04 1.17e-01 2.11e-06 -5.7 4.24e-02 -6.2 1.00e+00 1.00e+00h 1\n", + " 58 4.1628838e-04 3.01e+03 3.97e-04 -5.7 1.56e+02 - 1.00e+00 1.00e+00h 1\n", + " 59 4.1131149e-04 1.95e+01 6.47e-06 -5.7 7.18e+01 - 1.00e+00 1.00e+00h 1\n", "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 40 5.1940758e-04 2.00e-01 1.03e-05 -8.6 1.21e-01 -6.1 1.00e+00 1.00e+00h 1\n", - " 41 5.0706803e-04 3.93e+02 4.81e-04 -8.6 1.06e+02 - 1.00e+00 1.00e+00h 1\n", - " 42 5.0484181e-04 6.05e+01 1.92e-05 -8.6 8.11e+01 - 1.00e+00 1.00e+00h 1\n", - " 43 5.0321977e-04 6.96e-01 5.12e-06 -8.6 2.68e+02 - 1.00e+00 1.00e+00h 1\n", - " 44 5.0321816e-04 2.22e-05 6.64e-11 -8.6 2.74e-01 - 1.00e+00 1.00e+00h 1\n", - " 45 5.0321815e-04 2.83e-06 1.87e-13 -9.0 5.66e-02 - 1.00e+00 1.00e+00h 1\n", + " 60 4.1103610e-04 8.16e-01 8.43e-08 -5.7 7.11e+00 - 1.00e+00 1.00e+00h 1\n", + " 61 4.1104131e-04 1.35e-03 6.90e-11 -5.7 1.99e-01 - 1.00e+00 1.00e+00h 1\n", + " 62 4.1086346e-04 6.39e+00 3.25e-07 -8.6 1.78e+01 - 9.95e-01 1.00e+00h 1\n", + " 63 4.1086098e-04 8.07e-03 4.15e-10 -8.6 3.36e-01 - 1.00e+00 1.00e+00h 1\n", + " 64 4.1086096e-04 9.71e-09 2.51e-14 -8.6 4.29e-04 - 1.00e+00 1.00e+00h 1\n", "\n", - "Number of Iterations....: 45\n", + "Number of Iterations....: 64\n", "\n", " (scaled) (unscaled)\n", - "Objective...............: 5.0321815482191131e-04 5.0321815482191131e-04\n", - "Dual infeasibility......: 1.8736280629389788e-13 1.8736280629389788e-13\n", - "Constraint violation....: 9.8306979362164903e-09 2.8283393476158381e-06\n", - "Complementarity.........: 9.0910208979411485e-10 9.0910208979411485e-10\n", - "Overall NLP error.......: 9.8306979362164903e-09 2.8283393476158381e-06\n", + "Objective...............: 4.1086096262363253e-04 4.1086096262363253e-04\n", + "Dual infeasibility......: 2.5059086654842926e-14 2.5059086654842926e-14\n", + "Constraint violation....: 3.3686000923643029e-11 9.7061274573206902e-09\n", + "Complementarity.........: 2.5059035631905811e-09 2.5059035631905811e-09\n", + "Overall NLP error.......: 2.5059035631905811e-09 9.7061274573206902e-09\n", "\n", "\n", - "Number of objective function evaluations = 102\n", - "Number of objective gradient evaluations = 46\n", - "Number of equality constraint evaluations = 102\n", + "Number of objective function evaluations = 325\n", + "Number of objective gradient evaluations = 64\n", + "Number of equality constraint evaluations = 325\n", "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 46\n", + "Number of equality constraint Jacobian evaluations = 67\n", "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 45\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.254\n", - "Total CPU secs in NLP function evaluations = 0.047\n", + "Number of Lagrangian Hessian evaluations = 64\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.255\n", + "Total CPU secs in NLP function evaluations = 0.089\n", "\n", "EXIT: Optimal Solution Found.\n", "Ipopt 3.13.2: \n", @@ -1865,39 +1888,57 @@ " inequality constraints with only upper bounds: 0\n", "\n", "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 6.1189504e-03 5.63e+02 1.47e-08 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 1.1779279e-03 1.29e+03 1.58e+01 -1.0 1.37e+04 - 9.82e-01 1.00e+00h 1\n", - " 2 1.1340302e-03 7.48e+00 7.68e+01 -1.0 4.74e+02 -4.0 9.90e-01 1.00e+00h 1\n", - " 3 1.1339115e-03 3.96e-03 1.69e+00 -1.0 2.89e+00 -4.5 9.95e-01 1.00e+00h 1\n", - " 4 1.1342835e-03 4.81e-02 8.71e-03 -1.0 1.53e+00 -5.0 1.00e+00 1.00e+00h 1\n", - " 5 1.1343090e-03 3.64e-04 4.03e-05 -2.5 1.31e-01 -5.4 1.00e+00 1.00e+00h 1\n", - " 6 1.1342943e-03 7.15e-06 1.56e-07 -3.8 2.71e-02 -5.9 1.00e+00 1.00e+00h 1\n", - " 7 1.1342350e-03 6.98e-07 1.30e-08 -5.7 3.15e-02 -6.4 1.00e+00 1.00e+00h 1\n", - " 8 4.6007010e-04 9.99e+01 1.99e-04 -8.6 7.09e+02 - 9.51e-01 1.00e+00f 1\n", - " 9 4.5743136e-04 7.92e+00 1.58e-05 -8.6 5.32e+02 - 1.00e+00 1.00e+00h 1\n", + " 0 6.0934979e-03 5.41e+02 1.30e-08 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 1.0067953e-03 1.42e+03 1.66e+01 -1.0 1.32e+04 - 9.82e-01 1.00e+00h 1\n", + " 2 1.5505677e-03 1.16e+04 1.57e+01 -1.0 3.73e+03 - 4.42e-01 2.17e-01h 3\n", + " 3 1.5404225e-03 1.17e+04 1.57e+02 -1.0 3.44e+02 -4.0 8.63e-01 2.50e-01h 3\n", + " 4 1.5063675e-03 1.30e+04 1.74e+02 -1.0 3.09e+02 -4.5 7.38e-01 9.72e-02h 4\n", + " 5 1.3867601e-03 9.41e+03 5.71e+01 -1.0 2.41e+02 -5.0 9.93e-01 5.00e-01h 2\n", + " 6 1.0047237e-03 2.00e+02 1.02e+02 -1.0 4.19e+02 -5.4 1.00e+00 1.00e+00h 1\n", + " 7 9.8978295e-04 1.33e+02 3.63e+00 -1.0 3.67e+01 -5.9 1.00e+00 1.00e+00h 1\n", + " 8 9.8908235e-04 3.59e+01 9.39e-02 -1.0 1.98e+00 -4.6 1.00e+00 1.00e+00h 1\n", + " 9 9.9436740e-04 1.14e-01 4.95e-03 -2.5 3.95e+00 - 1.00e+00 1.00e+00h 1\n", "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 4.5742268e-04 2.23e-04 3.08e-09 -8.6 9.76e-01 - 1.00e+00 1.00e+00h 1\n", - " 11 4.5742268e-04 1.91e-08 5.98e-14 -8.6 6.14e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 11\n", + " 10 8.3472498e-04 3.29e+00 2.17e-04 -3.8 1.24e+02 - 1.00e+00 1.00e+00h 1\n", + " 11 6.2500106e-04 6.16e+01 2.16e-05 -3.8 2.93e+02 - 1.00e+00 1.00e+00h 1\n", + " 12 6.2888894e-04 1.27e+01 3.04e-07 -3.8 9.27e+00 - 1.00e+00 1.00e+00h 1\n", + " 13 6.2883670e-04 3.54e-03 1.50e-09 -3.8 8.92e-02 - 1.00e+00 1.00e+00h 1\n", + " 14 6.0274411e-04 2.18e+01 1.12e-05 -5.7 1.16e+02 - 1.00e+00 1.00e+00h 1\n", + " 15 6.0273686e-04 7.42e-02 3.05e-05 -5.7 8.73e-02 -5.1 1.00e+00 1.00e+00h 1\n", + " 16 5.8231241e-04 1.10e+03 3.14e-03 -5.7 4.46e+01 - 1.00e+00 1.00e+00h 1\n", + " 17 5.8218452e-04 5.20e+01 3.71e-03 -5.7 8.13e-01 -5.5 1.00e+00 1.00e+00h 1\n", + " 18 5.7458515e-04 1.00e+02 5.22e-03 -5.7 5.02e+01 - 1.00e+00 1.00e+00h 1\n", + " 19 5.7457556e-04 1.35e+00 1.01e-05 -5.7 5.55e-02 -6.0 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 4.9236271e-04 9.88e+03 1.23e-03 -5.7 3.68e+02 - 1.00e+00 1.00e+00h 1\n", + " 21 4.9222078e-04 4.82e+02 8.56e-05 -5.7 8.57e+01 - 1.00e+00 1.00e+00h 1\n", + " 22 4.9093828e-04 4.03e+01 1.21e-04 -5.7 2.08e+03 - 1.00e+00 1.00e+00h 1\n", + " 23 4.8572903e-04 4.33e+01 1.35e-04 -5.7 2.07e+03 - 1.00e+00 1.00e+00h 1\n", + " 24 4.8575737e-04 2.16e-01 6.61e-08 -5.7 1.22e+01 - 1.00e+00 1.00e+00h 1\n", + " 25 4.8575673e-04 2.44e-07 1.84e-11 -5.7 8.60e-02 - 1.00e+00 1.00e+00h 1\n", + " 26 4.8561981e-04 2.68e+00 2.47e-07 -8.6 6.22e+01 - 9.97e-01 1.00e+00h 1\n", + " 27 4.8561869e-04 2.40e-04 8.17e-10 -8.6 1.92e-01 - 1.00e+00 1.00e+00h 1\n", + " 28 4.8561869e-04 1.02e-10 2.51e-14 -8.6 8.03e-05 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 28\n", "\n", " (scaled) (unscaled)\n", - "Objective...............: 4.5742267974963584e-04 4.5742267974963584e-04\n", - "Dual infeasibility......: 5.9847447620240048e-14 5.9847447620240048e-14\n", - "Constraint violation....: 6.6461569389890306e-11 1.9121216610074043e-08\n", - "Complementarity.........: 2.5059035597140184e-09 2.5059035597140184e-09\n", - "Overall NLP error.......: 2.5059035597140184e-09 1.9121216610074043e-08\n", + "Objective...............: 4.8561869050371405e-04 4.8561869050371405e-04\n", + "Dual infeasibility......: 2.5059195075060174e-14 2.5059195075060174e-14\n", + "Constraint violation....: 1.4104644499482425e-11 1.0186340659856796e-10\n", + "Complementarity.........: 2.5059035596971493e-09 2.5059035596971493e-09\n", + "Overall NLP error.......: 2.5059035596971493e-09 2.5059035596971493e-09\n", "\n", "\n", - "Number of objective function evaluations = 12\n", - "Number of objective gradient evaluations = 12\n", - "Number of equality constraint evaluations = 12\n", + "Number of objective function evaluations = 41\n", + "Number of objective gradient evaluations = 29\n", + "Number of equality constraint evaluations = 41\n", "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 12\n", + "Number of equality constraint Jacobian evaluations = 29\n", "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 11\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.054\n", - "Total CPU secs in NLP function evaluations = 0.009\n", + "Number of Lagrangian Hessian evaluations = 28\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.134\n", + "Total CPU secs in NLP function evaluations = 0.037\n", "\n", "EXIT: Optimal Solution Found.\n", "Ipopt 3.13.2: \n", @@ -1937,76 +1978,207 @@ " inequality constraints with only upper bounds: 0\n", "\n", "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 7.3140480e-03 4.99e+02 1.73e-08 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 1.3207560e-03 1.51e+03 1.71e+01 -1.0 1.22e+04 - 9.80e-01 1.00e+00h 1\n", - " 2 1.8154463e-03 1.17e+04 1.79e+01 -1.0 6.32e+03 - 2.80e-01 1.33e-01h 3\n", - " 3 1.8019859e-03 1.15e+04 1.68e+02 -1.0 3.24e+02 -4.0 8.33e-01 2.50e-01h 3\n", - " 4 9.1607115e-04 1.14e+04 1.67e+02 -1.0 5.66e+04 - 1.86e-01 1.21e-02h 5\n", - " 5 9.1689129e-04 1.15e+04 1.68e+02 -1.0 2.40e+02 -4.5 2.90e-01 8.20e-03h 6\n", - " 6 9.1779570e-04 1.15e+04 1.68e+02 -1.0 3.09e+02 -4.1 3.68e-01 4.46e-03h 7\n", - " 7 9.1783813e-04 1.15e+04 1.68e+02 -1.0 2.66e+02 -2.7 9.91e-01 8.10e-04h 8\n", - " 8 9.1750565e-04 1.16e+04 1.69e+02 -1.0 4.79e+02 -1.4 5.55e-02 2.05e-03h 6\n", - " 9 9.1580217e-04 1.14e+04 4.52e+02 -1.0 2.36e+02 -1.9 6.09e-01 2.40e-02h 6\n", + " 0 6.0080157e-03 5.63e+02 9.87e-09 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 8.5722553e-04 1.44e+03 1.64e+01 -1.0 1.37e+04 - 9.82e-01 1.00e+00h 1\n", + " 2 1.2633817e-03 1.09e+04 1.34e+01 -1.0 3.20e+03 - 5.07e-01 2.50e-01h 3\n", + " 3 1.2582351e-03 1.05e+04 3.85e+01 -1.0 3.56e+02 -4.0 8.15e-01 1.25e-01h 4\n", + " 4 1.2580167e-03 1.05e+04 3.80e+01 -1.0 3.11e+02 -4.5 9.91e-01 1.17e-02h 6\n", + " 5 1.0516690e-03 9.87e+03 3.55e+01 -1.0 9.47e+03 - 9.10e-01 6.25e-02h 5\n", + " 6 1.0548808e-03 1.01e+04 3.59e+01 -1.0 2.88e+02 -5.0 5.26e-01 3.59e-02h 5\n", + " 7 1.0571437e-03 1.01e+04 3.61e+01 -1.0 2.78e+02 -4.5 3.75e-01 1.40e-02h 6\n", + " 8 1.0572387e-03 1.01e+04 3.62e+01 -1.0 5.65e+02 -3.2 1.37e-01 2.97e-04h 9\n", + " 9r 1.0572387e-03 1.01e+04 9.99e+02 1.5 0.00e+00 -2.8 0.00e+00 2.63e-07R 17\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10r 1.0573932e-03 8.08e+03 9.89e+02 1.5 3.50e+04 - 9.65e-01 9.97e-04f 1\n", + " 11 5.4743818e-03 2.51e+03 2.04e-01 -1.0 4.23e+03 - 1.00e+00 1.00e+00h 1\n", + " 12 3.7555091e-03 1.51e+03 3.72e-01 -1.0 1.17e+04 - 1.00e+00 1.00e+00h 1\n", + " 13 1.7570808e-03 1.36e+03 4.49e-01 -1.0 1.40e+04 - 1.00e+00 1.00e+00h 1\n", + " 14 1.5819722e-03 1.92e+01 3.66e-03 -1.0 1.10e+03 - 1.00e+00 1.00e+00h 1\n", + " 15 1.5644793e-03 1.61e-02 4.40e-04 -2.5 4.36e+01 - 1.00e+00 1.00e+00h 1\n", + " 16 1.1694177e-03 9.29e+00 3.51e-04 -3.8 2.13e+02 - 1.00e+00 1.00e+00h 1\n", + " 17 7.0567043e-04 5.23e+01 6.11e-05 -3.8 4.96e+02 - 1.00e+00 1.00e+00h 1\n", + " 18 7.0531544e-04 3.55e+00 1.29e-07 -3.8 5.48e+00 - 1.00e+00 1.00e+00h 1\n", + " 19 7.0529502e-04 4.85e-04 1.50e-09 -3.8 5.06e-02 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 6.8853990e-04 1.31e+01 8.02e-06 -5.7 9.38e+01 - 1.00e+00 1.00e+00h 1\n", + " 21 6.8852757e-04 2.45e-02 8.20e-04 -5.7 5.34e-02 -3.3 1.00e+00 1.00e+00h 1\n", + " 22 6.8807586e-04 5.94e-01 3.29e-03 -5.7 2.36e+00 - 1.00e+00 1.00e+00h 1\n", + " 23 6.8807572e-04 2.14e-05 7.42e-08 -5.7 3.96e-04 -3.7 1.00e+00 1.00e+00h 1\n", + " 24 6.6490277e-04 2.56e+03 7.60e-04 -8.6 6.52e+01 - 8.94e-01 1.00e+00h 1\n", + " 25 6.6477232e-04 1.95e+02 1.39e-01 -8.6 7.44e-01 -4.2 9.62e-01 1.00e+00h 1\n", + " 26 6.6446306e-04 1.44e-02 3.66e-03 -8.6 1.10e+00 -4.7 1.00e+00 1.00e+00h 1\n", + " 27 6.6415739e-04 9.02e-01 3.01e-03 -8.6 7.94e+01 - 1.00e+00 2.50e-01h 3\n", + " 28 6.6383285e-04 1.90e-02 1.58e-03 -8.6 8.93e+00 - 1.00e+00 1.00e+00h 1\n", + " 29 6.5357918e-04 1.36e+02 1.65e-05 -8.6 4.26e+01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30 6.5352437e-04 1.54e+00 5.29e-04 -8.6 2.59e-01 -5.2 1.00e+00 1.00e+00h 1\n", + " 31 6.4998430e-04 1.75e+01 1.81e-03 -8.6 2.78e+01 - 1.00e+00 1.00e+00h 1\n", + " 32 6.4997930e-04 3.63e-02 2.17e-06 -8.6 2.22e-02 -5.6 1.00e+00 1.00e+00h 1\n", + " 33 6.2054908e-04 1.52e+03 5.23e-04 -8.6 1.82e+02 - 1.00e+00 1.00e+00h 1\n", + " 34 6.1137893e-04 5.82e+01 1.92e-05 -8.6 6.74e+02 - 1.00e+00 1.00e+00h 1\n", + " 35 6.1139917e-04 2.14e+01 2.07e-05 -8.6 1.70e+02 - 1.00e+00 1.00e+00h 1\n", + " 36 6.1140523e-04 2.17e+00 1.98e-05 -8.6 7.30e+01 - 1.00e+00 1.00e+00h 1\n", + " 37 6.1136621e-04 2.93e+00 1.89e-05 -8.6 7.65e+01 - 1.00e+00 1.00e+00h 1\n", + " 38 6.1134451e-04 2.20e+00 9.34e-06 -8.6 7.66e+01 - 1.00e+00 5.00e-01h 2\n", + " 39 6.1140965e-04 4.40e-01 1.78e-05 -8.6 3.03e+01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 40 6.1157432e-04 1.35e-01 1.76e-05 -8.6 6.77e+01 - 1.00e+00 1.00e+00H 1\n", + " 41 6.1153319e-04 1.97e-02 2.04e-05 -8.6 7.66e+01 - 1.00e+00 1.00e+00H 1\n", + " 42 6.1158272e-04 6.23e-03 1.99e-05 -8.6 7.80e+01 - 1.00e+00 1.00e+00H 1\n", + " 43 6.1153325e-04 2.02e-02 2.04e-05 -8.6 7.77e+01 - 1.00e+00 1.00e+00H 1\n", + " 44 6.1158277e-04 1.70e-04 1.99e-05 -8.6 7.80e+01 - 1.00e+00 1.00e+00H 1\n", + " 45 6.1153325e-04 2.02e-02 2.04e-05 -8.6 7.77e+01 - 1.00e+00 1.00e+00H 1\n", + " 46 6.1158276e-04 1.70e-04 1.99e-05 -8.6 7.80e+01 - 1.00e+00 1.00e+00H 1\n", + " 47 6.1153986e-04 4.28e-03 2.04e-05 -8.6 7.77e+01 - 1.00e+00 1.00e+00H 1\n", + " 48 6.1136587e-04 2.98e+00 1.91e-05 -8.6 7.81e+01 - 1.00e+00 1.00e+00h 1\n", + " 49 6.1140692e-04 2.96e+00 1.99e-05 -8.6 7.67e+01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 50 6.1136628e-04 2.95e+00 1.89e-05 -8.6 7.66e+01 - 1.00e+00 1.00e+00h 1\n", + " 51 6.1140692e-04 2.96e+00 1.99e-05 -8.6 7.66e+01 - 1.00e+00 1.00e+00h 1\n", + " 52 6.1136628e-04 2.95e+00 1.89e-05 -8.6 7.66e+01 - 1.00e+00 1.00e+00h 1\n", + " 53 6.1134454e-04 2.22e+00 9.35e-06 -8.6 7.66e+01 - 1.00e+00 5.00e-01h 2\n", + " 54 6.1140964e-04 4.40e-01 1.78e-05 -8.6 3.03e+01 - 1.00e+00 1.00e+00h 1\n", + " 55 6.1157797e-04 1.06e-04 1.76e-05 -8.6 6.77e+01 - 1.00e+00 1.00e+00H 1\n", + " 56 6.1153319e-04 1.99e-02 2.04e-05 -8.6 7.66e+01 - 1.00e+00 1.00e+00H 1\n", + " 57 6.1140577e-04 7.49e-01 9.39e-06 -8.6 7.80e+01 - 1.00e+00 5.00e-01h 2\n", + " 58 6.1141057e-04 3.99e-01 1.75e-05 -8.6 2.83e+01 - 1.00e+00 1.00e+00h 1\n", + " 59 6.1136613e-04 2.16e+00 1.62e-05 -8.6 6.61e+01 - 1.00e+00 1.00e+00h 1\n", "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 5.8569305e-04 4.67e+02 1.96e+04 -1.0 4.28e+02 -2.3 1.00e+00 1.00e+00h 1\n", - " 11 5.8102621e-04 7.59e-01 2.13e+03 -1.0 4.93e+01 -2.8 1.00e+00 1.00e+00h 1\n", - " 12 5.8104491e-04 4.95e-04 4.24e-01 -1.0 1.38e-01 -3.3 1.00e+00 1.00e+00h 1\n", - " 13 6.5261872e-04 4.25e+01 2.41e-01 -1.7 2.45e+02 - 1.00e+00 1.00e+00f 1\n", - " 14 3.0298036e-03 5.64e+02 1.93e-02 -1.7 9.30e+02 - 1.00e+00 1.00e+00H 1\n", - " 15 3.3279331e-03 1.65e+03 8.87e-03 -1.7 7.85e+02 - 1.00e+00 1.00e+00h 1\n", - " 16 3.2805595e-03 1.10e+01 3.81e-05 -1.7 3.88e+02 - 1.00e+00 1.00e+00h 1\n", - " 17 3.0656018e-03 6.69e-01 4.98e-04 -2.5 1.94e+02 - 1.00e+00 1.00e+00h 1\n", - " 18 1.8976854e-03 2.88e+01 5.46e-04 -3.8 1.27e+03 - 1.00e+00 1.00e+00h 1\n", - " 19 6.3352994e-04 1.33e+02 1.31e-03 -3.8 1.09e+03 - 1.00e+00 1.00e+00h 1\n", + " 60 6.1153978e-04 3.98e-03 2.04e-05 -8.6 7.54e+01 - 1.00e+00 1.00e+00H 1\n", + " 61 6.1158277e-04 4.45e-06 1.99e-05 -8.6 7.81e+01 - 1.00e+00 1.00e+00H 1\n", + " 62 6.1153325e-04 2.02e-02 2.04e-05 -8.6 7.77e+01 - 1.00e+00 1.00e+00H 1\n", + " 63 6.1140578e-04 7.48e-01 9.39e-06 -8.6 7.80e+01 - 1.00e+00 5.00e-01h 2\n", + " 64 6.1141057e-04 3.98e-01 1.75e-05 -8.6 2.83e+01 - 1.00e+00 1.00e+00h 1\n", + " 65 6.1136613e-04 2.16e+00 1.62e-05 -8.6 6.61e+01 - 1.00e+00 1.00e+00h 1\n", + " 66 6.1153978e-04 3.98e-03 2.04e-05 -8.6 7.54e+01 - 1.00e+00 1.00e+00H 1\n", + " 67 6.1146340e-04 1.89e-01 1.52e-05 -8.6 7.81e+01 - 1.00e+00 2.50e-01h 3\n", + " 68 6.1136908e-04 1.28e+00 2.10e-05 -8.6 5.08e+01 - 1.00e+00 1.00e+00h 1\n", + " 69 6.1153274e-04 2.89e-02 2.03e-05 -8.6 6.87e+01 - 1.00e+00 1.00e+00H 1\n", "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 6.3635621e-04 1.03e+01 4.92e-06 -3.8 2.33e+01 - 1.00e+00 1.00e+00h 1\n", - " 21 6.3629587e-04 1.62e-03 1.50e-09 -3.8 1.70e-01 - 1.00e+00 1.00e+00h 1\n", - " 22 6.0131604e-04 2.48e+01 1.40e-05 -5.7 1.36e+02 - 1.00e+00 1.00e+00h 1\n", - " 23 6.0129826e-04 7.17e-02 6.26e-04 -5.7 1.21e-01 -3.8 1.00e+00 1.00e+00h 1\n", - " 24 6.0000985e-04 2.32e+00 3.59e-03 -5.7 5.65e+00 - 1.00e+00 1.00e+00h 1\n", - " 25 6.0000928e-04 3.98e-04 3.57e-07 -5.7 1.69e-03 -4.3 1.00e+00 1.00e+00h 1\n", - " 26 5.6683620e-04 2.63e+03 9.94e-04 -8.6 7.02e+01 - 8.93e-01 1.00e+00h 1\n", - " 27 5.6671075e-04 2.00e+02 4.83e-02 -8.6 8.57e-01 -4.7 9.61e-01 1.00e+00h 1\n", - " 28 5.6635393e-04 1.08e-01 1.03e-03 -8.6 1.42e+00 -5.2 1.00e+00 1.00e+00h 1\n", - " 29 5.6570294e-04 7.69e+00 6.61e-03 -8.6 4.44e+01 - 1.00e+00 1.00e+00h 1\n", + " 70 6.1158272e-04 3.79e-06 1.99e-05 -8.6 7.79e+01 - 1.00e+00 1.00e+00H 1\n", + " 71 6.1154015e-04 1.15e-04 2.04e-05 -8.6 7.77e+01 - 1.00e+00 1.00e+00H 1\n", + " 72 6.1146366e-04 1.86e-01 1.52e-05 -8.6 7.81e+01 - 1.00e+00 2.50e-01h 3\n", + " 73 6.1139783e-04 4.12e-01 1.05e-05 -8.6 5.08e+01 - 1.00e+00 5.00e-01h 2\n", + " 74 6.1152026e-04 3.04e-02 1.95e-05 -8.6 4.04e+01 - 1.00e+00 1.00e+00H 1\n", + " 75 6.1145164e-04 1.93e-01 1.44e-05 -8.6 7.46e+01 - 1.00e+00 2.50e-01h 3\n", + " 76 6.1137370e-04 8.95e-01 2.80e-05 -8.6 4.25e+01 - 1.00e+00 1.00e+00h 1\n", + " 77 6.1153859e-04 3.06e-03 2.03e-05 -8.6 6.27e+01 - 1.00e+00 1.00e+00H 1\n", + " 78 6.1158269e-04 3.43e-06 2.00e-05 -8.6 7.78e+01 - 1.00e+00 1.00e+00H 1\n", + " 79 6.1154015e-04 1.15e-04 2.04e-05 -8.6 7.77e+01 - 1.00e+00 1.00e+00H 1\n", "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30 5.6570173e-04 9.41e-03 5.90e-07 -8.6 1.19e-02 -5.7 1.00e+00 1.00e+00h 1\n", - " 31 5.1008979e-04 2.08e+04 1.33e-03 -8.6 6.79e+02 - 1.00e+00 1.00e+00h 1\n", - " 32 5.5137735e-04 1.22e+04 1.22e-03 -8.6 4.98e+02 - 1.00e+00 5.00e-01h 2\n", - " 33 5.5548664e-04 1.07e+04 1.07e-03 -8.6 4.01e+03 - 1.00e+00 1.25e-01h 4\n", - " 34 5.6114479e-04 1.00e+04 1.01e-03 -8.6 4.69e+03 - 1.00e+00 6.25e-02h 5\n", - " 35 5.6120142e-04 1.00e+04 1.01e-03 -8.6 2.11e+03 - 1.00e+00 4.88e-04h 12\n", - " 36 5.6120851e-04 1.00e+04 1.01e-03 -8.6 2.02e+03 - 1.00e+00 6.10e-05h 15\n", - " 37 9.4903015e-04 1.02e+04 3.53e-03 -8.6 2.03e+03 - 1.00e+00 1.00e+00H 1\n", - " 38 2.0775542e-03 3.23e+03 5.67e-03 -8.6 1.17e+04 - 1.00e+00 1.00e+00h 1\n", - " 39 5.1793815e-04 5.47e+02 2.09e-03 -8.6 7.94e+03 - 1.00e+00 1.00e+00h 1\n", + " 80 6.1149916e-04 4.65e-02 1.78e-05 -8.6 7.81e+01 - 1.00e+00 1.25e-01h 4\n", + " 81 6.1144145e-04 1.74e-01 1.25e-05 -8.6 6.73e+01 - 1.00e+00 2.50e-01h 3\n", + " 82 6.1141053e-04 9.99e-02 3.32e-05 -8.6 1.41e+01 - 1.00e+00 1.00e+00h 1\n", + " 83 6.1140894e-04 5.39e-01 1.81e-05 -8.6 3.26e+01 - 1.00e+00 1.00e+00h 1\n", + " 84 6.1136603e-04 2.38e+00 1.91e-05 -8.6 6.93e+01 - 1.00e+00 1.00e+00h 1\n", + " 85 6.1153324e-04 2.85e-02 2.04e-05 -8.6 7.59e+01 - 1.00e+00 1.00e+00H 1\n", + " 86 6.1158272e-04 6.24e-03 1.99e-05 -8.6 7.80e+01 - 1.00e+00 1.00e+00H 1\n", + " 87 6.1153325e-04 2.02e-02 2.04e-05 -8.6 7.77e+01 - 1.00e+00 1.00e+00H 1\n", + " 88 6.1158277e-04 1.70e-04 1.99e-05 -8.6 7.80e+01 - 1.00e+00 1.00e+00H 1\n", + " 89 6.1153325e-04 2.02e-02 2.04e-05 -8.6 7.77e+01 - 1.00e+00 1.00e+00H 1\n", "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 40 4.8972355e-04 8.79e+00 1.17e+00 -8.6 1.75e+02 -6.2 1.00e+00 1.00e+00h 1\n", - " 41 4.8962098e-04 2.78e-04 1.07e-02 -8.6 1.35e+00 -6.6 1.00e+00 1.00e+00h 1\n", - " 42 4.8560679e-04 7.45e-01 2.20e-04 -8.6 5.57e+01 - 1.00e+00 1.00e+00h 1\n", - " 43 4.8552396e-04 1.48e+00 2.93e-07 -8.6 1.25e+01 - 1.00e+00 1.00e+00h 1\n", - " 44 4.8552248e-04 2.11e-04 1.96e-11 -8.6 7.01e-02 - 1.00e+00 1.00e+00h 1\n", - " 45 4.8552248e-04 2.91e-11 2.51e-14 -8.6 6.63e-06 - 1.00e+00 1.00e+00h 1\n", + " 90 6.1158234e-04 9.64e-04 1.99e-05 -8.6 7.80e+01 - 1.00e+00 1.00e+00H 1\n", + " 91 6.1153997e-04 4.29e-03 2.04e-05 -8.6 7.77e+01 - 1.00e+00 1.00e+00H 1\n", + " 92 6.1136587e-04 2.98e+00 1.91e-05 -8.6 7.81e+01 - 1.00e+00 1.00e+00h 1\n", + " 93 6.1140692e-04 2.96e+00 1.99e-05 -8.6 7.67e+01 - 1.00e+00 1.00e+00h 1\n", + " 94 6.1136628e-04 2.95e+00 1.89e-05 -8.6 7.66e+01 - 1.00e+00 1.00e+00h 1\n", + " 95 6.1140692e-04 2.96e+00 1.99e-05 -8.6 7.66e+01 - 1.00e+00 1.00e+00h 1\n", + " 96 6.1136628e-04 2.95e+00 1.89e-05 -8.6 7.66e+01 - 1.00e+00 1.00e+00h 1\n", + " 97 6.1134454e-04 2.22e+00 9.35e-06 -8.6 7.66e+01 - 1.00e+00 5.00e-01h 2\n", + " 98 6.1140964e-04 4.40e-01 1.78e-05 -8.6 3.03e+01 - 1.00e+00 1.00e+00h 1\n", + " 99 6.1157794e-04 4.40e-03 1.76e-05 -8.6 6.77e+01 - 1.00e+00 1.00e+00H 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 100 6.1153319e-04 1.99e-02 2.04e-05 -8.6 7.66e+01 - 1.00e+00 1.00e+00H 1\n", + " 101 6.1158276e-04 1.70e-04 1.99e-05 -8.6 7.80e+01 - 1.00e+00 1.00e+00H 1\n", + " 102 6.1153325e-04 2.02e-02 2.04e-05 -8.6 7.77e+01 - 1.00e+00 1.00e+00H 1\n", + " 103 6.1140578e-04 7.48e-01 9.39e-06 -8.6 7.80e+01 - 1.00e+00 5.00e-01h 2\n", + " 104 6.1141057e-04 3.98e-01 1.75e-05 -8.6 2.83e+01 - 1.00e+00 1.00e+00h 1\n", + " 105 6.1136613e-04 2.16e+00 1.62e-05 -8.6 6.61e+01 - 1.00e+00 1.00e+00h 1\n", + " 106 6.1153321e-04 2.82e-02 2.04e-05 -8.6 7.54e+01 - 1.00e+00 1.00e+00H 1\n", + " 107 6.1158272e-04 6.23e-03 1.99e-05 -8.6 7.80e+01 - 1.00e+00 1.00e+00H 1\n", + " 108 6.1153986e-04 4.28e-03 2.04e-05 -8.6 7.77e+01 - 1.00e+00 1.00e+00H 1\n", + " 109 6.1158278e-04 1.71e-04 1.99e-05 -8.6 7.81e+01 - 1.00e+00 1.00e+00H 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 110 6.1153325e-04 2.02e-02 2.04e-05 -8.6 7.77e+01 - 1.00e+00 1.00e+00H 1\n", + " 111 6.1158277e-04 1.71e-04 1.99e-05 -8.6 7.80e+01 - 1.00e+00 1.00e+00H 1\n", + " 112 6.1154015e-04 1.15e-04 2.04e-05 -8.6 7.77e+01 - 1.00e+00 1.00e+00H 1\n", + " 113 6.1140911e-04 7.43e-01 9.39e-06 -8.6 7.81e+01 - 1.00e+00 5.00e-01h 2\n", + " 114 6.1141062e-04 3.96e-01 1.74e-05 -8.6 2.82e+01 - 1.00e+00 1.00e+00h 1\n", + " 115 6.1136614e-04 2.16e+00 1.62e-05 -8.6 6.60e+01 - 1.00e+00 1.00e+00h 1\n", + " 116 6.1153978e-04 3.98e-03 2.04e-05 -8.6 7.54e+01 - 1.00e+00 1.00e+00H 1\n", + " 117 6.1158277e-04 5.27e-06 1.99e-05 -8.6 7.81e+01 - 1.00e+00 1.00e+00H 1\n", + " 118 6.1154015e-04 1.15e-04 2.04e-05 -8.6 7.77e+01 - 1.00e+00 1.00e+00H 1\n", + " 119 6.1146366e-04 1.86e-01 1.52e-05 -8.6 7.81e+01 - 1.00e+00 2.50e-01h 3\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 120 6.1136906e-04 1.28e+00 2.10e-05 -8.6 5.08e+01 - 1.00e+00 1.00e+00h 1\n", + " 121 6.1153274e-04 2.89e-02 2.03e-05 -8.6 6.88e+01 - 1.00e+00 1.00e+00H 1\n", + " 122 6.1145830e-04 2.07e-01 1.51e-05 -8.6 7.79e+01 - 1.00e+00 2.50e-01h 3\n", + " 123 6.1136923e-04 1.26e+00 2.13e-05 -8.6 5.04e+01 - 1.00e+00 1.00e+00h 1\n", + " 124 6.1153926e-04 3.45e-03 2.04e-05 -8.6 6.85e+01 - 1.00e+00 1.00e+00H 1\n", + " 125 6.1158274e-04 3.65e-06 2.00e-05 -8.6 7.80e+01 - 1.00e+00 1.00e+00H 1\n", + " 126 6.1154017e-04 7.21e-06 2.04e-05 -8.6 7.77e+01 - 1.00e+00 1.00e+00H 1\n", + " 127 6.1140912e-04 7.43e-01 9.39e-06 -8.6 7.81e+01 - 1.00e+00 5.00e-01h 2\n", + " 128 6.1141062e-04 3.96e-01 1.74e-05 -8.6 2.82e+01 - 1.00e+00 1.00e+00h 1\n", + " 129 6.1135721e-04 7.36e-01 8.57e-06 -8.6 6.60e+01 - 1.00e+00 5.00e-01h 2\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 130 6.1151776e-04 2.83e-02 1.94e-05 -8.6 3.87e+01 - 1.00e+00 1.00e+00H 1\n", + " 131 6.1140252e-04 6.82e-01 9.31e-06 -8.6 7.39e+01 - 1.00e+00 5.00e-01h 2\n", + " 132 6.1140878e-04 5.46e-01 1.82e-05 -8.6 3.31e+01 - 1.00e+00 1.00e+00h 1\n", + " 133 6.1157935e-04 2.36e-06 1.83e-05 -8.6 6.96e+01 - 1.00e+00 1.00e+00H 1\n", + " 134 6.1153320e-04 2.00e-02 2.04e-05 -8.6 7.69e+01 - 1.00e+00 1.00e+00H 1\n", + " 135 6.1145855e-04 1.96e-01 1.52e-05 -8.6 7.80e+01 - 1.00e+00 2.50e-01h 3\n", + " 136 6.1139544e-04 4.15e-01 1.06e-05 -8.6 5.06e+01 - 1.00e+00 5.00e-01h 2\n", + " 137 6.1152568e-04 1.55e-03 1.95e-05 -8.6 4.04e+01 - 1.00e+00 1.00e+00H 1\n", + " 138 6.1136582e-04 2.73e+00 1.87e-05 -8.6 7.47e+01 - 1.00e+00 1.00e+00h 1\n", + " 139 6.1154017e-04 1.31e-04 2.04e-05 -8.6 7.65e+01 - 1.00e+00 1.00e+00H 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 140 6.1158278e-04 3.72e-06 2.00e-05 -8.6 7.81e+01 - 1.00e+00 1.00e+00H 1\n", + " 141 6.1154015e-04 1.15e-04 2.04e-05 -8.6 7.77e+01 - 1.00e+00 1.00e+00H 1\n", + " 142 6.1146366e-04 1.86e-01 1.52e-05 -8.6 7.81e+01 - 1.00e+00 2.50e-01h 3\n", + " 143 6.1136906e-04 1.28e+00 2.10e-05 -8.6 5.08e+01 - 1.00e+00 1.00e+00h 1\n", + " 144 6.1153960e-04 1.32e-04 2.04e-05 -8.6 6.88e+01 - 1.00e+00 1.00e+00H 1\n", + " 145 6.1146336e-04 1.85e-01 1.52e-05 -8.6 7.80e+01 - 1.00e+00 2.50e-01h 3\n", + " 146 6.1136917e-04 1.27e+00 2.11e-05 -8.6 5.05e+01 - 1.00e+00 1.00e+00h 1\n", + " 147 6.1153959e-04 1.32e-04 2.04e-05 -8.6 6.86e+01 - 1.00e+00 1.00e+00H 1\n", + " 148 6.1158274e-04 6.22e-06 2.00e-05 -8.6 7.80e+01 - 1.00e+00 1.00e+00H 1\n", + " 149 6.1154015e-04 1.15e-04 2.04e-05 -8.6 7.77e+01 - 1.00e+00 1.00e+00H 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 150 6.1149916e-04 4.65e-02 1.78e-05 -8.6 7.81e+01 - 1.00e+00 1.25e-01h 4\n", + " 151 6.1136594e-04 2.22e+00 1.55e-05 -8.6 6.73e+01 - 1.00e+00 1.00e+00h 1\n", + " 152 6.1154011e-04 1.31e-04 2.04e-05 -8.6 7.56e+01 - 1.00e+00 1.00e+00H 1\n", + " 153 6.1151894e-04 1.17e-02 1.91e-05 -8.6 7.81e+01 - 1.00e+00 6.25e-02h 5\n", + " 154 6.1145201e-04 1.71e-01 1.41e-05 -8.6 7.29e+01 - 1.00e+00 2.50e-01h 3\n", + " 155 6.1137834e-04 6.75e-01 3.46e-05 -8.6 3.69e+01 - 1.00e+00 1.00e+00h 1\n", + " 156 6.1153809e-04 1.22e-04 2.03e-05 -8.6 5.81e+01 - 1.00e+00 1.00e+00H 1\n", + " 157 6.1158264e-04 3.63e-06 2.00e-05 -8.6 7.76e+01 - 1.00e+00 1.00e+00H 1\n", + " 158 6.1154015e-04 1.16e-04 2.04e-05 -8.6 7.77e+01 - 1.00e+00 1.00e+00H 1\n", + " 159 6.1151897e-04 1.17e-02 1.91e-05 -8.6 7.81e+01 - 1.00e+00 6.25e-02h 5\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 160 6.1148311e-04 5.08e-02 1.67e-05 -8.6 7.29e+01 - 1.00e+00 1.25e-01h 4\n", + " 161 6.1143343e-04 1.55e-01 8.29e-06 -8.6 6.17e+01 - 1.00e+00 2.50e-01h 3\n", + " 162 6.1143330e-04 1.91e-03 4.74e-06 -8.6 1.91e+00 - 1.00e+00 1.00e+00h 1\n", + " 163 6.1143478e-04 6.26e-05 2.80e-07 -8.6 4.72e-01 - 1.00e+00 1.00e+00h 1\n", + " 164 6.1143483e-04 2.15e-07 2.06e-09 -8.6 2.06e-02 - 1.00e+00 1.00e+00h 1\n", "\n", - "Number of Iterations....: 45\n", + "Number of Iterations....: 164\n", "\n", " (scaled) (unscaled)\n", - "Objective...............: 4.8552248114450776e-04 4.8552248114450776e-04\n", - "Dual infeasibility......: 2.5059195075060174e-14 2.5059195075060174e-14\n", - "Constraint violation....: 1.4104644499482425e-11 2.9103830456733704e-11\n", + "Objective...............: 6.1143483258912969e-04 6.1143483258912969e-04\n", + "Dual infeasibility......: 2.0643051633861799e-09 2.0643051633861799e-09\n", + "Constraint violation....: 9.0993523826909950e-09 2.1496089175343511e-07\n", "Complementarity.........: 2.5059035596800626e-09 2.5059035596800626e-09\n", - "Overall NLP error.......: 2.5059035596800626e-09 2.5059035596800626e-09\n", + "Overall NLP error.......: 9.0993523826909950e-09 2.1496089175343511e-07\n", "\n", "\n", - "Number of objective function evaluations = 135\n", - "Number of objective gradient evaluations = 46\n", - "Number of equality constraint evaluations = 135\n", + "Number of objective function evaluations = 524\n", + "Number of objective gradient evaluations = 165\n", + "Number of equality constraint evaluations = 524\n", "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 46\n", + "Number of equality constraint Jacobian evaluations = 166\n", "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 45\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.195\n", - "Total CPU secs in NLP function evaluations = 0.049\n", + "Number of Lagrangian Hessian evaluations = 164\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.578\n", + "Total CPU secs in NLP function evaluations = 0.189\n", "\n", "EXIT: Optimal Solution Found.\n", "Ipopt 3.13.2: \n", @@ -2046,111 +2218,63 @@ " inequality constraints with only upper bounds: 0\n", "\n", "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0677766e-03 5.63e+02 1.45e-08 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 1.2386433e-03 1.21e+03 1.53e+01 -1.0 1.37e+04 - 9.82e-01 1.00e+00h 1\n", - " 2 1.5378810e-03 1.17e+04 1.65e+01 -1.0 8.44e+03 - 2.10e-01 9.65e-02h 3\n", - " 3 1.5219384e-03 1.15e+04 1.43e+02 -1.0 4.28e+02 -4.0 8.32e-01 2.50e-01h 3\n", - " 4 1.4766018e-03 1.27e+04 1.65e+02 -1.0 4.22e+02 -4.5 7.83e-01 1.12e-01h 4\n", - " 5 1.2351015e-03 6.46e+03 1.26e+02 -1.0 3.04e+02 -5.0 9.92e-01 1.00e+00h 1\n", - " 6 1.0582927e-03 1.79e+02 3.10e+01 -1.0 2.69e+02 -5.4 1.00e+00 1.00e+00h 1\n", - " 7 1.0490172e-03 3.18e+01 9.91e-01 -1.0 1.85e+01 -5.9 1.00e+00 1.00e+00h 1\n", - " 8 1.0555296e-03 5.85e+01 8.23e-02 -1.7 1.74e+01 -6.4 1.00e+00 1.00e+00h 1\n", - " 9 1.1004866e-03 3.29e+03 1.25e-01 -1.7 1.97e+02 -6.9 1.00e+00 5.00e-01h 2\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 8.8032955e-04 3.07e+03 1.03e-01 -1.7 5.68e+02 - 1.00e+00 2.50e-01h 3\n", - " 11 8.8045892e-04 3.22e+03 1.65e-01 -1.7 3.98e+01 -3.7 1.73e-01 5.73e-03h 6\n", - " 12 8.8051975e-04 3.22e+03 1.60e-01 -1.7 3.38e+01 -4.2 4.83e-01 4.56e-03h 8\n", - " 13 8.8057935e-04 3.22e+03 1.49e-01 -1.7 3.75e+01 -3.8 1.00e+00 4.07e-03h 8\n", - " 14 8.8060503e-04 3.21e+03 1.34e-01 -1.7 1.88e+01 -3.4 5.19e-01 3.98e-03h 8\n", - " 15 8.8061557e-04 3.21e+03 1.25e-01 -1.7 3.97e+01 -2.9 1.00e+00 8.65e-04h 9\n", - " 16 8.8060713e-04 3.21e+03 1.52e-01 -1.7 2.85e+01 -3.4 3.45e-01 6.44e-04h 10\n", - " 17 8.7770168e-04 2.94e+03 1.74e+00 -1.7 5.61e+01 -3.9 1.00e+00 1.25e-01h 4\n", - " 18 8.6121257e-04 2.48e+03 8.19e+00 -1.7 4.27e+01 -4.4 1.00e+00 1.00e+00h 1\n", - " 19 8.6095409e-04 1.82e+03 3.63e+00 -1.7 2.43e+00 -3.0 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 8.5999505e-04 4.58e+02 5.98e+00 -1.7 1.84e+00 -3.5 1.00e+00 1.00e+00h 1\n", - " 21 8.5844790e-04 4.87e+01 5.64e-01 -1.7 6.05e+00 -4.0 1.00e+00 1.00e+00H 1\n", - " 22 8.5805152e-04 7.17e+00 1.51e-01 -1.7 1.29e+00 -4.5 1.00e+00 1.00e+00h 1\n", - " 23 8.5806689e-04 4.14e-02 1.39e-03 -2.5 4.48e-02 -4.9 1.00e+00 1.00e+00h 1\n", - " 24 7.5665824e-04 2.46e+00 4.37e-04 -3.8 8.97e+01 - 1.00e+00 1.00e+00h 1\n", - " 25 5.9297453e-04 1.27e+01 1.44e-05 -3.8 2.37e+02 - 1.00e+00 1.00e+00h 1\n", - " 26 5.9393463e-04 4.23e+00 1.51e-07 -3.8 5.47e+00 - 1.00e+00 1.00e+00h 1\n", - " 27 5.9392799e-04 7.49e-05 1.50e-09 -3.8 2.44e-02 - 1.00e+00 1.00e+00h 1\n", - " 28 5.6387763e-04 8.78e+00 1.24e-05 -5.7 1.30e+02 - 1.00e+00 1.00e+00h 1\n", - " 29 5.2791567e-04 2.29e+04 9.63e-04 -5.7 1.95e+02 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30 5.2972980e-04 2.25e+04 9.48e-04 -5.7 5.59e+02 - 1.00e+00 1.56e-02h 7\n", - " 31 5.2973343e-04 2.25e+04 9.48e-04 -5.7 5.68e+02 - 1.00e+00 3.05e-05h 16\n", - " 32 8.2329598e-04 8.66e+03 1.13e-03 -5.7 5.55e+02 - 1.00e+00 1.00e+00s 22\n", - " 33r 8.2329598e-04 8.66e+03 9.99e+02 1.5 0.00e+00 - 0.00e+00 0.00e+00R 1\n", - " 34r 7.9209116e-04 7.01e+03 9.97e+02 1.5 3.00e+04 - 6.19e-03 9.93e-04f 1\n", - " 35r 7.5544383e-04 6.51e+03 9.96e+02 0.8 1.01e+01 2.0 5.97e-01 3.67e-02f 1\n", - " 36r 7.9027035e-04 4.83e+03 9.90e+02 0.8 7.57e+03 - 5.80e-03 4.85e-03f 1\n", - " 37r 7.8455905e-04 3.81e+03 9.84e+02 0.8 3.89e+03 - 5.64e-03 5.17e-03f 1\n", - " 38r 7.6578409e-04 3.71e+03 9.57e+02 0.8 3.58e+00 2.4 1.00e+00 1.88e-02f 1\n", - " 39r 7.1088777e-04 3.24e+03 9.74e+02 0.8 1.37e+00 2.9 1.00e+00 2.35e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 40r 7.4188221e-04 1.70e+03 9.51e+02 0.8 2.44e+03 - 2.35e-02 2.48e-02f 1\n", - " 41r 7.5471085e-04 1.65e+03 9.03e+02 0.8 3.80e+03 - 5.06e-02 3.35e-03f 1\n", - " 42r 9.4431463e-04 1.84e+03 8.89e+02 0.8 1.44e+03 - 1.56e-02 8.66e-02f 1\n", - " 43r 1.0046477e-03 1.81e+03 1.10e+03 0.8 7.94e+02 - 1.92e-01 1.77e-02f 1\n", - " 44r 9.5162959e-04 1.72e+03 1.06e+03 0.8 7.88e+02 - 7.27e-02 4.79e-02f 1\n", - " 45r 9.3273350e-04 1.64e+03 9.86e+02 0.8 7.35e+02 - 1.91e-01 5.05e-02f 1\n", - " 46r 1.1071537e-03 1.45e+03 8.69e+02 0.8 5.68e+02 - 1.26e-01 1.15e-01f 1\n", - " 47r 1.3530616e-03 1.28e+03 6.56e+02 0.8 9.35e+02 - 2.45e-01 1.43e-01f 1\n", - " 48r 1.3628911e-03 1.27e+03 6.48e+02 0.8 1.67e+03 - 8.90e-02 5.90e-03f 1\n", - " 49r 1.2626360e-03 1.03e+03 7.49e+02 0.8 6.94e+02 - 7.00e-01 2.08e-01f 1\n", + " 0 5.6010954e-03 5.63e+02 1.15e-08 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 1.0194432e-03 1.46e+03 1.64e+01 -1.0 1.37e+04 - 9.82e-01 1.00e+00h 1\n", + " 2 1.2968158e-03 7.43e+03 1.27e+01 -1.0 2.57e+03 - 5.93e-01 2.50e-01h 3\n", + " 3 1.2957916e-03 7.38e+03 1.26e+01 -1.0 3.56e+02 -4.0 5.72e-01 2.47e-02h 6\n", + " 4 1.2957789e-03 7.38e+03 1.26e+01 -1.0 3.47e+02 -3.6 5.33e-01 1.55e-03h 8\n", + " 5 1.2957646e-03 7.38e+03 1.26e+01 -1.0 3.46e+02 -3.1 8.24e-02 2.63e-04h 9\n", + " 6 7.4442110e-04 1.85e+03 3.03e+01 -1.0 9.55e+02 - 9.91e-01 1.00e+00h 1\n", + " 7 7.6477769e-04 4.66e+02 2.31e+02 -1.0 1.53e+02 -3.6 1.00e+00 1.00e+00h 1\n", + " 8 7.6400461e-04 5.98e+01 7.46e+01 -1.0 3.16e+00 -4.1 1.00e+00 1.00e+00h 1\n", + " 9 7.6408251e-04 2.28e-01 9.01e-02 -1.0 1.53e+00 -4.6 1.00e+00 1.00e+00h 1\n", "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 50r 1.1913421e-03 9.63e+02 9.31e+02 0.8 6.80e+02 - 1.00e+00 6.90e-02f 1\n", - " 51r 6.6266079e-04 4.64e+02 6.04e+01 0.8 2.51e+02 - 1.00e+00 9.26e-01f 1\n", - " 52r 6.6241288e-04 1.72e+02 3.34e+02 -0.6 1.42e-01 3.3 1.00e+00 6.30e-01f 1\n", - " 53r 6.6378543e-04 4.22e+01 1.71e+02 -0.6 2.35e-01 2.8 1.00e+00 7.62e-01f 1\n", - " 54r 6.5368318e-04 1.48e+01 6.63e+01 -0.6 2.24e-01 2.3 8.34e-01 7.31e-01f 1\n", - " 55r 6.5247649e-04 1.48e+01 5.37e+02 -0.6 6.45e-01 1.8 9.95e-01 4.56e-01f 1\n", - " 56r 6.4895541e-04 1.72e+01 8.39e+02 -0.6 1.61e+00 1.4 1.00e+00 1.77e-01f 1\n", - " 57r 6.4081200e-04 3.77e+01 1.06e+03 -0.6 5.02e+00 0.9 7.82e-01 1.31e-01f 1\n", - " 58r 6.7359020e-04 5.24e+01 1.00e+03 -0.6 5.87e+03 - 6.77e-02 1.88e-02f 1\n", - " 59r 6.6450297e-04 5.10e+01 1.17e+03 -0.6 2.23e+03 - 6.64e-01 5.03e-02f 1\n", + " 10 8.3823379e-04 4.85e+03 6.08e-01 -2.5 1.78e+03 - 8.50e-01 1.00e+00h 1\n", + " 11 7.7103878e-04 4.89e+01 2.13e-02 -2.5 1.63e+03 - 1.00e+00 1.00e+00h 1\n", + " 12 9.0641450e-04 1.02e+03 1.14e-02 -2.5 6.30e+02 - 1.00e+00 5.00e-01h 2\n", + " 13 1.3694856e-03 5.62e+02 3.12e-04 -2.5 3.29e+02 - 1.00e+00 1.00e+00h 1\n", + " 14 1.3411507e-03 1.12e+02 1.32e-05 -2.5 1.71e+01 - 1.00e+00 1.00e+00h 1\n", + " 15 1.3408428e-03 1.03e-01 2.83e-08 -2.5 1.60e+00 - 1.00e+00 1.00e+00h 1\n", + " 16 1.0823198e-03 5.95e+00 2.79e-04 -3.8 1.67e+02 - 1.00e+00 1.00e+00h 1\n", + " 17 7.6039054e-04 3.34e+01 3.80e-05 -3.8 3.91e+02 - 1.00e+00 1.00e+00h 1\n", + " 18 7.5982215e-04 1.49e+00 5.09e-08 -3.8 3.32e+00 - 1.00e+00 1.00e+00h 1\n", + " 19 7.5981362e-04 8.21e-05 1.50e-09 -3.8 2.34e-02 - 1.00e+00 1.00e+00h 1\n", "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 60r 6.5378620e-04 4.83e+01 1.54e+03 -0.6 9.69e+02 - 7.06e-01 7.03e-02f 1\n", - " 61r 6.1059197e-04 5.82e+01 4.80e+02 -0.6 5.24e+02 - 1.00e+00 5.04e-01f 1\n", - " 62r 6.0576333e-04 9.20e+01 1.54e+02 -0.6 2.80e+02 - 1.00e+00 7.93e-01f 1\n", - " 63r 6.0345577e-04 1.35e+02 1.30e+02 -0.6 3.00e+02 - 1.00e+00 6.35e-01f 1\n", - " 64r 6.0579638e-04 8.67e+00 2.49e+00 -0.6 1.75e+02 - 1.00e+00 1.00e+00H 1\n", - " 65r 6.0443224e-04 1.23e+01 6.17e-01 -2.0 4.95e+01 - 1.00e+00 9.86e-01f 1\n", - " 66r 6.0419074e-04 9.54e-03 1.24e+00 -2.0 1.90e+01 - 1.00e+00 1.00e+00f 1\n", - " 67r 6.0358870e-04 1.06e-03 1.53e-01 -2.0 3.94e+00 - 1.00e+00 1.00e+00H 1\n", - " 68r 6.0348593e-04 1.16e-05 3.91e-02 -3.0 2.59e-01 - 1.00e+00 1.00e+00f 1\n", - " 69r 6.0348566e-04 7.46e-06 1.47e-02 -4.5 5.94e-02 - 1.00e+00 1.00e+00f 1\n", + " 20 7.3964780e-04 1.39e+01 9.07e-06 -5.7 1.04e+02 - 1.00e+00 1.00e+00h 1\n", + " 21 7.3962506e-04 2.05e-02 1.45e-05 -5.7 6.41e-02 -5.1 1.00e+00 1.00e+00h 1\n", + " 22 7.2459137e-04 9.99e+02 2.60e-03 -5.7 4.55e+01 - 1.00e+00 1.00e+00h 1\n", + " 23 7.2438652e-04 3.72e+01 2.62e-03 -5.7 6.97e-01 -5.5 1.00e+00 1.00e+00h 1\n", + " 24 7.2133779e-04 3.72e+01 2.68e-03 -5.7 3.72e+01 - 1.00e+00 1.00e+00h 1\n", + " 25 7.2133543e-04 2.07e-01 1.28e-06 -5.7 7.89e-03 -6.0 1.00e+00 1.00e+00h 1\n", + " 26 6.7907673e-04 8.57e+03 4.30e-04 -5.7 3.04e+02 - 1.00e+00 1.00e+00h 1\n", + " 27 6.8326626e-04 6.82e+02 1.32e-04 -5.7 5.22e+02 - 1.00e+00 1.00e+00h 1\n", + " 28 6.7339163e-04 9.37e+00 3.98e-06 -5.7 1.41e+02 - 1.00e+00 1.00e+00h 1\n", + " 29 6.7297155e-04 3.98e-02 7.00e-09 -5.7 3.04e+00 - 1.00e+00 1.00e+00h 1\n", "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 70r 6.0348492e-04 3.17e-08 1.31e-05 -4.5 2.14e-02 - 1.00e+00 1.00e+00f 1\n", - " 71 5.2477981e-04 2.02e+03 4.70e-04 -5.7 3.67e+02 - 1.00e+00 1.00e+00h 1\n", - " 72 5.2174319e-04 4.07e+00 1.82e-05 -5.7 3.96e+01 - 1.00e+00 1.00e+00h 1\n", - " 73 5.2120375e-04 3.25e+00 2.31e-06 -5.7 7.98e+01 - 1.00e+00 1.00e+00h 1\n", - " 74 5.2120888e-04 4.72e-03 2.02e-09 -5.7 1.22e+00 - 1.00e+00 1.00e+00h 1\n", - " 75 5.2103883e-04 6.40e+00 3.90e-07 -8.6 7.10e+01 - 9.95e-01 1.00e+00h 1\n", - " 76 5.2103457e-04 8.42e-03 5.17e-10 -8.6 1.23e+00 - 1.00e+00 1.00e+00h 1\n", - " 77 5.2103455e-04 1.05e-08 2.51e-14 -8.6 1.18e-03 - 1.00e+00 1.00e+00h 1\n", + " 30 6.7297139e-04 5.28e-08 1.84e-11 -5.7 3.25e-03 - 1.00e+00 1.00e+00h 1\n", + " 31 6.7282315e-04 4.00e+00 2.48e-07 -8.6 6.59e+01 - 9.97e-01 1.00e+00h 1\n", + " 32 6.7281999e-04 2.40e-03 1.50e-10 -8.6 7.35e-01 - 1.00e+00 1.00e+00h 1\n", + " 33 6.7281999e-04 4.66e-10 2.51e-14 -8.6 3.38e-04 - 1.00e+00 1.00e+00h 1\n", "\n", - "Number of Iterations....: 77\n", + "Number of Iterations....: 33\n", "\n", " (scaled) (unscaled)\n", - "Objective...............: 5.2103454872737373e-04 5.2103454872737373e-04\n", + "Objective...............: 6.7281998558273008e-04 6.7281998558273008e-04\n", "Dual infeasibility......: 2.5059195075060174e-14 2.5059195075060174e-14\n", - "Constraint violation....: 3.6366718714863869e-11 1.0462827049195768e-08\n", - "Complementarity.........: 2.5059035633214610e-09 2.5059035633214610e-09\n", - "Overall NLP error.......: 2.5059035633214610e-09 1.0462827049195768e-08\n", + "Constraint violation....: 1.4104644499482425e-11 4.6566128730773926e-10\n", + "Complementarity.........: 2.5059035601133969e-09 2.5059035601133969e-09\n", + "Overall NLP error.......: 2.5059035601133969e-09 2.5059035601133969e-09\n", "\n", "\n", - "Number of objective function evaluations = 198\n", - "Number of objective gradient evaluations = 42\n", - "Number of equality constraint evaluations = 198\n", + "Number of objective function evaluations = 67\n", + "Number of objective gradient evaluations = 34\n", + "Number of equality constraint evaluations = 67\n", "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 79\n", + "Number of equality constraint Jacobian evaluations = 34\n", "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 77\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.324\n", - "Total CPU secs in NLP function evaluations = 0.080\n", + "Number of Lagrangian Hessian evaluations = 33\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.134\n", + "Total CPU secs in NLP function evaluations = 0.031\n", "\n", "EXIT: Optimal Solution Found.\n" ] @@ -2183,23 +2307,23 @@ " \n", " \n", " 0\n", - " -0.881649\n", - " 1.364704\n", + " -0.841522\n", + " 1.267428\n", " \n", " \n", " 1\n", - " -0.914679\n", - " 1.440070\n", + " -0.947847\n", + " 1.511261\n", " \n", " \n", " 2\n", - " -0.950606\n", - " 1.528018\n", + " -0.907245\n", + " 1.426084\n", " \n", " \n", " 3\n", - " -0.825095\n", - " 1.254646\n", + " -0.869204\n", + " 1.360484\n", " \n", " \n", "\n", @@ -2207,10 +2331,10 @@ ], "text/plain": [ " fs.properties.tau[benzene,toluene] fs.properties.tau[toluene,benzene]\n", - "0 -0.881649 1.364704\n", - "1 -0.914679 1.440070\n", - "2 -0.950606 1.528018\n", - "3 -0.825095 1.254646" + "0 -0.841522 1.267428\n", + "1 -0.947847 1.511261\n", + "2 -0.907245 1.426084\n", + "3 -0.869204 1.360484" ] }, "metadata": {}, diff --git a/idaes_examples/notebooks/docs/properties/parameter_estimation_pr.ipynb b/idaes_examples/notebooks/docs/properties/parameter_estimation_pr.ipynb index 64d6b2d1..19a1f0ef 100644 --- a/idaes_examples/notebooks/docs/properties/parameter_estimation_pr.ipynb +++ b/idaes_examples/notebooks/docs/properties/parameter_estimation_pr.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 6, + "execution_count": 1, "metadata": { "tags": [ "header", @@ -57,12 +57,12 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "# Import objects from pyomo package\n", - "from pyomo.environ import ConcreteModel, SolverFactory, value, Var, Suffix \n", + "from pyomo.environ import ConcreteModel, SolverFactory, value, Var, Suffix\n", "\n", "# Import the main FlowsheetBlock from IDAES. The flowsheet block will contain the unit model\n", "from idaes.core import FlowsheetBlock\n", @@ -83,7 +83,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -99,7 +99,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -121,7 +121,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -146,7 +146,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -229,20 +229,20 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "2026-06-10 22:12:38 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-10 22:12:39 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:12:39 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-10 22:12:39 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-10 22:12:39 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:12:39 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:12:39 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n" + "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n" ] } ], @@ -276,7 +276,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 8, "metadata": {}, "outputs": [], "source": [ @@ -288,11 +288,13 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "from pyomo.contrib.parmest.experiment import Experiment\n", + "\n", + "\n", "# Create experiment class for parameter estimation\n", "class PRExperiment(Experiment):\n", "\n", @@ -317,20 +319,11 @@ " # Add Suffixes to label the outputs, parameters, and measurement error in the model\n", " m.experiment_outputs = Suffix(direction=Suffix.LOCAL)\n", " m.experiment_outputs.update(\n", - " [\n", - " (\n", - " m.fs.state_block[1].pressure,\n", - " self.data[\"pressure\"],\n", - " ),\n", - " ]\n", + " [(m.fs.state_block[1].pressure, self.data[\"pressure\"])]\n", " )\n", "\n", " m.measurement_error = Suffix(direction=Suffix.LOCAL)\n", - " m.measurement_error.update(\n", - " [\n", - " (m.fs.state_block[1].pressure, self.meas_error),\n", - " ]\n", - " )\n", + " m.measurement_error.update([(m.fs.state_block[1].pressure, self.meas_error)])\n", "\n", " # Add unknown parameters to the model for easier access\n", " m.unknown_parameters = Suffix(direction=Suffix.LOCAL)\n", @@ -347,10 +340,7 @@ " if self.model is None:\n", " self.create_model()\n", " self.label_model()\n", - " return self.model\n", - "\n", - "\n", - "\n" + " return self.model" ] }, { @@ -364,7 +354,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 10, "metadata": {}, "outputs": [], "source": [ @@ -384,7 +374,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 11, "metadata": {}, "outputs": [ { @@ -396,132 +386,132 @@ "future release, please update to the new parmest interface using experiment\n", "lists. (deprecated in 6.7.2) (called from /Applications/anaconda3/envs/idaes-\n", "examples-dev-py313-macmini/lib/python3.13/functools.py:974)\n", - "2026-06-10 22:13:45 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-10 22:13:45 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:45 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-10 22:13:45 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-10 22:13:45 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:45 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:45 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:45 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-10 22:13:46 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-10 22:13:47 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-10 22:13:48 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:49 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:49 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:49 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-10 22:13:49 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:49 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-10 22:13:49 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-10 22:13:49 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:49 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:49 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", "Ipopt 3.13.2: \n", "\n", "******************************************************************************\n", @@ -591,7 +581,7 @@ "Number of inequality constraint Jacobian evaluations = 0\n", "Number of Lagrangian Hessian evaluations = 11\n", "Total CPU secs in IPOPT (w/o function evaluations) = 0.006\n", - "Total CPU secs in NLP function evaluations = 0.024\n", + "Total CPU secs in NLP function evaluations = 0.025\n", "\n", "EXIT: Optimal Solution Found.\n" ] @@ -605,7 +595,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 12, "metadata": {}, "outputs": [], "source": [ @@ -617,139 +607,139 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-10 22:13:55 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:56 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:57 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-10 22:13:58 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:58 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-10 22:13:58 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-10 22:13:58 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:58 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:58 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:58 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-10 22:13:58 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:58 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-10 22:13:58 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-10 22:13:58 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:58 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:58 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:58 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-10 22:13:58 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:58 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-10 22:13:58 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-10 22:13:58 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:58 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-10 22:13:58 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", "Ipopt 3.13.2: \n", "\n", "******************************************************************************\n", @@ -838,7 +828,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 14, "metadata": {}, "outputs": [ { @@ -863,7 +853,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 15, "metadata": {}, "outputs": [ { From 4b697182d9e8bb76363e597b0c5a73a4aafc5c8c Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Thu, 11 Jun 2026 00:40:39 -0400 Subject: [PATCH 09/23] Update parameter_estimation_pr.ipynb --- .../properties/parameter_estimation_pr.ipynb | 579 +++++------------- 1 file changed, 152 insertions(+), 427 deletions(-) diff --git a/idaes_examples/notebooks/docs/properties/parameter_estimation_pr.ipynb b/idaes_examples/notebooks/docs/properties/parameter_estimation_pr.ipynb index 19a1f0ef..280aedcc 100644 --- a/idaes_examples/notebooks/docs/properties/parameter_estimation_pr.ipynb +++ b/idaes_examples/notebooks/docs/properties/parameter_estimation_pr.ipynb @@ -236,13 +236,13 @@ "name": "stdout", "output_type": "stream", "text": [ - "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n" + "2026-06-11 00:33:41 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:33:41 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:41 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:33:41 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:33:41 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:41 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:41 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n" ] } ], @@ -269,9 +269,9 @@ "source": [ "## 4.0 Parameter estimation using parmest \n", "\n", - "### 4.1 List of variable names to be estimated\n", + "### 4.1 Define the Experiment class\n", "\n", - "Create a list of vars to estimate" + "Define the Experiment class to label model for parameter estimation." ] }, { @@ -279,18 +279,6 @@ "execution_count": 8, "metadata": {}, "outputs": [], - "source": [ - "variable_name = [\n", - " \"fs.properties.PR_kappa['bmimPF6', 'carbon_dioxide']\",\n", - " \"fs.properties.PR_kappa['carbon_dioxide', 'bmimPF6']\",\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [], "source": [ "from pyomo.contrib.parmest.experiment import Experiment\n", "\n", @@ -330,8 +318,8 @@ " m.unknown_parameters.update(\n", " (k, value(k))\n", " for k in [\n", - " m.fs.properties.PR_kappa['bmimPF6', 'carbon_dioxide'],\n", - " m.fs.properties.PR_kappa['carbon_dioxide', 'bmimPF6'],\n", + " m.fs.properties.PR_kappa[\"bmimPF6\", \"carbon_dioxide\"],\n", + " m.fs.properties.PR_kappa[\"carbon_dioxide\", \"bmimPF6\"],\n", " ]\n", " )\n", "\n", @@ -347,20 +335,21 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### 4.2 Create method to return an expression that computes the sum of squared error\n", + "### 4.2 Pre-process the data into individual experiments\n", "\n", - "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." + "We now separate our data and assign a model for each individual experiments, creating an experiment list. " ] }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ - "def SSE(m, data):\n", - " expr = (float(data.iloc[0][\"pressure\"]) - m.fs.state_block[1].pressure) ** 2\n", - " return expr * 1e-7" + "# Update to new interface\n", + "exp_list = []\n", + "for i in range(data.shape[0]):\n", + " exp_list.append(PRExperiment(data.iloc[i]))" ] }, { @@ -369,377 +358,144 @@ "source": [ "### 4.3 Run the parameter estimation\n", "\n", - "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." + "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." ] }, { "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "WARNING: DEPRECATED: You're using the deprecated parmest interface\n", - "(model_function, data, theta_names). This interface will be removed in a\n", - "future release, please update to the new parmest interface using experiment\n", - "lists. (deprecated in 6.7.2) (called from /Applications/anaconda3/envs/idaes-\n", - "examples-dev-py313-macmini/lib/python3.13/functools.py:974)\n", - "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:07:45 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:07:46 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:47 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:48 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 842\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 720\n", - "\n", - "Total number of variables............................: 360\n", - " variables with only lower bounds: 72\n", - " variables with lower and upper bounds: 270\n", - " variables with only upper bounds: 18\n", - "Total number of equality constraints.................: 358\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 5.00e-01 3.80e-14 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 1.1422489e+01 2.60e-01 2.37e+03 -1.0 3.35e+04 - 3.39e-01 6.89e-01h 1\n", - " 2 2.8781463e+01 1.27e-01 1.10e+03 -1.0 1.36e+04 - 8.22e-02 9.90e-01h 1\n", - " 3 2.9814423e+01 1.87e-01 6.44e+02 -1.0 4.87e+02 - 8.73e-01 9.90e-01h 1\n", - " 4 2.9709661e+01 4.26e-02 1.57e+03 -1.0 5.50e+02 - 9.85e-01 9.90e-01h 1\n", - " 5 2.9285199e+01 7.98e-03 9.52e+04 -1.0 2.77e+03 - 9.87e-01 1.00e+00h 1\n", - " 6 2.9283590e+01 1.42e-04 9.49e+04 -1.0 3.48e+02 - 9.90e-01 1.00e+00h 1\n", - " 7 2.9283603e+01 7.45e-08 9.06e+02 -1.0 5.94e-01 - 9.90e-01 1.00e+00h 1\n", - " 8 2.9282891e+01 3.35e-07 1.47e+04 -2.5 1.24e+02 - 9.98e-01 1.00e+00f 1\n", - " 9 2.9282892e+01 1.72e-12 4.97e-08 -2.5 2.39e-01 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 2.9282891e+01 2.85e-10 3.05e+00 -8.6 3.61e+00 - 1.00e+00 1.00e+00h 1\n", - " 11 2.9282891e+01 1.26e-12 9.06e-12 -8.6 2.03e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 11\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.9282891309651692e+01 2.9282891309651692e+01\n", - "Dual infeasibility......: 9.0591404729482314e-12 9.0591404729482314e-12\n", - "Constraint violation....: 1.2554475105183152e-12 1.2554475105183152e-12\n", - "Complementarity.........: 2.5059037693871210e-09 2.5059037693871210e-09\n", - "Overall NLP error.......: 2.5059037693871210e-09 2.5059037693871210e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 12\n", - "Number of objective gradient evaluations = 12\n", - "Number of equality constraint evaluations = 12\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 12\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 11\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.006\n", - "Total CPU secs in NLP function evaluations = 0.025\n", - "\n", - "EXIT: Optimal Solution Found.\n" - ] - } - ], - "source": [ - "pest = parmest.Estimator(PR_model, data, variable_name, SSE, tee=True)\n", - "\n", - "obj_value, parameters = pest.theta_est()" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [], - "source": [ - "# Update to new interface\n", - "exp_list = []\n", - "for i in range(data.shape[0]):\n", - " exp_list.append(PRExperiment(data.iloc[i]))" - ] - }, - { - "cell_type": "code", - "execution_count": 13, + "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:07:49 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:07:50 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:07:51 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:07:52 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:41 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:33:41 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:41 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:33:41 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:33:41 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:41 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:41 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:41 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:33:41 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:41 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:33:41 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:33:41 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:41 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:41 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:41 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", "Ipopt 3.13.2: \n", "\n", "******************************************************************************\n", @@ -813,8 +569,8 @@ } ], "source": [ - "pest_new = parmest.Estimator(exp_list, obj_function=\"SSE\", tee=True)\n", - "obj_value_new, parameters_new = pest_new.theta_est()" + "pest = parmest.Estimator(exp_list, obj_function=\"SSE\", tee=True)\n", + "obj_value, parameters = pest.theta_est()" ] }, { @@ -828,7 +584,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 18, "metadata": {}, "outputs": [ { @@ -838,48 +594,17 @@ "The SSE at the optimal solution is 29.282891\n", "\n", "The values for the parameters are as follows:\n", - "fs.properties.PR_kappa[bmimPF6,carbon_dioxide] = -0.40714284002971035\n", - "fs.properties.PR_kappa[carbon_dioxide,bmimPF6] = 0.020593684002514167\n" - ] - } - ], - "source": [ - "print(\"The SSE at the optimal solution is %0.6f\" % obj_value)\n", - "print()\n", - "print(\"The values for the parameters are as follows:\")\n", - "for k, v in parameters.items():\n", - " print(k, \"=\", v)" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "\n", - "Using new interface:\n", - "\n", - "The SSE at the optimal solution is 292828913.096275\n", - "\n", - "The values for the parameters are as follows:\n", "fs.properties.PR_kappa[bmimPF6,carbon_dioxide] = -0.40714284008565715\n", "fs.properties.PR_kappa[carbon_dioxide,bmimPF6] = 0.02059368400143062\n" ] } ], "source": [ - "# Repeat for new interface\n", - "print(\"\\n\\nUsing new interface:\\n\")\n", - "print(\"The SSE at the optimal solution is %0.6f\" % obj_value_new)\n", + "print(f\"The SSE at the optimal solution is {obj_value*1e-7:0.6f}\")\n", "print()\n", "print(\"The values for the parameters are as follows:\")\n", - "for k, v in parameters_new.items():\n", - " print(k, \"=\", v)" + "for k, v in parameters.items():\n", + " print(f\"{k} = {v}\")" ] }, { From 2d7f027dacbb6765f6b99fead98571cb0d462ab8 Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Thu, 11 Jun 2026 12:19:45 -0400 Subject: [PATCH 10/23] Fully updated unit model, first pass, ran black. --- ...ter_estimation_nrtl_using_unit_model.ipynb | 1268 +---------------- 1 file changed, 43 insertions(+), 1225 deletions(-) diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb index 315202cb..12f86b76 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb @@ -16,7 +16,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", @@ -32,11 +32,8 @@ "# Parameter Estimation Using Flash Unit Model\n", "\n", "Author: Jaffer Ghouse \n", - "Maintainer: Andrew Lee \n", - "Updated: 2023-06-01 \n", - "\n", - "Updated by Stephen Cini\n", - "Updated: 2026-06-10\n", + "Maintainer: Stephen Cini \n", + "Updated: 2026-06-11 \n", "\n", "In this module, we will be using Pyomo's `parmest` tool in conjunction with IDAES models for parameter estimation. We demonstrate these tools by estimating the parameters associated with the NRTL property model for a benzene-toluene mixture. The NRTL model has 2 sets of parameters: the non-randomness parameter (`alpha_ij`) and the binary interaction parameter (`tau_ij`), where `i` and `j` is the pure component species. In this example, we will be only estimate the binary interaction parameter (`tau_ij`) for a given dataset. 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 the NRTL property package. \n", "\n", @@ -90,8 +87,7 @@ "source": [ "# Todo: import ConcreteModel from pyomo.environ\n", "# from pyomo.environ import ConcreteModel, value\n", - "\n", - "import pyomo.environ as pyo\n", + "from pyomo.environ import ConcreteModel, value, Suffix\n", "\n", "# Todo: import FlowsheetBlock from idaes.core\n", "from idaes.core import FlowsheetBlock\n", @@ -236,7 +232,7 @@ "def NRTL_model(data):\n", "\n", " # Todo: Create a ConcreteModel object\n", - " m = pyo.ConcreteModel()\n", + " m = ConcreteModel()\n", "\n", " # Todo: Create FlowsheetBlock object\n", " m.fs = FlowsheetBlock(dynamic=False)\n", @@ -317,17 +313,17 @@ "assert degrees_of_freedom(m) == 0\n", "\n", "# Check for output values\n", - "assert pyo.value(m.fs.flash.liq_outlet.mole_frac_comp[0, \"benzene\"]) == pytest.approx(\n", + "assert value(m.fs.flash.liq_outlet.mole_frac_comp[0, \"benzene\"]) == pytest.approx(\n", " 0.389, abs=1e-2\n", ")\n", - "assert pyo.value(m.fs.flash.vap_outlet.mole_frac_comp[0, \"benzene\"]) == pytest.approx(\n", + "assert value(m.fs.flash.vap_outlet.mole_frac_comp[0, \"benzene\"]) == pytest.approx(\n", " 0.610, abs=1e-2\n", ")\n", "\n", - "assert pyo.value(m.fs.flash.liq_outlet.mole_frac_comp[0, \"toluene\"]) == pytest.approx(\n", + "assert value(m.fs.flash.liq_outlet.mole_frac_comp[0, \"toluene\"]) == pytest.approx(\n", " 0.610, abs=1e-2\n", ")\n", - "assert pyo.value(m.fs.flash.vap_outlet.mole_frac_comp[0, \"toluene\"]) == pytest.approx(\n", + "assert value(m.fs.flash.vap_outlet.mole_frac_comp[0, \"toluene\"]) == pytest.approx(\n", " 0.394, abs=1e-2\n", ")" ] @@ -345,29 +341,26 @@ "source": [ "In addition to providing a method to return an initialized model, the `parmest` tool needs the following:\n", "\n", - "* List of variable names to be estimated\n", - "* Dataset with multiple scenarios\n", - "* Expression to compute the sum of squared errors\n", - "\n", - "\n", - "Updated list:\n", - "* Dataset with multiple scenarios - organized into an experiment list\n", - "* Experiment class to set up and label model with suffixes\n" + "* Experiment class to set up and label model with suffixes\n", + "* Dataset with multiple scenarios - organized into an experiment list" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ + "Here we build an experiment class to label our model problem for parameter estimation. The labels are defined as a `Suffix`, and the main labels for our model are `experiment_outputs`, `unknown_parameters`. and `measurement_error`.\n", + "\n", + "For this problem, the error will be computed for the mole fraction of benzene in the vapor and liquid phase between the model prediction and data. The `experimental_outputs` will therefore be the mole fraction of benzene in the two phases.\n", + "\n", "In this example, we only estimate the binary interaction parameter (`tau_ij`). Given that this variable is usually indexed as `tau_ij = Var(component_list, component_list)`, there are 2*2=4 degrees of freedom. However, when i=j, the binary interaction parameter is 0. Therefore, in this problem, we estimate the binary interaction parameter for the following variables only:\n", "\n", "* fs.properties.tau['benzene', 'toluene']\n", "* fs.properties.tau['toluene', 'benzene']\n", "\n", - "
\n", - "Inline Exercise:\n", - "Create a list called `variable_name` with the above-mentioned variables declared as strings.\n", - "
" + "As shown below, these model components are used as our `unknown_parameters`.\n", + "\n", + "We define `measurement_error` as none so parmest calculates the value internally based on the experimental outputs. Refer to https://pyomo.readthedocs.io/en/stable/explanation/analysis/parmest/driver.html for more information. " ] }, { @@ -402,7 +395,7 @@ " m = self.model\n", "\n", " # Add experiment outputs to the model for easier access\n", - " m.experiment_outputs = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + " m.experiment_outputs = Suffix(direction=Suffix.LOCAL)\n", " m.experiment_outputs.update(\n", " [\n", " (\n", @@ -416,7 +409,7 @@ " ]\n", " )\n", "\n", - " m.measurement_error = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + " m.measurement_error = Suffix(direction=Suffix.LOCAL)\n", " m.measurement_error.update(\n", " [\n", " (m.fs.flash.liq_outlet.mole_frac_comp[0, \"benzene\"], self.meas_error),\n", @@ -425,9 +418,9 @@ " )\n", "\n", " # Add unknown parameters to the model for easier access\n", - " m.unknown_parameters = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + " m.unknown_parameters = Suffix(direction=Suffix.LOCAL)\n", " m.unknown_parameters.update(\n", - " (k, pyo.value(k))\n", + " (k, value(k))\n", " for k in [\n", " m.fs.properties.tau[\"benzene\", \"toluene\"],\n", " m.fs.properties.tau[\"toluene\", \"benzene\"],\n", @@ -892,66 +885,19 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "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 mole fraction of benzene in the vapor and liquid phase between the model prediction and data. \n", - "\n", - "
\n", - "Inline Exercise:\n", - "Complete the following cell by adding an expression to compute the sum of square errors. \n", - "
" + "We define the `exp_list` by spliting the data into individual experiments, or data points." ] }, { "cell_type": "code", "execution_count": 13, - "metadata": { - "tags": [ - "exercise" - ] - }, - "outputs": [], - "source": [ - "# Create method to return an expression that computes the sum of squared error\n", - "def SSE(m, data):\n", - " # Todo: Add expression for computing the sum of squared errors in mole fraction of benzene in the liquid\n", - " # and vapor phase. For example, the squared error for the vapor phase is:\n", - " # (float(data.iloc[0][\"vap_benzene\"]) - m.fs.flash.vap_outlet.mole_frac_comp[0, \"benzene\"])**2\n", - "\n", - " return expr * 1e4" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": { - "tags": [ - "solution" - ] - }, - "outputs": [], - "source": [ - "# Create method to return an expression that computes the sum of squared error\n", - "def SSE(m, data):\n", - " # Todo: Add expression for computing the sum of squared errors in mole fraction of benzene in the liquid\n", - " # and vapor phase. For example, the squared error for the vapor phase is:\n", - " # (float(data[\"vap_benzene\"]) - m.fs.flash.vap_outlet.mole_frac_comp[0, \"benzene\"])**2\n", - " expr = (\n", - " float(data.iloc[0][\"vap_benzene\"])\n", - " - m.fs.flash.vap_outlet.mole_frac_comp[0, \"benzene\"]\n", - " ) ** 2 + (\n", - " float(data.iloc[0][\"liq_benzene\"])\n", - " - m.fs.flash.liq_outlet.mole_frac_comp[0, \"benzene\"]\n", - " ) ** 2\n", - " return expr * 1e4" - ] - }, - { - "cell_type": "markdown", "metadata": {}, + "outputs": [], "source": [ - "
\n", - "Note:\n", - "Notice that we have scaled the expression up by a factor of 10000 as the SSE computed here will be an extremely small number given that we are using the difference in mole fraction in our expression. A well-scaled objective will help improve solve robustness when using IPOPT. \n", - "
\n" + "# Loop through the dataset and create an experiment for each row of data\n", + "exp_list = []\n", + "for i in range(data.shape[0]):\n", + " exp_list.append(NRTLExperiment(data.iloc[i]))" ] }, { @@ -963,116 +909,7 @@ }, { "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "WARNING: DEPRECATED: You're using the deprecated parmest interface\n", - "(model_function, data, theta_names). This interface will be removed in a\n", - "future release, please update to the new parmest interface using experiment\n", - "lists. (deprecated in 6.7.2) (called from /Applications/anaconda3/envs/idaes-\n", - "examples-dev-py313-macmini/lib/python3.13/functools.py:974)\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 10946\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 6600\n", - "\n", - "Total number of variables............................: 2950\n", - " variables with only lower bounds: 150\n", - " variables with lower and upper bounds: 600\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 2948\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 6.0671019e+01 5.63e+02 1.08e-04 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 5.0339335e+00 1.57e+03 7.47e+01 -1.0 1.37e+04 - 9.45e-01 1.00e+00h 1\n", - " 2 5.1535704e+00 1.93e+02 4.59e+02 -1.0 5.54e+02 -4.0 9.90e-01 1.00e+00h 1\n", - " 3 5.1392848e+00 1.07e+00 3.40e+01 -1.0 6.17e+01 -4.5 9.92e-01 1.00e+00h 1\n", - " 4 5.1359488e+00 3.65e+02 2.24e+01 -1.0 8.41e+02 - 1.00e+00 1.00e+00h 1\n", - " 5 5.1198699e+00 1.64e+00 1.32e-01 -1.0 3.65e+02 - 1.00e+00 1.00e+00h 1\n", - " 6 5.0735545e+00 1.54e+02 1.83e-01 -2.5 3.80e+02 - 9.96e-01 1.00e+00h 1\n", - " 7 5.0752210e+00 1.03e+01 5.00e-02 -2.5 9.51e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 5.0750012e+00 5.57e-03 2.07e-05 -2.5 2.09e-01 - 1.00e+00 1.00e+00h 1\n", - " 9 5.0749679e+00 5.85e-02 7.21e-04 -3.8 8.43e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 5.0749686e+00 5.59e-04 1.05e-05 -5.7 9.63e-01 - 1.00e+00 1.00e+00h 1\n", - " 11 5.0749686e+00 3.98e-08 1.56e-09 -8.6 7.56e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 11\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 5.0749685783044818e+00 5.0749685783044818e+00\n", - "Dual infeasibility......: 1.5648777723425133e-09 1.5648777723425133e-09\n", - "Constraint violation....: 1.3843631310512158e-10 3.9843143895268440e-08\n", - "Complementarity.........: 2.5074825420344762e-09 2.5074825420344762e-09\n", - "Overall NLP error.......: 2.5074825420344762e-09 3.9843143895268440e-08\n", - "\n", - "\n", - "Number of objective function evaluations = 12\n", - "Number of objective gradient evaluations = 12\n", - "Number of equality constraint evaluations = 12\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 12\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 11\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.048\n", - "Total CPU secs in NLP function evaluations = 0.012\n", - "\n", - "EXIT: Optimal Solution Found.\n" - ] - } - ], - "source": [ - "# Initialize a parameter estimation object\n", - "pest = parmest.Estimator(NRTL_model, data, variable_name, SSE, tee=True)\n", - "\n", - "# Run parameter estimation using all data\n", - "obj_value, parameters = pest.theta_est()" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [], - "source": [ - "# Update to new interface\n", - "exp_list = []\n", - "for i in range(data.shape[0]):\n", - " exp_list.append(NRTLExperiment(data.iloc[i]))" - ] - }, - { - "cell_type": "code", - "execution_count": 17, + "execution_count": 14, "metadata": {}, "outputs": [ { @@ -1227,7 +1064,7 @@ "Number of equality constraint Jacobian evaluations = 85\n", "Number of inequality constraint Jacobian evaluations = 0\n", "Number of Lagrangian Hessian evaluations = 84\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.341\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.338\n", "Total CPU secs in NLP function evaluations = 0.092\n", "\n", "EXIT: Optimal Solution Found.\n" @@ -1235,13 +1072,13 @@ } ], "source": [ - "pest_new = parmest.Estimator(exp_list, obj_function=\"SSE\", tee=True)\n", - "obj_value_new, parameters_new = pest_new.theta_est()" + "pest = parmest.Estimator(exp_list, obj_function=\"SSE\", tee=True)\n", + "obj_value, parameters = pest.theta_est()" ] }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 15, "metadata": { "tags": [ "testing" @@ -1250,7 +1087,7 @@ "outputs": [], "source": [ "# Check for values of the parameter estimation problem\n", - "assert obj_value == pytest.approx(5.07496, abs=1e-1)\n", + "assert obj_value == pytest.approx(5.07496e-4, abs=1e-1)\n", "assert parameters[\"fs.properties.tau[benzene,toluene]\"] == pytest.approx(-0.89876, 1e-3)\n", "assert parameters[\"fs.properties.tau[toluene,benzene]\"] == pytest.approx(1.410486, 1e-3)" ] @@ -1266,18 +1103,18 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "The SSE at the optimal solution is 0.000507\n", + "The SSE at the optimal solution is 0.000000\n", "\n", "The values for the parameters are as follows:\n", - "fs.properties.tau[benzene,toluene] = -0.8987624039723882\n", - "fs.properties.tau[toluene,benzene] = 1.4104861106604814\n" + "fs.properties.tau[benzene,toluene] = -0.8987454466579063\n", + "fs.properties.tau[toluene,benzene] = 1.410449514796474\n" ] } ], @@ -1296,32 +1133,6 @@ "Using the data that was provided, we have estimated the binary interaction parameters in the NRTL model for a benzene-toluene mixture. Although the dataset that was provided was temperature dependent, in this example we have estimated a single value that fits best for all temperatures." ] }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The SSE at the optimal solution is 0.000507\n", - "\n", - "The values for the parameters are as follows:\n", - "fs.properties.tau[benzene,toluene] = -0.8987454466579063\n", - "fs.properties.tau[toluene,benzene] = 1.410449514796474\n" - ] - } - ], - "source": [ - "# Repeat with new interface\n", - "print(\"The SSE at the optimal solution is %0.6f\" % (obj_value_new))\n", - "print()\n", - "print(\"The values for the parameters are as follows:\")\n", - "for k, v in parameters_new.items():\n", - " print(k, \"=\", v)" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -1341,1016 +1152,23 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 17, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 10946\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 6600\n", - "\n", - "Total number of variables............................: 2950\n", - " variables with only lower bounds: 150\n", - " variables with lower and upper bounds: 600\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 2948\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.4201486e+01 5.41e+02 1.18e-04 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.7673838e+00 1.41e+03 6.59e+01 -1.0 1.32e+04 - 9.54e-01 1.00e+00h 1\n", - " 2 4.9120868e+00 6.82e+01 2.88e+02 -1.0 4.05e+02 -4.0 9.90e-01 1.00e+00h 1\n", - " 3 4.9155706e+00 8.04e+01 2.69e+02 -1.0 1.21e+03 - 9.92e-01 6.25e-02h 5\n", - " 4 4.9153937e+00 2.36e-01 1.11e+01 -1.0 6.25e+00 -4.5 1.00e+00 1.00e+00h 1\n", - " 5 4.8229519e+00 3.75e+02 2.02e+00 -1.0 9.74e+02 - 1.00e+00 1.00e+00f 1\n", - " 6 4.8411927e+00 4.77e+00 2.98e-01 -1.0 7.21e+02 - 1.00e+00 1.00e+00h 1\n", - " 7 4.7910663e+00 1.37e+02 5.72e-02 -1.7 7.95e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 4.7919173e+00 2.79e+00 1.40e-03 -1.7 6.83e+00 - 1.00e+00 1.00e+00h 1\n", - " 9 4.7900483e+00 4.41e+00 2.03e-03 -3.8 1.67e+01 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 4.7900437e+00 3.00e-03 1.57e-06 -3.8 2.23e-01 - 1.00e+00 1.00e+00h 1\n", - " 11 4.7900435e+00 2.26e-04 1.06e-07 -5.7 1.22e-01 - 1.00e+00 1.00e+00h 1\n", - " 12 4.7900435e+00 3.37e-08 1.59e-11 -8.6 1.51e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 12\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 4.7900435100207801e+00 4.7900435100207801e+00\n", - "Dual infeasibility......: 1.5883423092616088e-11 1.5883423092616088e-11\n", - "Constraint violation....: 1.1714230951825415e-10 3.3716787584125996e-08\n", - "Complementarity.........: 2.5073461565202905e-09 2.5073461565202905e-09\n", - "Overall NLP error.......: 2.5073461565202905e-09 3.3716787584125996e-08\n", - "\n", - "\n", - "Number of objective function evaluations = 18\n", - "Number of objective gradient evaluations = 13\n", - "Number of equality constraint evaluations = 18\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 13\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 12\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.047\n", - "Total CPU secs in NLP function evaluations = 0.010\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 10946\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 6600\n", - "\n", - "Total number of variables............................: 2950\n", - " variables with only lower bounds: 150\n", - " variables with lower and upper bounds: 600\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 2948\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 7.9385398e+01 5.63e+02 1.41e-04 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 3.6732844e+00 1.51e+03 7.25e+01 -1.0 1.37e+04 - 9.30e-01 1.00e+00h 1\n", - " 2 3.8447731e+00 2.72e+02 8.62e+02 -1.0 8.03e+02 -4.0 9.90e-01 1.00e+00h 1\n", - " 3 3.8455364e+00 2.83e+02 8.25e+02 -1.0 1.47e+04 - 9.91e-01 3.12e-02h 6\n", - " 4 3.7510500e+00 2.19e+00 7.88e+01 -1.0 4.17e+02 -4.5 1.00e+00 1.00e+00h 1\n", - " 5 4.0251556e+00 1.04e+02 2.95e+02 -1.0 9.58e+02 - 1.00e+00 1.00e+00H 1\n", - " 6 3.7747250e+00 5.10e+02 2.92e+00 -1.0 1.29e+02 - 1.00e+00 1.00e+00h 1\n", - " 7 3.7456697e+00 4.11e+00 1.08e-01 -1.0 3.92e+02 - 1.00e+00 1.00e+00h 1\n", - " 8 3.6977549e+00 1.24e+02 1.72e-01 -2.5 3.61e+02 - 9.99e-01 1.00e+00h 1\n", - " 9 3.7086634e+00 1.56e+01 5.90e-02 -2.5 1.44e+02 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 3.7083820e+00 1.78e-02 2.33e-05 -2.5 1.22e+00 - 1.00e+00 1.00e+00h 1\n", - " 11 3.7083472e+00 6.16e-02 2.81e-05 -3.8 9.06e+00 - 1.00e+00 1.00e+00h 1\n", - " 12 3.7083469e+00 1.70e-04 7.71e-08 -5.7 4.93e-01 - 1.00e+00 1.00e+00h 1\n", - " 13 3.7083469e+00 2.81e-08 1.28e-11 -8.6 6.19e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 13\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 3.7083468741502537e+00 3.7083468741502537e+00\n", - "Dual infeasibility......: 1.2842477470779329e-11 1.2842477470779329e-11\n", - "Constraint violation....: 9.7618591265211775e-11 2.8114300221204758e-08\n", - "Complementarity.........: 2.5072445933176966e-09 2.5072445933176966e-09\n", - "Overall NLP error.......: 2.5072445933176966e-09 2.8114300221204758e-08\n", - "\n", - "\n", - "Number of objective function evaluations = 22\n", - "Number of objective gradient evaluations = 14\n", - "Number of equality constraint evaluations = 22\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 14\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 13\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.051\n", - "Total CPU secs in NLP function evaluations = 0.012\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 10946\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 6600\n", - "\n", - "Total number of variables............................: 2950\n", - " variables with only lower bounds: 150\n", - " variables with lower and upper bounds: 600\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 2948\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 6.4678342e+01 5.63e+02 1.26e-04 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.1403827e+00 1.61e+03 7.48e+01 -1.0 1.37e+04 - 9.43e-01 1.00e+00h 1\n", - " 2 4.1979019e+00 3.36e+02 5.20e+02 -1.0 4.73e+02 -4.0 9.90e-01 1.00e+00h 1\n", - " 3 4.1897805e+00 4.07e+00 5.45e+01 -1.0 1.99e+01 -4.5 9.92e-01 1.00e+00h 1\n", - " 4 4.2236487e+00 1.94e+01 1.43e+00 -1.0 1.88e+02 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2197088e+00 7.33e-02 1.51e-03 -1.0 1.39e+01 - 1.00e+00 1.00e+00h 1\n", - " 6 4.1776383e+00 9.05e+01 4.70e-02 -2.5 3.45e+02 - 1.00e+00 1.00e+00h 1\n", - " 7 4.1770010e+00 7.87e-01 5.51e-04 -2.5 1.54e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 4.1769404e+00 4.33e-02 2.37e-05 -3.8 8.71e+00 - 1.00e+00 1.00e+00h 1\n", - " 9 4.1769400e+00 1.29e-04 7.07e-08 -5.7 4.78e-01 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 4.1769400e+00 2.12e-08 1.16e-11 -8.6 6.00e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 10\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 4.1769399649268752e+00 4.1769399649268752e+00\n", - "Dual infeasibility......: 1.1596265104711192e-11 1.1596265104711192e-11\n", - "Constraint violation....: 7.3492131144224205e-11 2.1158484742045403e-08\n", - "Complementarity.........: 2.5071334548934459e-09 2.5071334548934459e-09\n", - "Overall NLP error.......: 2.5071334548934459e-09 2.1158484742045403e-08\n", - "\n", - "\n", - "Number of objective function evaluations = 11\n", - "Number of objective gradient evaluations = 11\n", - "Number of equality constraint evaluations = 11\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 11\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 10\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.042\n", - "Total CPU secs in NLP function evaluations = 0.009\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 10946\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 6600\n", - "\n", - "Total number of variables............................: 2950\n", - " variables with only lower bounds: 150\n", - " variables with lower and upper bounds: 600\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 2948\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0571322e+01 5.63e+02 1.24e-04 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.8510547e+00 1.63e+03 7.35e+01 -1.0 1.37e+04 - 9.58e-01 1.00e+00h 1\n", - " 2 4.9028623e+00 1.65e+02 3.29e+02 -1.0 3.80e+02 -4.0 9.90e-01 1.00e+00h 1\n", - " 3 4.8974465e+00 8.69e-01 2.74e+01 -1.0 1.46e+01 -4.5 9.92e-01 1.00e+00h 1\n", - " 4 4.9435751e+00 5.44e+01 1.70e+00 -1.0 3.05e+02 - 1.00e+00 1.00e+00h 1\n", - " 5 4.9400183e+00 1.14e-02 4.72e-02 -1.0 6.32e+00 - 1.00e+00 1.00e+00h 1\n", - " 6 4.9022807e+00 4.38e+01 1.86e+00 -2.5 2.05e+02 - 1.00e+00 1.00e+00h 1\n", - " 7 4.8938710e+00 9.79e+00 1.17e+00 -2.5 1.68e+02 - 1.00e+00 1.00e+00h 1\n", - " 8 4.8938840e+00 5.24e-03 9.38e-05 -2.5 7.99e-01 - 1.00e+00 1.00e+00h 1\n", - " 9 4.8938537e+00 5.00e-02 3.64e-05 -3.8 8.98e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 4.8938533e+00 1.39e-04 1.01e-07 -5.7 4.88e-01 - 1.00e+00 1.00e+00h 1\n", - " 11 4.8938533e+00 2.30e-08 1.67e-11 -8.6 6.13e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 11\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 4.8938532544429725e+00 4.8938532544429725e+00\n", - "Dual infeasibility......: 1.6721247418921680e-11 1.6721247418921680e-11\n", - "Constraint violation....: 7.9763999184061651e-11 2.2962922230362892e-08\n", - "Complementarity.........: 2.5071700149320549e-09 2.5071700149320549e-09\n", - "Overall NLP error.......: 2.5071700149320549e-09 2.2962922230362892e-08\n", - "\n", - "\n", - "Number of objective function evaluations = 12\n", - "Number of objective gradient evaluations = 12\n", - "Number of equality constraint evaluations = 12\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 12\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 11\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.044\n", - "Total CPU secs in NLP function evaluations = 0.009\n", - "\n", - "EXIT: Optimal Solution Found.\n" - ] - }, - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
fs.properties.tau[benzene,toluene]fs.properties.tau[toluene,benzene]
0-0.9001621.400445
1-0.9132451.440885
2-0.9627791.562557
3-0.9530521.534538
\n", - "
" - ], - "text/plain": [ - " fs.properties.tau[benzene,toluene] fs.properties.tau[toluene,benzene]\n", - "0 -0.900162 1.400445\n", - "1 -0.913245 1.440885\n", - "2 -0.962779 1.562557\n", - "3 -0.953052 1.534538" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "# Run parameter estimation using bootstrap resample of the data (10 samples),\n", "# plot results along with confidence regions\n", "\n", "# Uncomment the following lines\n", - "\n", - "bootstrap_theta = pest.theta_est_bootstrap(4)\n", - "display(bootstrap_theta)" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 10950\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 6600\n", - "\n", - "Total number of variables............................: 2952\n", - " variables with only lower bounds: 150\n", - " variables with lower and upper bounds: 600\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 2950\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.5931873e-03 5.63e+02 1.07e-08 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 7.2040815e-04 1.42e+03 1.66e+01 -1.0 1.37e+04 - 9.82e-01 1.00e+00h 1\n", - " 2 1.0777759e-03 1.17e+04 1.69e+01 -1.0 5.37e+03 - 3.28e-01 1.56e-01h 3\n", - " 3 1.0673210e-03 1.17e+04 1.70e+02 -1.0 4.00e+02 -4.0 8.36e-01 2.50e-01h 3\n", - " 4 7.6613103e-04 1.17e+04 1.70e+02 -1.0 6.68e+05 - 1.61e-02 4.95e-04h 6\n", - " 5 8.0909902e-04 1.16e+04 1.68e+02 -1.0 2.82e+04 - 9.90e-01 1.14e-02h 6\n", - " 6 9.0975669e-04 1.14e+04 1.65e+02 -1.0 7.82e+03 - 1.00e+00 1.56e-02h 7\n", - " 7 9.5018858e-04 1.14e+04 1.64e+02 -1.0 9.59e+03 - 1.00e+00 3.91e-03h 9\n", - " 8 9.5086210e-04 1.14e+04 1.64e+02 -1.0 9.68e+03 - 1.00e+00 6.10e-05h 15\n", - " 9 9.5101836e-04 1.14e+04 1.64e+02 -1.0 8.96e+03 - 1.00e+00 1.53e-05h 17\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 4.2672867e-03 1.08e+04 1.33e+02 -1.0 8.95e+03 - 1.00e+00 1.25e-01h 4\n", - " 11 1.8528984e-03 5.51e+02 1.85e+02 -1.0 2.19e+03 - 1.00e+00 1.00e+00h 1\n", - " 12 9.5355596e-04 2.97e+03 2.94e+01 -1.0 5.79e+03 - 1.00e+00 1.00e+00h 1\n", - " 13 1.3370336e-03 2.53e+02 3.41e+00 -1.0 5.05e+03 - 1.00e+00 1.00e+00h 1\n", - " 14 1.4965357e-03 4.03e+02 1.30e-01 -1.0 1.57e+02 - 1.00e+00 1.00e+00h 1\n", - " 15 1.4793308e-03 2.95e+01 2.10e-04 -1.0 7.18e+00 - 1.00e+00 1.00e+00h 1\n", - " 16 1.4616765e-03 1.13e-02 3.29e-04 -2.5 7.50e+00 - 1.00e+00 1.00e+00h 1\n", - " 17 1.0077106e-03 1.03e+01 3.56e-04 -3.8 2.27e+02 - 1.00e+00 1.00e+00h 1\n", - " 18 4.7653562e-04 5.81e+01 6.95e-05 -3.8 5.29e+02 - 1.00e+00 1.00e+00h 1\n", - " 19 4.7650361e-04 1.65e+00 7.96e-08 -3.8 8.32e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 4.7649639e-04 1.50e-04 1.50e-09 -3.8 2.81e-02 - 1.00e+00 1.00e+00h 1\n", - " 21 4.5811965e-04 7.13e+00 9.49e-06 -5.7 1.01e+02 - 1.00e+00 1.00e+00h 1\n", - " 22 4.2418207e-04 1.57e+04 4.28e-04 -5.7 2.89e+02 - 1.00e+00 5.00e-01h 2\n", - " 23 4.3806397e-04 1.19e+04 3.36e-04 -5.7 2.07e+02 - 1.00e+00 2.50e-01h 3\n", - " 24 4.4112546e-04 1.16e+04 3.26e-04 -5.7 3.38e+02 - 1.00e+00 3.12e-02h 6\n", - " 25 4.4234498e-04 1.15e+04 3.24e-04 -5.7 5.50e+02 - 1.00e+00 7.81e-03h 8\n", - " 26 4.4320922e-04 1.14e+04 3.23e-04 -5.7 7.80e+02 - 1.00e+00 3.91e-03h 9\n", - " 27 4.4327937e-04 1.14e+04 3.23e-04 -5.7 1.02e+03 - 1.00e+00 2.44e-04h 13\n", - " 28 5.6179673e-04 1.08e+04 3.65e-04 -5.7 1.06e+03 - 1.00e+00 2.50e-01h 3\n", - " 29 5.6096848e-04 1.05e+04 1.40e+00 -5.7 4.90e+01 -4.5 1.00e+00 1.25e-01h 4\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30 4.1881048e-04 6.28e+03 7.11e+01 -5.7 3.62e+02 -5.0 1.00e+00 1.00e+00h 1\n", - " 31 4.1932000e-04 6.10e+03 6.27e+01 -5.7 9.12e+01 -3.6 1.00e+00 6.25e-02h 5\n", - " 32 4.1932819e-04 6.10e+03 6.25e+01 -5.7 6.94e+02 -3.2 1.32e-01 4.36e-04h 9\n", - " 33 4.1950035e-04 6.08e+03 5.90e+01 -5.7 2.63e+02 -2.8 4.27e-01 8.44e-03h 7\n", - " 34 4.2253095e-04 5.79e+03 7.09e+01 -5.7 1.83e+02 -3.3 1.00e+00 1.25e-01h 4\n", - " 35 3.5340029e-03 3.88e+02 3.15e+02 -5.7 1.41e+03 - 1.00e+00 1.00e+00h 1\n", - " 36 3.5370353e-03 3.78e+02 2.97e+02 -5.7 1.16e+03 -2.8 8.09e-01 2.69e-02h 6\n", - " 37 3.5371394e-03 3.78e+02 2.97e+02 -5.7 1.13e+03 -3.3 1.00e+00 9.77e-04h 11\n", - " 38r 3.5371394e-03 3.78e+02 9.99e+02 -0.4 0.00e+00 -3.8 0.00e+00 2.98e-07R 20\n", - " 39r 3.4772716e-03 8.90e+01 9.96e+02 -0.4 2.13e+04 - 1.87e-02 1.72e-03f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 40r 3.2915567e-03 4.36e+01 9.84e+02 -0.4 2.56e+04 - 4.96e-03 1.29e-02f 1\n", - " 41 4.0706315e-04 4.77e+03 5.33e-04 -5.7 4.22e+03 - 1.00e+00 1.00e+00H 1\n", - " 42 4.2691926e-04 3.94e+03 1.50e-04 -5.7 2.38e+03 - 1.00e+00 1.00e+00h 1\n", - " 43 4.2769306e-04 3.86e+03 1.42e-04 -5.7 3.68e+02 - 1.00e+00 6.25e-02h 5\n", - " 44 4.2759384e-04 3.85e+03 4.47e-02 -5.7 3.39e+01 -4.3 6.55e-01 1.29e-02h 7\n", - " 45 4.4578401e-04 3.83e+03 4.37e-02 -5.7 4.30e+03 - 1.00e+00 3.12e-02h 6\n", - " 46 4.4576474e-04 3.82e+03 4.54e-02 -5.7 2.92e+01 -4.7 5.17e-01 4.11e-03h 8\n", - " 47 4.4899517e-04 3.82e+03 4.53e-02 -5.7 7.59e+03 - 4.54e-01 1.41e-03h 9\n", - " 48 4.5019143e-04 3.82e+03 4.53e-02 -5.7 1.42e+04 - 1.00e+00 2.64e-04h 10\n", - " 49r 4.5019143e-04 3.82e+03 9.99e+02 1.1 0.00e+00 - 0.00e+00 2.64e-07R 18\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 50r 4.5032678e-04 3.05e+03 7.64e+02 1.1 1.33e+04 - 1.00e+00 9.92e-04f 1\n", - " 51 7.1722392e-04 1.63e+02 1.44e-03 -5.7 5.15e+03 - 1.00e+00 1.00e+00h 1\n", - " 52 6.1392121e-04 2.38e+02 1.11e-03 -5.7 5.08e+03 - 1.00e+00 2.50e-01h 3\n", - " 53 4.4508936e-04 8.17e+02 4.28e-04 -5.7 3.84e+03 - 1.00e+00 1.00e+00H 1\n", - " 54 4.4422322e-04 4.34e+01 1.66e-01 -5.7 1.54e+01 -5.2 1.00e+00 1.00e+00h 1\n", - " 55 4.4417956e-04 2.05e-02 4.15e-03 -5.7 3.49e-01 -5.7 1.00e+00 1.00e+00h 1\n", - " 56 4.4109546e-04 2.99e+01 9.89e-04 -5.7 1.18e+01 - 1.00e+00 1.00e+00h 1\n", - " 57 4.4108663e-04 1.17e-01 2.11e-06 -5.7 4.24e-02 -6.2 1.00e+00 1.00e+00h 1\n", - " 58 4.1628838e-04 3.01e+03 3.97e-04 -5.7 1.56e+02 - 1.00e+00 1.00e+00h 1\n", - " 59 4.1131149e-04 1.95e+01 6.47e-06 -5.7 7.18e+01 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 60 4.1103610e-04 8.16e-01 8.43e-08 -5.7 7.11e+00 - 1.00e+00 1.00e+00h 1\n", - " 61 4.1104131e-04 1.35e-03 6.90e-11 -5.7 1.99e-01 - 1.00e+00 1.00e+00h 1\n", - " 62 4.1086346e-04 6.39e+00 3.25e-07 -8.6 1.78e+01 - 9.95e-01 1.00e+00h 1\n", - " 63 4.1086098e-04 8.07e-03 4.15e-10 -8.6 3.36e-01 - 1.00e+00 1.00e+00h 1\n", - " 64 4.1086096e-04 9.71e-09 2.51e-14 -8.6 4.29e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 64\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 4.1086096262363253e-04 4.1086096262363253e-04\n", - "Dual infeasibility......: 2.5059086654842926e-14 2.5059086654842926e-14\n", - "Constraint violation....: 3.3686000923643029e-11 9.7061274573206902e-09\n", - "Complementarity.........: 2.5059035631905811e-09 2.5059035631905811e-09\n", - "Overall NLP error.......: 2.5059035631905811e-09 9.7061274573206902e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 325\n", - "Number of objective gradient evaluations = 64\n", - "Number of equality constraint evaluations = 325\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 67\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 64\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.255\n", - "Total CPU secs in NLP function evaluations = 0.089\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 10950\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 6600\n", - "\n", - "Total number of variables............................: 2952\n", - " variables with only lower bounds: 150\n", - " variables with lower and upper bounds: 600\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 2950\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 6.0934979e-03 5.41e+02 1.30e-08 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 1.0067953e-03 1.42e+03 1.66e+01 -1.0 1.32e+04 - 9.82e-01 1.00e+00h 1\n", - " 2 1.5505677e-03 1.16e+04 1.57e+01 -1.0 3.73e+03 - 4.42e-01 2.17e-01h 3\n", - " 3 1.5404225e-03 1.17e+04 1.57e+02 -1.0 3.44e+02 -4.0 8.63e-01 2.50e-01h 3\n", - " 4 1.5063675e-03 1.30e+04 1.74e+02 -1.0 3.09e+02 -4.5 7.38e-01 9.72e-02h 4\n", - " 5 1.3867601e-03 9.41e+03 5.71e+01 -1.0 2.41e+02 -5.0 9.93e-01 5.00e-01h 2\n", - " 6 1.0047237e-03 2.00e+02 1.02e+02 -1.0 4.19e+02 -5.4 1.00e+00 1.00e+00h 1\n", - " 7 9.8978295e-04 1.33e+02 3.63e+00 -1.0 3.67e+01 -5.9 1.00e+00 1.00e+00h 1\n", - " 8 9.8908235e-04 3.59e+01 9.39e-02 -1.0 1.98e+00 -4.6 1.00e+00 1.00e+00h 1\n", - " 9 9.9436740e-04 1.14e-01 4.95e-03 -2.5 3.95e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 8.3472498e-04 3.29e+00 2.17e-04 -3.8 1.24e+02 - 1.00e+00 1.00e+00h 1\n", - " 11 6.2500106e-04 6.16e+01 2.16e-05 -3.8 2.93e+02 - 1.00e+00 1.00e+00h 1\n", - " 12 6.2888894e-04 1.27e+01 3.04e-07 -3.8 9.27e+00 - 1.00e+00 1.00e+00h 1\n", - " 13 6.2883670e-04 3.54e-03 1.50e-09 -3.8 8.92e-02 - 1.00e+00 1.00e+00h 1\n", - " 14 6.0274411e-04 2.18e+01 1.12e-05 -5.7 1.16e+02 - 1.00e+00 1.00e+00h 1\n", - " 15 6.0273686e-04 7.42e-02 3.05e-05 -5.7 8.73e-02 -5.1 1.00e+00 1.00e+00h 1\n", - " 16 5.8231241e-04 1.10e+03 3.14e-03 -5.7 4.46e+01 - 1.00e+00 1.00e+00h 1\n", - " 17 5.8218452e-04 5.20e+01 3.71e-03 -5.7 8.13e-01 -5.5 1.00e+00 1.00e+00h 1\n", - " 18 5.7458515e-04 1.00e+02 5.22e-03 -5.7 5.02e+01 - 1.00e+00 1.00e+00h 1\n", - " 19 5.7457556e-04 1.35e+00 1.01e-05 -5.7 5.55e-02 -6.0 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 4.9236271e-04 9.88e+03 1.23e-03 -5.7 3.68e+02 - 1.00e+00 1.00e+00h 1\n", - " 21 4.9222078e-04 4.82e+02 8.56e-05 -5.7 8.57e+01 - 1.00e+00 1.00e+00h 1\n", - " 22 4.9093828e-04 4.03e+01 1.21e-04 -5.7 2.08e+03 - 1.00e+00 1.00e+00h 1\n", - " 23 4.8572903e-04 4.33e+01 1.35e-04 -5.7 2.07e+03 - 1.00e+00 1.00e+00h 1\n", - " 24 4.8575737e-04 2.16e-01 6.61e-08 -5.7 1.22e+01 - 1.00e+00 1.00e+00h 1\n", - " 25 4.8575673e-04 2.44e-07 1.84e-11 -5.7 8.60e-02 - 1.00e+00 1.00e+00h 1\n", - " 26 4.8561981e-04 2.68e+00 2.47e-07 -8.6 6.22e+01 - 9.97e-01 1.00e+00h 1\n", - " 27 4.8561869e-04 2.40e-04 8.17e-10 -8.6 1.92e-01 - 1.00e+00 1.00e+00h 1\n", - " 28 4.8561869e-04 1.02e-10 2.51e-14 -8.6 8.03e-05 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 28\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 4.8561869050371405e-04 4.8561869050371405e-04\n", - "Dual infeasibility......: 2.5059195075060174e-14 2.5059195075060174e-14\n", - "Constraint violation....: 1.4104644499482425e-11 1.0186340659856796e-10\n", - "Complementarity.........: 2.5059035596971493e-09 2.5059035596971493e-09\n", - "Overall NLP error.......: 2.5059035596971493e-09 2.5059035596971493e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 41\n", - "Number of objective gradient evaluations = 29\n", - "Number of equality constraint evaluations = 41\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 29\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 28\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.134\n", - "Total CPU secs in NLP function evaluations = 0.037\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 10950\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 6600\n", - "\n", - "Total number of variables............................: 2952\n", - " variables with only lower bounds: 150\n", - " variables with lower and upper bounds: 600\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 2950\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 6.0080157e-03 5.63e+02 9.87e-09 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 8.5722553e-04 1.44e+03 1.64e+01 -1.0 1.37e+04 - 9.82e-01 1.00e+00h 1\n", - " 2 1.2633817e-03 1.09e+04 1.34e+01 -1.0 3.20e+03 - 5.07e-01 2.50e-01h 3\n", - " 3 1.2582351e-03 1.05e+04 3.85e+01 -1.0 3.56e+02 -4.0 8.15e-01 1.25e-01h 4\n", - " 4 1.2580167e-03 1.05e+04 3.80e+01 -1.0 3.11e+02 -4.5 9.91e-01 1.17e-02h 6\n", - " 5 1.0516690e-03 9.87e+03 3.55e+01 -1.0 9.47e+03 - 9.10e-01 6.25e-02h 5\n", - " 6 1.0548808e-03 1.01e+04 3.59e+01 -1.0 2.88e+02 -5.0 5.26e-01 3.59e-02h 5\n", - " 7 1.0571437e-03 1.01e+04 3.61e+01 -1.0 2.78e+02 -4.5 3.75e-01 1.40e-02h 6\n", - " 8 1.0572387e-03 1.01e+04 3.62e+01 -1.0 5.65e+02 -3.2 1.37e-01 2.97e-04h 9\n", - " 9r 1.0572387e-03 1.01e+04 9.99e+02 1.5 0.00e+00 -2.8 0.00e+00 2.63e-07R 17\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10r 1.0573932e-03 8.08e+03 9.89e+02 1.5 3.50e+04 - 9.65e-01 9.97e-04f 1\n", - " 11 5.4743818e-03 2.51e+03 2.04e-01 -1.0 4.23e+03 - 1.00e+00 1.00e+00h 1\n", - " 12 3.7555091e-03 1.51e+03 3.72e-01 -1.0 1.17e+04 - 1.00e+00 1.00e+00h 1\n", - " 13 1.7570808e-03 1.36e+03 4.49e-01 -1.0 1.40e+04 - 1.00e+00 1.00e+00h 1\n", - " 14 1.5819722e-03 1.92e+01 3.66e-03 -1.0 1.10e+03 - 1.00e+00 1.00e+00h 1\n", - " 15 1.5644793e-03 1.61e-02 4.40e-04 -2.5 4.36e+01 - 1.00e+00 1.00e+00h 1\n", - " 16 1.1694177e-03 9.29e+00 3.51e-04 -3.8 2.13e+02 - 1.00e+00 1.00e+00h 1\n", - " 17 7.0567043e-04 5.23e+01 6.11e-05 -3.8 4.96e+02 - 1.00e+00 1.00e+00h 1\n", - " 18 7.0531544e-04 3.55e+00 1.29e-07 -3.8 5.48e+00 - 1.00e+00 1.00e+00h 1\n", - " 19 7.0529502e-04 4.85e-04 1.50e-09 -3.8 5.06e-02 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 6.8853990e-04 1.31e+01 8.02e-06 -5.7 9.38e+01 - 1.00e+00 1.00e+00h 1\n", - " 21 6.8852757e-04 2.45e-02 8.20e-04 -5.7 5.34e-02 -3.3 1.00e+00 1.00e+00h 1\n", - " 22 6.8807586e-04 5.94e-01 3.29e-03 -5.7 2.36e+00 - 1.00e+00 1.00e+00h 1\n", - " 23 6.8807572e-04 2.14e-05 7.42e-08 -5.7 3.96e-04 -3.7 1.00e+00 1.00e+00h 1\n", - " 24 6.6490277e-04 2.56e+03 7.60e-04 -8.6 6.52e+01 - 8.94e-01 1.00e+00h 1\n", - " 25 6.6477232e-04 1.95e+02 1.39e-01 -8.6 7.44e-01 -4.2 9.62e-01 1.00e+00h 1\n", - " 26 6.6446306e-04 1.44e-02 3.66e-03 -8.6 1.10e+00 -4.7 1.00e+00 1.00e+00h 1\n", - " 27 6.6415739e-04 9.02e-01 3.01e-03 -8.6 7.94e+01 - 1.00e+00 2.50e-01h 3\n", - " 28 6.6383285e-04 1.90e-02 1.58e-03 -8.6 8.93e+00 - 1.00e+00 1.00e+00h 1\n", - " 29 6.5357918e-04 1.36e+02 1.65e-05 -8.6 4.26e+01 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30 6.5352437e-04 1.54e+00 5.29e-04 -8.6 2.59e-01 -5.2 1.00e+00 1.00e+00h 1\n", - " 31 6.4998430e-04 1.75e+01 1.81e-03 -8.6 2.78e+01 - 1.00e+00 1.00e+00h 1\n", - " 32 6.4997930e-04 3.63e-02 2.17e-06 -8.6 2.22e-02 -5.6 1.00e+00 1.00e+00h 1\n", - " 33 6.2054908e-04 1.52e+03 5.23e-04 -8.6 1.82e+02 - 1.00e+00 1.00e+00h 1\n", - " 34 6.1137893e-04 5.82e+01 1.92e-05 -8.6 6.74e+02 - 1.00e+00 1.00e+00h 1\n", - " 35 6.1139917e-04 2.14e+01 2.07e-05 -8.6 1.70e+02 - 1.00e+00 1.00e+00h 1\n", - " 36 6.1140523e-04 2.17e+00 1.98e-05 -8.6 7.30e+01 - 1.00e+00 1.00e+00h 1\n", - " 37 6.1136621e-04 2.93e+00 1.89e-05 -8.6 7.65e+01 - 1.00e+00 1.00e+00h 1\n", - " 38 6.1134451e-04 2.20e+00 9.34e-06 -8.6 7.66e+01 - 1.00e+00 5.00e-01h 2\n", - " 39 6.1140965e-04 4.40e-01 1.78e-05 -8.6 3.03e+01 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 40 6.1157432e-04 1.35e-01 1.76e-05 -8.6 6.77e+01 - 1.00e+00 1.00e+00H 1\n", - " 41 6.1153319e-04 1.97e-02 2.04e-05 -8.6 7.66e+01 - 1.00e+00 1.00e+00H 1\n", - " 42 6.1158272e-04 6.23e-03 1.99e-05 -8.6 7.80e+01 - 1.00e+00 1.00e+00H 1\n", - " 43 6.1153325e-04 2.02e-02 2.04e-05 -8.6 7.77e+01 - 1.00e+00 1.00e+00H 1\n", - " 44 6.1158277e-04 1.70e-04 1.99e-05 -8.6 7.80e+01 - 1.00e+00 1.00e+00H 1\n", - " 45 6.1153325e-04 2.02e-02 2.04e-05 -8.6 7.77e+01 - 1.00e+00 1.00e+00H 1\n", - " 46 6.1158276e-04 1.70e-04 1.99e-05 -8.6 7.80e+01 - 1.00e+00 1.00e+00H 1\n", - " 47 6.1153986e-04 4.28e-03 2.04e-05 -8.6 7.77e+01 - 1.00e+00 1.00e+00H 1\n", - " 48 6.1136587e-04 2.98e+00 1.91e-05 -8.6 7.81e+01 - 1.00e+00 1.00e+00h 1\n", - " 49 6.1140692e-04 2.96e+00 1.99e-05 -8.6 7.67e+01 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 50 6.1136628e-04 2.95e+00 1.89e-05 -8.6 7.66e+01 - 1.00e+00 1.00e+00h 1\n", - " 51 6.1140692e-04 2.96e+00 1.99e-05 -8.6 7.66e+01 - 1.00e+00 1.00e+00h 1\n", - " 52 6.1136628e-04 2.95e+00 1.89e-05 -8.6 7.66e+01 - 1.00e+00 1.00e+00h 1\n", - " 53 6.1134454e-04 2.22e+00 9.35e-06 -8.6 7.66e+01 - 1.00e+00 5.00e-01h 2\n", - " 54 6.1140964e-04 4.40e-01 1.78e-05 -8.6 3.03e+01 - 1.00e+00 1.00e+00h 1\n", - " 55 6.1157797e-04 1.06e-04 1.76e-05 -8.6 6.77e+01 - 1.00e+00 1.00e+00H 1\n", - " 56 6.1153319e-04 1.99e-02 2.04e-05 -8.6 7.66e+01 - 1.00e+00 1.00e+00H 1\n", - " 57 6.1140577e-04 7.49e-01 9.39e-06 -8.6 7.80e+01 - 1.00e+00 5.00e-01h 2\n", - " 58 6.1141057e-04 3.99e-01 1.75e-05 -8.6 2.83e+01 - 1.00e+00 1.00e+00h 1\n", - " 59 6.1136613e-04 2.16e+00 1.62e-05 -8.6 6.61e+01 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 60 6.1153978e-04 3.98e-03 2.04e-05 -8.6 7.54e+01 - 1.00e+00 1.00e+00H 1\n", - " 61 6.1158277e-04 4.45e-06 1.99e-05 -8.6 7.81e+01 - 1.00e+00 1.00e+00H 1\n", - " 62 6.1153325e-04 2.02e-02 2.04e-05 -8.6 7.77e+01 - 1.00e+00 1.00e+00H 1\n", - " 63 6.1140578e-04 7.48e-01 9.39e-06 -8.6 7.80e+01 - 1.00e+00 5.00e-01h 2\n", - " 64 6.1141057e-04 3.98e-01 1.75e-05 -8.6 2.83e+01 - 1.00e+00 1.00e+00h 1\n", - " 65 6.1136613e-04 2.16e+00 1.62e-05 -8.6 6.61e+01 - 1.00e+00 1.00e+00h 1\n", - " 66 6.1153978e-04 3.98e-03 2.04e-05 -8.6 7.54e+01 - 1.00e+00 1.00e+00H 1\n", - " 67 6.1146340e-04 1.89e-01 1.52e-05 -8.6 7.81e+01 - 1.00e+00 2.50e-01h 3\n", - " 68 6.1136908e-04 1.28e+00 2.10e-05 -8.6 5.08e+01 - 1.00e+00 1.00e+00h 1\n", - " 69 6.1153274e-04 2.89e-02 2.03e-05 -8.6 6.87e+01 - 1.00e+00 1.00e+00H 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 70 6.1158272e-04 3.79e-06 1.99e-05 -8.6 7.79e+01 - 1.00e+00 1.00e+00H 1\n", - " 71 6.1154015e-04 1.15e-04 2.04e-05 -8.6 7.77e+01 - 1.00e+00 1.00e+00H 1\n", - " 72 6.1146366e-04 1.86e-01 1.52e-05 -8.6 7.81e+01 - 1.00e+00 2.50e-01h 3\n", - " 73 6.1139783e-04 4.12e-01 1.05e-05 -8.6 5.08e+01 - 1.00e+00 5.00e-01h 2\n", - " 74 6.1152026e-04 3.04e-02 1.95e-05 -8.6 4.04e+01 - 1.00e+00 1.00e+00H 1\n", - " 75 6.1145164e-04 1.93e-01 1.44e-05 -8.6 7.46e+01 - 1.00e+00 2.50e-01h 3\n", - " 76 6.1137370e-04 8.95e-01 2.80e-05 -8.6 4.25e+01 - 1.00e+00 1.00e+00h 1\n", - " 77 6.1153859e-04 3.06e-03 2.03e-05 -8.6 6.27e+01 - 1.00e+00 1.00e+00H 1\n", - " 78 6.1158269e-04 3.43e-06 2.00e-05 -8.6 7.78e+01 - 1.00e+00 1.00e+00H 1\n", - " 79 6.1154015e-04 1.15e-04 2.04e-05 -8.6 7.77e+01 - 1.00e+00 1.00e+00H 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 80 6.1149916e-04 4.65e-02 1.78e-05 -8.6 7.81e+01 - 1.00e+00 1.25e-01h 4\n", - " 81 6.1144145e-04 1.74e-01 1.25e-05 -8.6 6.73e+01 - 1.00e+00 2.50e-01h 3\n", - " 82 6.1141053e-04 9.99e-02 3.32e-05 -8.6 1.41e+01 - 1.00e+00 1.00e+00h 1\n", - " 83 6.1140894e-04 5.39e-01 1.81e-05 -8.6 3.26e+01 - 1.00e+00 1.00e+00h 1\n", - " 84 6.1136603e-04 2.38e+00 1.91e-05 -8.6 6.93e+01 - 1.00e+00 1.00e+00h 1\n", - " 85 6.1153324e-04 2.85e-02 2.04e-05 -8.6 7.59e+01 - 1.00e+00 1.00e+00H 1\n", - " 86 6.1158272e-04 6.24e-03 1.99e-05 -8.6 7.80e+01 - 1.00e+00 1.00e+00H 1\n", - " 87 6.1153325e-04 2.02e-02 2.04e-05 -8.6 7.77e+01 - 1.00e+00 1.00e+00H 1\n", - " 88 6.1158277e-04 1.70e-04 1.99e-05 -8.6 7.80e+01 - 1.00e+00 1.00e+00H 1\n", - " 89 6.1153325e-04 2.02e-02 2.04e-05 -8.6 7.77e+01 - 1.00e+00 1.00e+00H 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 90 6.1158234e-04 9.64e-04 1.99e-05 -8.6 7.80e+01 - 1.00e+00 1.00e+00H 1\n", - " 91 6.1153997e-04 4.29e-03 2.04e-05 -8.6 7.77e+01 - 1.00e+00 1.00e+00H 1\n", - " 92 6.1136587e-04 2.98e+00 1.91e-05 -8.6 7.81e+01 - 1.00e+00 1.00e+00h 1\n", - " 93 6.1140692e-04 2.96e+00 1.99e-05 -8.6 7.67e+01 - 1.00e+00 1.00e+00h 1\n", - " 94 6.1136628e-04 2.95e+00 1.89e-05 -8.6 7.66e+01 - 1.00e+00 1.00e+00h 1\n", - " 95 6.1140692e-04 2.96e+00 1.99e-05 -8.6 7.66e+01 - 1.00e+00 1.00e+00h 1\n", - " 96 6.1136628e-04 2.95e+00 1.89e-05 -8.6 7.66e+01 - 1.00e+00 1.00e+00h 1\n", - " 97 6.1134454e-04 2.22e+00 9.35e-06 -8.6 7.66e+01 - 1.00e+00 5.00e-01h 2\n", - " 98 6.1140964e-04 4.40e-01 1.78e-05 -8.6 3.03e+01 - 1.00e+00 1.00e+00h 1\n", - " 99 6.1157794e-04 4.40e-03 1.76e-05 -8.6 6.77e+01 - 1.00e+00 1.00e+00H 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 100 6.1153319e-04 1.99e-02 2.04e-05 -8.6 7.66e+01 - 1.00e+00 1.00e+00H 1\n", - " 101 6.1158276e-04 1.70e-04 1.99e-05 -8.6 7.80e+01 - 1.00e+00 1.00e+00H 1\n", - " 102 6.1153325e-04 2.02e-02 2.04e-05 -8.6 7.77e+01 - 1.00e+00 1.00e+00H 1\n", - " 103 6.1140578e-04 7.48e-01 9.39e-06 -8.6 7.80e+01 - 1.00e+00 5.00e-01h 2\n", - " 104 6.1141057e-04 3.98e-01 1.75e-05 -8.6 2.83e+01 - 1.00e+00 1.00e+00h 1\n", - " 105 6.1136613e-04 2.16e+00 1.62e-05 -8.6 6.61e+01 - 1.00e+00 1.00e+00h 1\n", - " 106 6.1153321e-04 2.82e-02 2.04e-05 -8.6 7.54e+01 - 1.00e+00 1.00e+00H 1\n", - " 107 6.1158272e-04 6.23e-03 1.99e-05 -8.6 7.80e+01 - 1.00e+00 1.00e+00H 1\n", - " 108 6.1153986e-04 4.28e-03 2.04e-05 -8.6 7.77e+01 - 1.00e+00 1.00e+00H 1\n", - " 109 6.1158278e-04 1.71e-04 1.99e-05 -8.6 7.81e+01 - 1.00e+00 1.00e+00H 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 110 6.1153325e-04 2.02e-02 2.04e-05 -8.6 7.77e+01 - 1.00e+00 1.00e+00H 1\n", - " 111 6.1158277e-04 1.71e-04 1.99e-05 -8.6 7.80e+01 - 1.00e+00 1.00e+00H 1\n", - " 112 6.1154015e-04 1.15e-04 2.04e-05 -8.6 7.77e+01 - 1.00e+00 1.00e+00H 1\n", - " 113 6.1140911e-04 7.43e-01 9.39e-06 -8.6 7.81e+01 - 1.00e+00 5.00e-01h 2\n", - " 114 6.1141062e-04 3.96e-01 1.74e-05 -8.6 2.82e+01 - 1.00e+00 1.00e+00h 1\n", - " 115 6.1136614e-04 2.16e+00 1.62e-05 -8.6 6.60e+01 - 1.00e+00 1.00e+00h 1\n", - " 116 6.1153978e-04 3.98e-03 2.04e-05 -8.6 7.54e+01 - 1.00e+00 1.00e+00H 1\n", - " 117 6.1158277e-04 5.27e-06 1.99e-05 -8.6 7.81e+01 - 1.00e+00 1.00e+00H 1\n", - " 118 6.1154015e-04 1.15e-04 2.04e-05 -8.6 7.77e+01 - 1.00e+00 1.00e+00H 1\n", - " 119 6.1146366e-04 1.86e-01 1.52e-05 -8.6 7.81e+01 - 1.00e+00 2.50e-01h 3\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 120 6.1136906e-04 1.28e+00 2.10e-05 -8.6 5.08e+01 - 1.00e+00 1.00e+00h 1\n", - " 121 6.1153274e-04 2.89e-02 2.03e-05 -8.6 6.88e+01 - 1.00e+00 1.00e+00H 1\n", - " 122 6.1145830e-04 2.07e-01 1.51e-05 -8.6 7.79e+01 - 1.00e+00 2.50e-01h 3\n", - " 123 6.1136923e-04 1.26e+00 2.13e-05 -8.6 5.04e+01 - 1.00e+00 1.00e+00h 1\n", - " 124 6.1153926e-04 3.45e-03 2.04e-05 -8.6 6.85e+01 - 1.00e+00 1.00e+00H 1\n", - " 125 6.1158274e-04 3.65e-06 2.00e-05 -8.6 7.80e+01 - 1.00e+00 1.00e+00H 1\n", - " 126 6.1154017e-04 7.21e-06 2.04e-05 -8.6 7.77e+01 - 1.00e+00 1.00e+00H 1\n", - " 127 6.1140912e-04 7.43e-01 9.39e-06 -8.6 7.81e+01 - 1.00e+00 5.00e-01h 2\n", - " 128 6.1141062e-04 3.96e-01 1.74e-05 -8.6 2.82e+01 - 1.00e+00 1.00e+00h 1\n", - " 129 6.1135721e-04 7.36e-01 8.57e-06 -8.6 6.60e+01 - 1.00e+00 5.00e-01h 2\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 130 6.1151776e-04 2.83e-02 1.94e-05 -8.6 3.87e+01 - 1.00e+00 1.00e+00H 1\n", - " 131 6.1140252e-04 6.82e-01 9.31e-06 -8.6 7.39e+01 - 1.00e+00 5.00e-01h 2\n", - " 132 6.1140878e-04 5.46e-01 1.82e-05 -8.6 3.31e+01 - 1.00e+00 1.00e+00h 1\n", - " 133 6.1157935e-04 2.36e-06 1.83e-05 -8.6 6.96e+01 - 1.00e+00 1.00e+00H 1\n", - " 134 6.1153320e-04 2.00e-02 2.04e-05 -8.6 7.69e+01 - 1.00e+00 1.00e+00H 1\n", - " 135 6.1145855e-04 1.96e-01 1.52e-05 -8.6 7.80e+01 - 1.00e+00 2.50e-01h 3\n", - " 136 6.1139544e-04 4.15e-01 1.06e-05 -8.6 5.06e+01 - 1.00e+00 5.00e-01h 2\n", - " 137 6.1152568e-04 1.55e-03 1.95e-05 -8.6 4.04e+01 - 1.00e+00 1.00e+00H 1\n", - " 138 6.1136582e-04 2.73e+00 1.87e-05 -8.6 7.47e+01 - 1.00e+00 1.00e+00h 1\n", - " 139 6.1154017e-04 1.31e-04 2.04e-05 -8.6 7.65e+01 - 1.00e+00 1.00e+00H 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 140 6.1158278e-04 3.72e-06 2.00e-05 -8.6 7.81e+01 - 1.00e+00 1.00e+00H 1\n", - " 141 6.1154015e-04 1.15e-04 2.04e-05 -8.6 7.77e+01 - 1.00e+00 1.00e+00H 1\n", - " 142 6.1146366e-04 1.86e-01 1.52e-05 -8.6 7.81e+01 - 1.00e+00 2.50e-01h 3\n", - " 143 6.1136906e-04 1.28e+00 2.10e-05 -8.6 5.08e+01 - 1.00e+00 1.00e+00h 1\n", - " 144 6.1153960e-04 1.32e-04 2.04e-05 -8.6 6.88e+01 - 1.00e+00 1.00e+00H 1\n", - " 145 6.1146336e-04 1.85e-01 1.52e-05 -8.6 7.80e+01 - 1.00e+00 2.50e-01h 3\n", - " 146 6.1136917e-04 1.27e+00 2.11e-05 -8.6 5.05e+01 - 1.00e+00 1.00e+00h 1\n", - " 147 6.1153959e-04 1.32e-04 2.04e-05 -8.6 6.86e+01 - 1.00e+00 1.00e+00H 1\n", - " 148 6.1158274e-04 6.22e-06 2.00e-05 -8.6 7.80e+01 - 1.00e+00 1.00e+00H 1\n", - " 149 6.1154015e-04 1.15e-04 2.04e-05 -8.6 7.77e+01 - 1.00e+00 1.00e+00H 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 150 6.1149916e-04 4.65e-02 1.78e-05 -8.6 7.81e+01 - 1.00e+00 1.25e-01h 4\n", - " 151 6.1136594e-04 2.22e+00 1.55e-05 -8.6 6.73e+01 - 1.00e+00 1.00e+00h 1\n", - " 152 6.1154011e-04 1.31e-04 2.04e-05 -8.6 7.56e+01 - 1.00e+00 1.00e+00H 1\n", - " 153 6.1151894e-04 1.17e-02 1.91e-05 -8.6 7.81e+01 - 1.00e+00 6.25e-02h 5\n", - " 154 6.1145201e-04 1.71e-01 1.41e-05 -8.6 7.29e+01 - 1.00e+00 2.50e-01h 3\n", - " 155 6.1137834e-04 6.75e-01 3.46e-05 -8.6 3.69e+01 - 1.00e+00 1.00e+00h 1\n", - " 156 6.1153809e-04 1.22e-04 2.03e-05 -8.6 5.81e+01 - 1.00e+00 1.00e+00H 1\n", - " 157 6.1158264e-04 3.63e-06 2.00e-05 -8.6 7.76e+01 - 1.00e+00 1.00e+00H 1\n", - " 158 6.1154015e-04 1.16e-04 2.04e-05 -8.6 7.77e+01 - 1.00e+00 1.00e+00H 1\n", - " 159 6.1151897e-04 1.17e-02 1.91e-05 -8.6 7.81e+01 - 1.00e+00 6.25e-02h 5\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 160 6.1148311e-04 5.08e-02 1.67e-05 -8.6 7.29e+01 - 1.00e+00 1.25e-01h 4\n", - " 161 6.1143343e-04 1.55e-01 8.29e-06 -8.6 6.17e+01 - 1.00e+00 2.50e-01h 3\n", - " 162 6.1143330e-04 1.91e-03 4.74e-06 -8.6 1.91e+00 - 1.00e+00 1.00e+00h 1\n", - " 163 6.1143478e-04 6.26e-05 2.80e-07 -8.6 4.72e-01 - 1.00e+00 1.00e+00h 1\n", - " 164 6.1143483e-04 2.15e-07 2.06e-09 -8.6 2.06e-02 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 164\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 6.1143483258912969e-04 6.1143483258912969e-04\n", - "Dual infeasibility......: 2.0643051633861799e-09 2.0643051633861799e-09\n", - "Constraint violation....: 9.0993523826909950e-09 2.1496089175343511e-07\n", - "Complementarity.........: 2.5059035596800626e-09 2.5059035596800626e-09\n", - "Overall NLP error.......: 9.0993523826909950e-09 2.1496089175343511e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 524\n", - "Number of objective gradient evaluations = 165\n", - "Number of equality constraint evaluations = 524\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 166\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 164\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.578\n", - "Total CPU secs in NLP function evaluations = 0.189\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 10950\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 6600\n", - "\n", - "Total number of variables............................: 2952\n", - " variables with only lower bounds: 150\n", - " variables with lower and upper bounds: 600\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 2950\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.6010954e-03 5.63e+02 1.15e-08 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 1.0194432e-03 1.46e+03 1.64e+01 -1.0 1.37e+04 - 9.82e-01 1.00e+00h 1\n", - " 2 1.2968158e-03 7.43e+03 1.27e+01 -1.0 2.57e+03 - 5.93e-01 2.50e-01h 3\n", - " 3 1.2957916e-03 7.38e+03 1.26e+01 -1.0 3.56e+02 -4.0 5.72e-01 2.47e-02h 6\n", - " 4 1.2957789e-03 7.38e+03 1.26e+01 -1.0 3.47e+02 -3.6 5.33e-01 1.55e-03h 8\n", - " 5 1.2957646e-03 7.38e+03 1.26e+01 -1.0 3.46e+02 -3.1 8.24e-02 2.63e-04h 9\n", - " 6 7.4442110e-04 1.85e+03 3.03e+01 -1.0 9.55e+02 - 9.91e-01 1.00e+00h 1\n", - " 7 7.6477769e-04 4.66e+02 2.31e+02 -1.0 1.53e+02 -3.6 1.00e+00 1.00e+00h 1\n", - " 8 7.6400461e-04 5.98e+01 7.46e+01 -1.0 3.16e+00 -4.1 1.00e+00 1.00e+00h 1\n", - " 9 7.6408251e-04 2.28e-01 9.01e-02 -1.0 1.53e+00 -4.6 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 8.3823379e-04 4.85e+03 6.08e-01 -2.5 1.78e+03 - 8.50e-01 1.00e+00h 1\n", - " 11 7.7103878e-04 4.89e+01 2.13e-02 -2.5 1.63e+03 - 1.00e+00 1.00e+00h 1\n", - " 12 9.0641450e-04 1.02e+03 1.14e-02 -2.5 6.30e+02 - 1.00e+00 5.00e-01h 2\n", - " 13 1.3694856e-03 5.62e+02 3.12e-04 -2.5 3.29e+02 - 1.00e+00 1.00e+00h 1\n", - " 14 1.3411507e-03 1.12e+02 1.32e-05 -2.5 1.71e+01 - 1.00e+00 1.00e+00h 1\n", - " 15 1.3408428e-03 1.03e-01 2.83e-08 -2.5 1.60e+00 - 1.00e+00 1.00e+00h 1\n", - " 16 1.0823198e-03 5.95e+00 2.79e-04 -3.8 1.67e+02 - 1.00e+00 1.00e+00h 1\n", - " 17 7.6039054e-04 3.34e+01 3.80e-05 -3.8 3.91e+02 - 1.00e+00 1.00e+00h 1\n", - " 18 7.5982215e-04 1.49e+00 5.09e-08 -3.8 3.32e+00 - 1.00e+00 1.00e+00h 1\n", - " 19 7.5981362e-04 8.21e-05 1.50e-09 -3.8 2.34e-02 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 7.3964780e-04 1.39e+01 9.07e-06 -5.7 1.04e+02 - 1.00e+00 1.00e+00h 1\n", - " 21 7.3962506e-04 2.05e-02 1.45e-05 -5.7 6.41e-02 -5.1 1.00e+00 1.00e+00h 1\n", - " 22 7.2459137e-04 9.99e+02 2.60e-03 -5.7 4.55e+01 - 1.00e+00 1.00e+00h 1\n", - " 23 7.2438652e-04 3.72e+01 2.62e-03 -5.7 6.97e-01 -5.5 1.00e+00 1.00e+00h 1\n", - " 24 7.2133779e-04 3.72e+01 2.68e-03 -5.7 3.72e+01 - 1.00e+00 1.00e+00h 1\n", - " 25 7.2133543e-04 2.07e-01 1.28e-06 -5.7 7.89e-03 -6.0 1.00e+00 1.00e+00h 1\n", - " 26 6.7907673e-04 8.57e+03 4.30e-04 -5.7 3.04e+02 - 1.00e+00 1.00e+00h 1\n", - " 27 6.8326626e-04 6.82e+02 1.32e-04 -5.7 5.22e+02 - 1.00e+00 1.00e+00h 1\n", - " 28 6.7339163e-04 9.37e+00 3.98e-06 -5.7 1.41e+02 - 1.00e+00 1.00e+00h 1\n", - " 29 6.7297155e-04 3.98e-02 7.00e-09 -5.7 3.04e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30 6.7297139e-04 5.28e-08 1.84e-11 -5.7 3.25e-03 - 1.00e+00 1.00e+00h 1\n", - " 31 6.7282315e-04 4.00e+00 2.48e-07 -8.6 6.59e+01 - 9.97e-01 1.00e+00h 1\n", - " 32 6.7281999e-04 2.40e-03 1.50e-10 -8.6 7.35e-01 - 1.00e+00 1.00e+00h 1\n", - " 33 6.7281999e-04 4.66e-10 2.51e-14 -8.6 3.38e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 33\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 6.7281998558273008e-04 6.7281998558273008e-04\n", - "Dual infeasibility......: 2.5059195075060174e-14 2.5059195075060174e-14\n", - "Constraint violation....: 1.4104644499482425e-11 4.6566128730773926e-10\n", - "Complementarity.........: 2.5059035601133969e-09 2.5059035601133969e-09\n", - "Overall NLP error.......: 2.5059035601133969e-09 2.5059035601133969e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 67\n", - "Number of objective gradient evaluations = 34\n", - "Number of equality constraint evaluations = 67\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 34\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 33\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.134\n", - "Total CPU secs in NLP function evaluations = 0.031\n", - "\n", - "EXIT: Optimal Solution Found.\n" - ] - }, - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
fs.properties.tau[benzene,toluene]fs.properties.tau[toluene,benzene]
0-0.8415221.267428
1-0.9478471.511261
2-0.9072451.426084
3-0.8692041.360484
\n", - "
" - ], - "text/plain": [ - " fs.properties.tau[benzene,toluene] fs.properties.tau[toluene,benzene]\n", - "0 -0.841522 1.267428\n", - "1 -0.947847 1.511261\n", - "2 -0.907245 1.426084\n", - "3 -0.869204 1.360484" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "bootstrap_theta_new = pest_new.theta_est_bootstrap(4)\n", - "display(bootstrap_theta_new)" + "# bootstrap_theta = pest.theta_est_bootstrap(4, seed=542)\n", + "# display(bootstrap_theta)" ] } ], "metadata": { "celltoolbar": "Tags", "kernelspec": { - "display_name": "idaes-examples-dev-py313-macmini", + "display_name": "idaes-pse-and-examples-dev-py313-macmini", "language": "python", "name": "python3" }, From fd07b69fb60c1fe4a4acc74f656a9b1783057edf Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Thu, 11 Jun 2026 12:43:04 -0400 Subject: [PATCH 11/23] All primary notebooks updated, ran black. --- ...er_estimation_nrtl_using_state_block.ipynb | 868 +++--------------- ...ter_estimation_nrtl_using_unit_model.ipynb | 59 +- .../properties/parameter_estimation_pr.ipynb | 408 +++++--- 3 files changed, 427 insertions(+), 908 deletions(-) diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block.ipynb index cb184a96..70ef705e 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block.ipynb @@ -16,7 +16,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", @@ -32,8 +32,8 @@ "# Parameter Estimation Using the NRTL State Block\n", "\n", "Author: Jaffer Ghouse \n", - "Maintainer: Andrew Lee \n", - "Updated: 2023-06-01 \n", + "Maintainer: Stephen Cini \n", + "Updated: 2026-06-11 \n", "\n", "In this module, we use Pyomo's `parmest` tool in conjunction with IDAES models for parameter estimation. We demonstrate these tools by estimating the parameters associated with the NRTL property model for a benzene-toluene mixture. The NRTL model has 2 sets of parameters: the non-randomness parameter (`alpha_ij`) and the binary interaction parameter (`tau_ij`), where `i` and `j` are the pure component species. In this example, we only estimate the binary interaction parameter (`tau_ij`) for a given dataset. 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 only the state block. \n", "\n", @@ -54,7 +54,7 @@ "source": [ "
\n", "Inline Exercise:\n", - "import `ConcreteModel` from Pyomo and `FlowsheetBlock` from IDAES. \n", + "import `ConcreteModel`, `value`, and `Suffix` from Pyomo, `FlowsheetBlock` and `Flash` from IDAES. \n", "
" ] }, @@ -68,7 +68,7 @@ }, "outputs": [], "source": [ - "# Todo: import ConcreteModel from pyomo.environ\n", + "# Todo: import ConcreteModel, value, and Suffix from pyomo.environ\n", "\n", "# Todo: import FlowsheetBlock from idaes.core" ] @@ -83,11 +83,14 @@ }, "outputs": [], "source": [ - "# Todo: import ConcreteModel from pyomo.environ\n", - "import pyomo.environ as pyo\n", + "# Todo: import ConcreteModel, value, and Suffix from pyomo.environ\n", + "from pyomo.environ import ConcreteModel, value, Suffix\n", "\n", "# Todo: import FlowsheetBlock from idaes.core\n", - "from idaes.core import FlowsheetBlock" + "from idaes.core import FlowsheetBlock\n", + "\n", + "# Todo: import Flash unit model from idaes.models.unit_models\n", + "from idaes.models.unit_models import Flash" ] }, { @@ -228,7 +231,7 @@ "def NRTL_model(data):\n", "\n", " # Todo: Create a ConcreteModel object\n", - " m = pyo.ConcreteModel()\n", + " m = ConcreteModel()\n", "\n", " # Todo: Create FlowsheetBlock object\n", " m.fs = FlowsheetBlock(dynamic=False)\n", @@ -268,7 +271,6 @@ " m.fs.state_block.initialize(outlvl=idaeslog.INFO_LOW)\n", "\n", " # Fix at actual temperature\n", - " # Fix at actual temperature\n", " if isinstance(data, dict) or isinstance(data, pd.Series):\n", " m.fs.state_block.temperature.fix(float(data[\"temperature\"]))\n", " elif isinstance(data, pd.DataFrame):\n", @@ -309,398 +311,19 @@ "assert degrees_of_freedom(m) == 0\n", "\n", "# Check for output values\n", - "assert pyo.value(\n", - " m.fs.state_block.mole_frac_phase_comp[\"Liq\", \"benzene\"]\n", - ") == pytest.approx(0.389, abs=1e-2)\n", - "assert pyo.value(\n", - " m.fs.state_block.mole_frac_phase_comp[\"Vap\", \"benzene\"]\n", - ") == pytest.approx(0.610, abs=1e-2)\n", - "\n", - "assert pyo.value(\n", - " m.fs.state_block.mole_frac_phase_comp[\"Liq\", \"toluene\"]\n", - ") == pytest.approx(0.610, abs=1e-2)\n", - "assert pyo.value(\n", - " m.fs.state_block.mole_frac_phase_comp[\"Vap\", \"toluene\"]\n", - ") == pytest.approx(0.394, abs=1e-2)" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1 Block Declarations\n", - " fs : Size=1, Index=None, Active=True\n", - " 1 Set Declarations\n", - " _time : Size=1, Index=None, Ordered=Insertion\n", - " Key : Dimen : Domain : Size : Members\n", - " None : 1 : Any : 1 : {0.0,}\n", - "\n", - " 2 Block Declarations\n", - " properties : Size=1, Index=None, Active=True\n", - " 6 Set Declarations\n", - " _phase_component_set : Size=1, Index=None, Ordered=Insertion\n", - " Key : Dimen : Domain : Size : Members\n", - " None : 2 : Any : 4 : {('Liq', 'benzene'), ('Liq', 'toluene'), ('Vap', 'benzene'), ('Vap', 'toluene')}\n", - " component_list : Size=1, Index=None, Ordered=Insertion\n", - " Key : Dimen : Domain : Size : Members\n", - " None : 1 : Any : 2 : {'benzene', 'toluene'}\n", - " component_list_master : Size=1, Index=None, Ordered=Insertion\n", - " Key : Dimen : Domain : Size : Members\n", - " None : 1 : Any : 3 : {'benzene', 'toluene', 'o-xylene'}\n", - " phase_equilibrium_idx : Size=1, Index=None, Ordered=Insertion\n", - " Key : Dimen : Domain : Size : Members\n", - " None : 1 : Any : 2 : {1, 2}\n", - " phase_equilibrium_idx_master : Size=1, Index=None, Ordered=Insertion\n", - " Key : Dimen : Domain : Size : Members\n", - " None : 1 : Any : 3 : {1, 2, 3}\n", - " phase_list : Size=1, Index=None, Ordered=Insertion\n", - " Key : Dimen : Domain : Size : Members\n", - " None : 1 : Any : 2 : {'Liq', 'Vap'}\n", - "\n", - " 18 Param Declarations\n", - " cp_mol_liq_comp_coeff_A : Liquid phase Cp parameter A\n", - " Size=2, Index=fs.properties.component_list, Domain=Any, Default=None, Mutable=True, Units=J/K/kmol\n", - " Key : Value\n", - " benzene : 129000.0\n", - " toluene : 140000.0\n", - " cp_mol_liq_comp_coeff_B : Liquid phase Cp parameter B\n", - " Size=2, Index=fs.properties.component_list, Domain=Any, Default=None, Mutable=True, Units=J/K**2/kmol\n", - " Key : Value\n", - " benzene : -170.0\n", - " toluene : -152.0\n", - " cp_mol_liq_comp_coeff_C : Liquid phase Cp parameter C\n", - " Size=2, Index=fs.properties.component_list, Domain=Any, Default=None, Mutable=True, Units=J/K**3/kmol\n", - " Key : Value\n", - " benzene : 0.648\n", - " toluene : 0.695\n", - " cp_mol_liq_comp_coeff_D : Liquid phase Cp parameter D\n", - " Size=2, Index=fs.properties.component_list, Domain=Any, Default=None, Mutable=True, Units=J/K**4/kmol\n", - " Key : Value\n", - " benzene : 0\n", - " toluene : 0\n", - " cp_mol_liq_comp_coeff_E : Liquid phase Cp parameter E\n", - " Size=2, Index=fs.properties.component_list, Domain=Any, Default=None, Mutable=True, Units=J/K**5/kmol\n", - " Key : Value\n", - " benzene : 0\n", - " toluene : 0\n", - " cp_mol_vap_comp_coeff_A : Vapor phase Cp parameter A\n", - " Size=2, Index=fs.properties.component_list, Domain=Any, Default=None, Mutable=True, Units=J/K/mol\n", - " Key : Value\n", - " benzene : -33.92\n", - " toluene : -24.35\n", - " cp_mol_vap_comp_coeff_B : Vapor phase Cp parameter B\n", - " Size=2, Index=fs.properties.component_list, Domain=Any, Default=None, Mutable=True, Units=J/K**2/mol\n", - " Key : Value\n", - " benzene : 0.4739\n", - " toluene : 0.5125\n", - " cp_mol_vap_comp_coeff_C : Vapor phase Cp parameter C\n", - " Size=2, Index=fs.properties.component_list, Domain=Any, Default=None, Mutable=True, Units=J/K**3/mol\n", - " Key : Value\n", - " benzene : -0.0003017\n", - " toluene : -0.0002765\n", - " cp_mol_vap_comp_coeff_D : Vapor phase Cp parameter D\n", - " Size=2, Index=fs.properties.component_list, Domain=Any, Default=None, Mutable=True, Units=J/K**4/mol\n", - " Key : Value\n", - " benzene : 7.13e-08\n", - " toluene : 4.911e-08\n", - " cp_mol_vap_comp_coeff_E : Vapor phase Cp parameter E\n", - " Size=2, Index=fs.properties.component_list, Domain=Any, Default=None, Mutable=True, Units=J/K**5/mol\n", - " Key : Value\n", - " benzene : 0\n", - " toluene : 0\n", - " dh_form : Standard heats of formation [J/mol]\n", - " Size=4, Index=fs.properties.phase_list*fs.properties.component_list, Domain=Any, Default=None, Mutable=True, Units=J/mol\n", - " Key : Value\n", - " ('Liq', 'benzene') : 49000.0\n", - " ('Liq', 'toluene') : 12000.0\n", - " ('Vap', 'benzene') : 82900.0\n", - " ('Vap', 'toluene') : 50100.0\n", - " ds_form : Standard entropy of formation [J/mol.K]\n", - " Size=4, Index=fs.properties.phase_list*fs.properties.component_list, Domain=Any, Default=None, Mutable=True, Units=J/K/mol\n", - " Key : Value\n", - " ('Liq', 'benzene') : -173\n", - " ('Liq', 'toluene') : -220\n", - " ('Vap', 'benzene') : -269\n", - " ('Vap', 'toluene') : -321\n", - " mw_comp : molecular weight kg/mol\n", - " Size=2, Index=fs.properties.component_list, Domain=Any, Default=None, Mutable=True, Units=kg/mol\n", - " Key : Value\n", - " benzene : 0.0781136\n", - " toluene : 0.0921405\n", - " pressure_critical : Critical pressure [Pa]\n", - " Size=2, Index=fs.properties.component_list, Domain=NonNegativeReals, Default=None, Mutable=True, Units=Pa\n", - " Key : Value\n", - " benzene : 4890000.0\n", - " toluene : 4100000.0\n", - " pressure_reference : Reference pressure [Pa]\n", - " Size=1, Index=None, Domain=Any, Default=101325, Mutable=True, Units=Pa\n", - " Key : Value\n", - " pressure_sat_coeff : parameters to compute P_sat\n", - " Size=8, Index=fs.properties.component_list*{A, B, C, D}, Domain=Any, Default=None, Mutable=False\n", - " Key : Value\n", - " ('benzene', 'A') : -6.98273\n", - " ('benzene', 'B') : 1.33213\n", - " ('benzene', 'C') : -2.62863\n", - " ('benzene', 'D') : -3.33399\n", - " ('toluene', 'A') : -7.28607\n", - " ('toluene', 'B') : 1.38091\n", - " ('toluene', 'C') : -2.83433\n", - " ('toluene', 'D') : -2.79168\n", - " temperature_critical : Critical temperature [K]\n", - " Size=2, Index=fs.properties.component_list, Domain=NonNegativeReals, Default=None, Mutable=True, Units=K\n", - " Key : Value\n", - " benzene : 562.2\n", - " toluene : 591.8\n", - " temperature_reference : Reference temperature [K]\n", - " Size=1, Index=None, Domain=Any, Default=298.15, Mutable=True, Units=K\n", - " Key : Value\n", - "\n", - " 2 Var Declarations\n", - " alpha : Non-randomness parameter for NRTL model\n", - " Size=4, Index=fs.properties.component_list*fs.properties.component_list\n", - " Key : Lower : Value : Upper : Fixed : Stale : Domain\n", - " ('benzene', 'benzene') : None : 0 : None : True : True : Reals\n", - " ('benzene', 'toluene') : None : 0.3 : None : True : True : Reals\n", - " ('toluene', 'benzene') : None : 0.3 : None : True : True : Reals\n", - " ('toluene', 'toluene') : None : 0 : None : True : True : Reals\n", - " tau : Binary interaction parameter for NRTL model\n", - " Size=4, Index=fs.properties.component_list*fs.properties.component_list\n", - " Key : Lower : Value : Upper : Fixed : Stale : Domain\n", - " ('benzene', 'benzene') : None : 0 : None : True : True : Reals\n", - " ('benzene', 'toluene') : -5 : -0.9 : 5 : True : True : Reals\n", - " ('toluene', 'benzene') : -5 : 1.4 : 5 : True : True : Reals\n", - " ('toluene', 'toluene') : None : 0 : None : True : True : Reals\n", - "\n", - " 4 Block Declarations\n", - " Liq : Size=1, Index=None, Active=True\n", - " 0 Declarations: \n", - " Vap : Size=1, Index=None, Active=True\n", - " 0 Declarations: \n", - " benzene : Size=1, Index=None, Active=True\n", - " 0 Declarations: \n", - " toluene : Size=1, Index=None, Active=True\n", - " 0 Declarations: \n", - "\n", - " 30 Declarations: component_list_master benzene component_list toluene Liq phase_list Vap alpha tau phase_equilibrium_idx_master phase_equilibrium_idx pressure_reference temperature_reference pressure_critical temperature_critical mw_comp cp_mol_liq_comp_coeff_A cp_mol_liq_comp_coeff_B cp_mol_liq_comp_coeff_C cp_mol_liq_comp_coeff_D cp_mol_liq_comp_coeff_E cp_mol_vap_comp_coeff_A cp_mol_vap_comp_coeff_B cp_mol_vap_comp_coeff_C cp_mol_vap_comp_coeff_D cp_mol_vap_comp_coeff_E pressure_sat_coeff dh_form ds_form _phase_component_set\n", - " state_block : Size=1, Index=None, Active=True\n", - " 2 Param Declarations\n", - " eps_1 : Smoothing parameter for equilibrium temperature\n", - " Size=1, Index=None, Domain=Any, Default=0.01, Mutable=True, Units=K\n", - " Key : Value\n", - " None : 0.01\n", - " eps_2 : Smoothing parameter for equilibrium temperature\n", - " Size=1, Index=None, Domain=Any, Default=0.0005, Mutable=True, Units=K\n", - " Key : Value\n", - " None : 0.0005\n", - "\n", - " 15 Var Declarations\n", - " A : Intermediate variable to compute activity coefficient\n", - " Size=2, Index=fs.properties.component_list\n", - " Key : Lower : Value : Upper : Fixed : Stale : Domain\n", - " benzene : None : 0.7100260859013878 : None : False : False : Reals\n", - " toluene : None : -0.4099107824679704 : None : False : False : Reals\n", - " B : Intermediate variable to compute activity coefficient\n", - " Size=2, Index=fs.properties.component_list\n", - " Key : Lower : Value : Upper : Fixed : Stale : Domain\n", - " benzene : None : -0.6995248754062293 : None : False : False : Reals\n", - " toluene : None : 0.44664023909664 : None : False : False : Reals\n", - " Gij_coeff : Gij coefficient for use in NRTL model \n", - " Size=4, Index=fs.properties.component_list*fs.properties.component_list\n", - " Key : Lower : Value : Upper : Fixed : Stale : Domain\n", - " ('benzene', 'benzene') : None : 1 : None : True : True : Reals\n", - " ('benzene', 'toluene') : None : 1.3099644507332473 : None : False : False : Reals\n", - " ('toluene', 'benzene') : None : 0.6570468198150567 : None : False : False : Reals\n", - " ('toluene', 'toluene') : None : 1 : None : True : True : Reals\n", - " _t1 : Intermediate temperature for calculating the equilibrium temperature\n", - " Size=1, Index=None, Units=K\n", - " Key : Lower : Value : Upper : Fixed : Stale : Domain\n", - " None : None : 368.0000081121381 : None : False : False : Reals\n", - " _temperature_equilibrium : Temperature for calculating phase equilibrium\n", - " Size=1, Index=None, Units=K\n", - " Key : Lower : Value : Upper : Fixed : Stale : Domain\n", - " None : None : 368.00000809159246 : None : False : False : Reals\n", - " activity_coeff_comp : Activity coefficient of component\n", - " Size=2, Index=fs.properties.component_list\n", - " Key : Lower : Value : Upper : Fixed : Stale : Domain\n", - " benzene : None : 1.010556541718034 : None : False : False : Reals\n", - " toluene : None : 1.0374123178427703 : None : False : False : Reals\n", - " flow_mol : Total molar flowrate [mol/s]\n", - " Size=1, Index=None, Units=mol/s\n", - " Key : Lower : Value : Upper : Fixed : Stale : Domain\n", - " None : 0 : 1 : None : True : True : NonNegativeReals\n", - " flow_mol_phase : Size=2, Index=fs.properties.phase_list, Units=mol/s\n", - " Key : Lower : Value : Upper : Fixed : Stale : Domain\n", - " Liq : None : 0.4895285678452709 : None : False : False : Reals\n", - " Vap : None : 0.5104714321547291 : None : False : False : Reals\n", - " mole_frac_comp : Mixture mole fraction\n", - " Size=2, Index=fs.properties.component_list\n", - " Key : Lower : Value : Upper : Fixed : Stale : Domain\n", - " benzene : 0 : 0.5 : 1 : True : True : Reals\n", - " toluene : 0 : 0.5 : 1 : True : True : Reals\n", - " mole_frac_phase_comp : Size=4, Index=fs.properties._phase_component_set\n", - " Key : Lower : Value : Upper : Fixed : Stale : Domain\n", - " ('Liq', 'benzene') : 0 : 0.3896822835079589 : 1 : False : False : Reals\n", - " ('Liq', 'toluene') : 0 : 0.6103177164920411 : 1 : False : False : Reals\n", - " ('Vap', 'benzene') : 0 : 0.6057917649390352 : 1 : False : False : Reals\n", - " ('Vap', 'toluene') : 0 : 0.3942082350609649 : 1 : False : False : Reals\n", - " pressure : State pressure [Pa]\n", - " Size=1, Index=None, Units=Pa\n", - " Key : Lower : Value : Upper : Fixed : Stale : Domain\n", - " None : 0 : 101325 : None : True : True : NonNegativeReals\n", - " pressure_sat_comp : vapor pressure\n", - " Size=2, Index=fs.properties.component_list, Units=Pa\n", - " Key : Lower : Value : Upper : Fixed : Stale : Domain\n", - " benzene : None : 155872.21194897484 : None : False : False : Reals\n", - " toluene : None : 63086.28122456876 : None : False : False : Reals\n", - " temperature : State temperature [K]\n", - " Size=1, Index=None, Units=K\n", - " Key : Lower : Value : Upper : Fixed : Stale : Domain\n", - " None : 0 : 368.0 : None : True : False : NonNegativeReals\n", - " temperature_bubble : Bubble point temperature (K)\n", - " Size=1, Index=None, Units=K\n", - " Key : Lower : Value : Upper : Fixed : Stale : Domain\n", - " None : None : 364.9182065507927 : None : False : False : Reals\n", - " temperature_dew : Dew point temperature (K)\n", - " Size=1, Index=None, Units=K\n", - " Key : Lower : Value : Upper : Fixed : Stale : Domain\n", - " None : None : 371.0420078019091 : None : False : False : Reals\n", - "\n", - " 12 Expression Declarations\n", - " A_bubble : Size=2, Index=fs.properties.component_list\n", - " Key : Expression\n", - " benzene : (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,benzene]*1 + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,benzene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))\n", - " toluene : (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,toluene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,toluene]*1)/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1)\n", - " A_dew : Size=2, Index=fs.properties.component_list\n", - " Key : Expression\n", - " benzene : (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,benzene]*1 + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,benzene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))\n", - " toluene : (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,toluene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,toluene]*1)/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1)\n", - " B_bubble : Size=2, Index=fs.properties.component_list\n", - " Key : Expression\n", - " benzene : fs.state_block.mole_frac_comp[benzene]*1/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))*(fs.properties.tau[benzene,benzene] - (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,benzene]*1 + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,benzene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))) + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene])/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1)*(fs.properties.tau[benzene,toluene] - (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,toluene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,toluene]*1)/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1))\n", - " toluene : fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene])/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))*(fs.properties.tau[toluene,benzene] - (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,benzene]*1 + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,benzene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))) + fs.state_block.mole_frac_comp[toluene]*1/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1)*(fs.properties.tau[toluene,toluene] - (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,toluene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,toluene]*1)/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1))\n", - " B_dew : Size=2, Index=fs.properties.component_list\n", - " Key : Expression\n", - " benzene : fs.state_block.mole_frac_comp[benzene]*1/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))*(fs.properties.tau[benzene,benzene] - (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,benzene]*1 + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,benzene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))) + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene])/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1)*(fs.properties.tau[benzene,toluene] - (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,toluene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,toluene]*1)/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1))\n", - " toluene : fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene])/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))*(fs.properties.tau[toluene,benzene] - (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,benzene]*1 + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,benzene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))) + fs.state_block.mole_frac_comp[toluene]*1/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1)*(fs.properties.tau[toluene,toluene] - (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,toluene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,toluene]*1)/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1))\n", - " Gij_coeff_bubble : Size=4, Index=fs.properties.component_list*fs.properties.component_list\n", - " Key : Expression\n", - " ('benzene', 'benzene') : 1.0\n", - " ('benzene', 'toluene') : exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene])\n", - " ('toluene', 'benzene') : exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene])\n", - " ('toluene', 'toluene') : 1.0\n", - " Gij_coeff_dew : Size=4, Index=fs.properties.component_list*fs.properties.component_list\n", - " Key : Expression\n", - " ('benzene', 'benzene') : 1.0\n", - " ('benzene', 'toluene') : exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene])\n", - " ('toluene', 'benzene') : exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene])\n", - " ('toluene', 'toluene') : 1.0\n", - " _p_sat_bubbleT : Size=2, Index=fs.properties.component_list\n", - " Key : Expression\n", - " benzene : fs.properties.pressure_critical[benzene]*exp((-6.98273*(1 - 1/fs.properties.temperature_critical[benzene]*fs.state_block.temperature_bubble) + 1.33213*(1 - 1/fs.properties.temperature_critical[benzene]*fs.state_block.temperature_bubble)**1.5 - 2.62863*(1 - 1/fs.properties.temperature_critical[benzene]*fs.state_block.temperature_bubble)**3 - 3.33399*(1 - 1/fs.properties.temperature_critical[benzene]*fs.state_block.temperature_bubble)**6)/(1 - (1 - 1/fs.properties.temperature_critical[benzene]*fs.state_block.temperature_bubble)))\n", - " toluene : fs.properties.pressure_critical[toluene]*exp((-7.28607*(1 - 1/fs.properties.temperature_critical[toluene]*fs.state_block.temperature_bubble) + 1.38091*(1 - 1/fs.properties.temperature_critical[toluene]*fs.state_block.temperature_bubble)**1.5 - 2.83433*(1 - 1/fs.properties.temperature_critical[toluene]*fs.state_block.temperature_bubble)**3 - 2.79168*(1 - 1/fs.properties.temperature_critical[toluene]*fs.state_block.temperature_bubble)**6)/(1 - (1 - 1/fs.properties.temperature_critical[toluene]*fs.state_block.temperature_bubble)))\n", - " _p_sat_dewT : Size=2, Index=fs.properties.component_list\n", - " Key : Expression\n", - " benzene : fs.properties.pressure_critical[benzene]*exp((-6.98273*(1 - 1/fs.properties.temperature_critical[benzene]*fs.state_block.temperature_dew) + 1.33213*(1 - 1/fs.properties.temperature_critical[benzene]*fs.state_block.temperature_dew)**1.5 - 2.62863*(1 - 1/fs.properties.temperature_critical[benzene]*fs.state_block.temperature_dew)**3 - 3.33399*(1 - 1/fs.properties.temperature_critical[benzene]*fs.state_block.temperature_dew)**6)/(1 - (1 - 1/fs.properties.temperature_critical[benzene]*fs.state_block.temperature_dew)))\n", - " toluene : fs.properties.pressure_critical[toluene]*exp((-7.28607*(1 - 1/fs.properties.temperature_critical[toluene]*fs.state_block.temperature_dew) + 1.38091*(1 - 1/fs.properties.temperature_critical[toluene]*fs.state_block.temperature_dew)**1.5 - 2.83433*(1 - 1/fs.properties.temperature_critical[toluene]*fs.state_block.temperature_dew)**3 - 2.79168*(1 - 1/fs.properties.temperature_critical[toluene]*fs.state_block.temperature_dew)**6)/(1 - (1 - 1/fs.properties.temperature_critical[toluene]*fs.state_block.temperature_dew)))\n", - " _reduced_temp : Size=2, Index=fs.properties.component_list\n", - " Key : Expression\n", - " benzene : (fs.properties.temperature_critical[benzene] - fs.state_block._temperature_equilibrium)/fs.properties.temperature_critical[benzene]\n", - " toluene : (fs.properties.temperature_critical[toluene] - fs.state_block._temperature_equilibrium)/fs.properties.temperature_critical[toluene]\n", - " activity_coeff_comp_bubble : Size=2, Index=fs.properties.component_list\n", - " Key : Expression\n", - " benzene : exp(((fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,benzene]*1 + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,benzene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))) + (fs.state_block.mole_frac_comp[benzene]*1/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))*(fs.properties.tau[benzene,benzene] - (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,benzene]*1 + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,benzene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))) + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene])/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1)*(fs.properties.tau[benzene,toluene] - (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,toluene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,toluene]*1)/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1))))\n", - " toluene : exp(((fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,toluene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,toluene]*1)/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1)) + (fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene])/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))*(fs.properties.tau[toluene,benzene] - (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,benzene]*1 + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,benzene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))) + fs.state_block.mole_frac_comp[toluene]*1/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1)*(fs.properties.tau[toluene,toluene] - (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,toluene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,toluene]*1)/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1))))\n", - " activity_coeff_comp_dew : Size=2, Index=fs.properties.component_list\n", - " Key : Expression\n", - " benzene : exp(((fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,benzene]*1 + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,benzene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))) + (fs.state_block.mole_frac_comp[benzene]*1/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))*(fs.properties.tau[benzene,benzene] - (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,benzene]*1 + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,benzene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))) + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene])/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1)*(fs.properties.tau[benzene,toluene] - (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,toluene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,toluene]*1)/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1))))\n", - " toluene : exp(((fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,toluene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,toluene]*1)/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1)) + (fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene])/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))*(fs.properties.tau[toluene,benzene] - (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,benzene]*1 + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,benzene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))) + fs.state_block.mole_frac_comp[toluene]*1/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1)*(fs.properties.tau[toluene,toluene] - (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,toluene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,toluene]*1)/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1))))\n", - " fug_phase_comp : Size=4, Index=fs.properties.phase_list*fs.properties.component_list\n", - " Key : Expression\n", - " ('Liq', 'benzene') : fs.state_block.mole_frac_phase_comp[Liq,benzene]*fs.state_block.activity_coeff_comp[benzene]*fs.state_block.pressure_sat_comp[benzene]\n", - " ('Liq', 'toluene') : fs.state_block.mole_frac_phase_comp[Liq,toluene]*fs.state_block.activity_coeff_comp[toluene]*fs.state_block.pressure_sat_comp[toluene]\n", - " ('Vap', 'benzene') : fs.state_block.mole_frac_phase_comp[Vap,benzene]*fs.state_block.pressure\n", - " ('Vap', 'toluene') : fs.state_block.mole_frac_phase_comp[Vap,toluene]*fs.state_block.pressure\n", - "\n", - " 13 Constraint Declarations\n", - " _t1_constraint : Size=1, Index=None, Active=True\n", - " Key : Lower : Body : Upper : Active\n", - " None : 0.0 : fs.state_block._t1 - 0.5*(fs.state_block.temperature + fs.state_block.temperature_bubble + sqrt((fs.state_block.temperature - fs.state_block.temperature_bubble)**2 + fs.state_block.eps_1**2)) : 0.0 : True\n", - " _teq_constraint : Size=1, Index=None, Active=True\n", - " Key : Lower : Body : Upper : Active\n", - " None : 0.0 : fs.state_block._temperature_equilibrium - 0.5*(fs.state_block._t1 + fs.state_block.temperature_dew - sqrt((fs.state_block._t1 - fs.state_block.temperature_dew)**2 + fs.state_block.eps_2**2)) : 0.0 : True\n", - " eq_A : Size=2, Index=fs.properties.component_list, Active=True\n", - " Key : Lower : Body : Upper : Active\n", - " benzene : 0.0 : fs.state_block.A[benzene] - (fs.state_block.mole_frac_phase_comp[Liq,benzene]*fs.properties.tau[benzene,benzene]*fs.state_block.Gij_coeff[benzene,benzene] + fs.state_block.mole_frac_phase_comp[Liq,toluene]*fs.properties.tau[toluene,benzene]*fs.state_block.Gij_coeff[toluene,benzene])/(fs.state_block.mole_frac_phase_comp[Liq,benzene]*fs.state_block.Gij_coeff[benzene,benzene] + fs.state_block.mole_frac_phase_comp[Liq,toluene]*fs.state_block.Gij_coeff[toluene,benzene]) : 0.0 : True\n", - " toluene : 0.0 : fs.state_block.A[toluene] - (fs.state_block.mole_frac_phase_comp[Liq,benzene]*fs.properties.tau[benzene,toluene]*fs.state_block.Gij_coeff[benzene,toluene] + fs.state_block.mole_frac_phase_comp[Liq,toluene]*fs.properties.tau[toluene,toluene]*fs.state_block.Gij_coeff[toluene,toluene])/(fs.state_block.mole_frac_phase_comp[Liq,benzene]*fs.state_block.Gij_coeff[benzene,toluene] + fs.state_block.mole_frac_phase_comp[Liq,toluene]*fs.state_block.Gij_coeff[toluene,toluene]) : 0.0 : True\n", - " eq_B : Size=2, Index=fs.properties.component_list, Active=True\n", - " Key : Lower : Body : Upper : Active\n", - " benzene : 0.0 : fs.state_block.B[benzene] - (fs.state_block.mole_frac_phase_comp[Liq,benzene]*fs.state_block.Gij_coeff[benzene,benzene]/(fs.state_block.mole_frac_phase_comp[Liq,benzene]*fs.state_block.Gij_coeff[benzene,benzene] + fs.state_block.mole_frac_phase_comp[Liq,toluene]*fs.state_block.Gij_coeff[toluene,benzene])*(fs.properties.tau[benzene,benzene] - (fs.state_block.mole_frac_phase_comp[Liq,benzene]*fs.properties.tau[benzene,benzene]*fs.state_block.Gij_coeff[benzene,benzene] + fs.state_block.mole_frac_phase_comp[Liq,toluene]*fs.properties.tau[toluene,benzene]*fs.state_block.Gij_coeff[toluene,benzene])/(fs.state_block.mole_frac_phase_comp[Liq,benzene]*fs.state_block.Gij_coeff[benzene,benzene] + fs.state_block.mole_frac_phase_comp[Liq,toluene]*fs.state_block.Gij_coeff[toluene,benzene])) + fs.state_block.mole_frac_phase_comp[Liq,toluene]*fs.state_block.Gij_coeff[benzene,toluene]/(fs.state_block.mole_frac_phase_comp[Liq,benzene]*fs.state_block.Gij_coeff[benzene,toluene] + fs.state_block.mole_frac_phase_comp[Liq,toluene]*fs.state_block.Gij_coeff[toluene,toluene])*(fs.properties.tau[benzene,toluene] - (fs.state_block.mole_frac_phase_comp[Liq,benzene]*fs.properties.tau[benzene,toluene]*fs.state_block.Gij_coeff[benzene,toluene] + fs.state_block.mole_frac_phase_comp[Liq,toluene]*fs.properties.tau[toluene,toluene]*fs.state_block.Gij_coeff[toluene,toluene])/(fs.state_block.mole_frac_phase_comp[Liq,benzene]*fs.state_block.Gij_coeff[benzene,toluene] + fs.state_block.mole_frac_phase_comp[Liq,toluene]*fs.state_block.Gij_coeff[toluene,toluene]))) : 0.0 : True\n", - " toluene : 0.0 : fs.state_block.B[toluene] - (fs.state_block.mole_frac_phase_comp[Liq,benzene]*fs.state_block.Gij_coeff[toluene,benzene]/(fs.state_block.mole_frac_phase_comp[Liq,benzene]*fs.state_block.Gij_coeff[benzene,benzene] + fs.state_block.mole_frac_phase_comp[Liq,toluene]*fs.state_block.Gij_coeff[toluene,benzene])*(fs.properties.tau[toluene,benzene] - (fs.state_block.mole_frac_phase_comp[Liq,benzene]*fs.properties.tau[benzene,benzene]*fs.state_block.Gij_coeff[benzene,benzene] + fs.state_block.mole_frac_phase_comp[Liq,toluene]*fs.properties.tau[toluene,benzene]*fs.state_block.Gij_coeff[toluene,benzene])/(fs.state_block.mole_frac_phase_comp[Liq,benzene]*fs.state_block.Gij_coeff[benzene,benzene] + fs.state_block.mole_frac_phase_comp[Liq,toluene]*fs.state_block.Gij_coeff[toluene,benzene])) + fs.state_block.mole_frac_phase_comp[Liq,toluene]*fs.state_block.Gij_coeff[toluene,toluene]/(fs.state_block.mole_frac_phase_comp[Liq,benzene]*fs.state_block.Gij_coeff[benzene,toluene] + fs.state_block.mole_frac_phase_comp[Liq,toluene]*fs.state_block.Gij_coeff[toluene,toluene])*(fs.properties.tau[toluene,toluene] - (fs.state_block.mole_frac_phase_comp[Liq,benzene]*fs.properties.tau[benzene,toluene]*fs.state_block.Gij_coeff[benzene,toluene] + fs.state_block.mole_frac_phase_comp[Liq,toluene]*fs.properties.tau[toluene,toluene]*fs.state_block.Gij_coeff[toluene,toluene])/(fs.state_block.mole_frac_phase_comp[Liq,benzene]*fs.state_block.Gij_coeff[benzene,toluene] + fs.state_block.mole_frac_phase_comp[Liq,toluene]*fs.state_block.Gij_coeff[toluene,toluene]))) : 0.0 : True\n", - " eq_Gij_coeff : Size=2, Index=fs.properties.component_list*fs.properties.component_list, Active=True\n", - " Key : Lower : Body : Upper : Active\n", - " ('benzene', 'toluene') : 0.0 : fs.state_block.Gij_coeff[benzene,toluene] - exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) : 0.0 : True\n", - " ('toluene', 'benzene') : 0.0 : fs.state_block.Gij_coeff[toluene,benzene] - exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]) : 0.0 : True\n", - " eq_P_vap : Size=2, Index=fs.properties.component_list, Active=True\n", - " Key : Lower : Body : Upper : Active\n", - " benzene : 0.0 : (1 - ((fs.properties.temperature_critical[benzene] - fs.state_block._temperature_equilibrium)/fs.properties.temperature_critical[benzene]))*log(1/fs.properties.pressure_critical[benzene]*fs.state_block.pressure_sat_comp[benzene]) - (-6.98273*((fs.properties.temperature_critical[benzene] - fs.state_block._temperature_equilibrium)/fs.properties.temperature_critical[benzene]) + 1.33213*((fs.properties.temperature_critical[benzene] - fs.state_block._temperature_equilibrium)/fs.properties.temperature_critical[benzene])**1.5 - 2.62863*((fs.properties.temperature_critical[benzene] - fs.state_block._temperature_equilibrium)/fs.properties.temperature_critical[benzene])**3 - 3.33399*((fs.properties.temperature_critical[benzene] - fs.state_block._temperature_equilibrium)/fs.properties.temperature_critical[benzene])**6) : 0.0 : True\n", - " toluene : 0.0 : (1 - ((fs.properties.temperature_critical[toluene] - fs.state_block._temperature_equilibrium)/fs.properties.temperature_critical[toluene]))*log(1/fs.properties.pressure_critical[toluene]*fs.state_block.pressure_sat_comp[toluene]) - (-7.28607*((fs.properties.temperature_critical[toluene] - fs.state_block._temperature_equilibrium)/fs.properties.temperature_critical[toluene]) + 1.38091*((fs.properties.temperature_critical[toluene] - fs.state_block._temperature_equilibrium)/fs.properties.temperature_critical[toluene])**1.5 - 2.83433*((fs.properties.temperature_critical[toluene] - fs.state_block._temperature_equilibrium)/fs.properties.temperature_critical[toluene])**3 - 2.79168*((fs.properties.temperature_critical[toluene] - fs.state_block._temperature_equilibrium)/fs.properties.temperature_critical[toluene])**6) : 0.0 : True\n", - " eq_activity_coeff : Size=2, Index=fs.properties.component_list, Active=True\n", - " Key : Lower : Body : Upper : Active\n", - " benzene : 0.0 : log(fs.state_block.activity_coeff_comp[benzene]) - (fs.state_block.A[benzene] + fs.state_block.B[benzene]) : 0.0 : True\n", - " toluene : 0.0 : log(fs.state_block.activity_coeff_comp[toluene]) - (fs.state_block.A[toluene] + fs.state_block.B[toluene]) : 0.0 : True\n", - " eq_comp : Size=2, Index=fs.properties.component_list, Active=True\n", - " Key : Lower : Body : Upper : Active\n", - " benzene : 0.0 : fs.state_block.flow_mol*fs.state_block.mole_frac_comp[benzene] - (fs.state_block.flow_mol_phase[Liq]*fs.state_block.mole_frac_phase_comp[Liq,benzene] + fs.state_block.flow_mol_phase[Vap]*fs.state_block.mole_frac_phase_comp[Vap,benzene]) : 0.0 : True\n", - " toluene : 0.0 : fs.state_block.flow_mol*fs.state_block.mole_frac_comp[toluene] - (fs.state_block.flow_mol_phase[Liq]*fs.state_block.mole_frac_phase_comp[Liq,toluene] + fs.state_block.flow_mol_phase[Vap]*fs.state_block.mole_frac_phase_comp[Vap,toluene]) : 0.0 : True\n", - " eq_phase_equilibrium : Size=2, Index=fs.properties.component_list, Active=True\n", - " Key : Lower : Body : Upper : Active\n", - " benzene : 0.0 : (fs.state_block.mole_frac_phase_comp[Vap,benzene]*fs.state_block.pressure) - (fs.state_block.mole_frac_phase_comp[Liq,benzene]*fs.state_block.activity_coeff_comp[benzene]*fs.state_block.pressure_sat_comp[benzene]) : 0.0 : True\n", - " toluene : 0.0 : (fs.state_block.mole_frac_phase_comp[Vap,toluene]*fs.state_block.pressure) - (fs.state_block.mole_frac_phase_comp[Liq,toluene]*fs.state_block.activity_coeff_comp[toluene]*fs.state_block.pressure_sat_comp[toluene]) : 0.0 : True\n", - " eq_sum_mol_frac : Size=1, Index=None, Active=True\n", - " Key : Lower : Body : Upper : Active\n", - " None : 0.0 : fs.state_block.mole_frac_phase_comp[Liq,benzene] + fs.state_block.mole_frac_phase_comp[Liq,toluene] - (fs.state_block.mole_frac_phase_comp[Vap,benzene] + fs.state_block.mole_frac_phase_comp[Vap,toluene]) : 0.0 : True\n", - " eq_temperature_bubble : Size=1, Index=None, Active=True\n", - " Key : Lower : Body : Upper : Active\n", - " None : 0.0 : fs.state_block.mole_frac_comp[benzene]*exp(((fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,benzene]*1 + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,benzene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))) + (fs.state_block.mole_frac_comp[benzene]*1/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))*(fs.properties.tau[benzene,benzene] - (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,benzene]*1 + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,benzene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))) + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene])/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1)*(fs.properties.tau[benzene,toluene] - (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,toluene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,toluene]*1)/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1))))*(fs.properties.pressure_critical[benzene]*exp((-6.98273*(1 - 1/fs.properties.temperature_critical[benzene]*fs.state_block.temperature_bubble) + 1.33213*(1 - 1/fs.properties.temperature_critical[benzene]*fs.state_block.temperature_bubble)**1.5 - 2.62863*(1 - 1/fs.properties.temperature_critical[benzene]*fs.state_block.temperature_bubble)**3 - 3.33399*(1 - 1/fs.properties.temperature_critical[benzene]*fs.state_block.temperature_bubble)**6)/(1 - (1 - 1/fs.properties.temperature_critical[benzene]*fs.state_block.temperature_bubble)))) + fs.state_block.mole_frac_comp[toluene]*exp(((fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,toluene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,toluene]*1)/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1)) + (fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene])/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))*(fs.properties.tau[toluene,benzene] - (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,benzene]*1 + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,benzene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))/(fs.state_block.mole_frac_comp[benzene]*1 + fs.state_block.mole_frac_comp[toluene]*exp(- fs.properties.alpha[toluene,benzene]*fs.properties.tau[toluene,benzene]))) + fs.state_block.mole_frac_comp[toluene]*1/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1)*(fs.properties.tau[toluene,toluene] - (fs.state_block.mole_frac_comp[benzene]*fs.properties.tau[benzene,toluene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*fs.properties.tau[toluene,toluene]*1)/(fs.state_block.mole_frac_comp[benzene]*exp(- fs.properties.alpha[benzene,toluene]*fs.properties.tau[benzene,toluene]) + fs.state_block.mole_frac_comp[toluene]*1))))*(fs.properties.pressure_critical[toluene]*exp((-7.28607*(1 - 1/fs.properties.temperature_critical[toluene]*fs.state_block.temperature_bubble) + 1.38091*(1 - 1/fs.properties.temperature_critical[toluene]*fs.state_block.temperature_bubble)**1.5 - 2.83433*(1 - 1/fs.properties.temperature_critical[toluene]*fs.state_block.temperature_bubble)**3 - 2.79168*(1 - 1/fs.properties.temperature_critical[toluene]*fs.state_block.temperature_bubble)**6)/(1 - (1 - 1/fs.properties.temperature_critical[toluene]*fs.state_block.temperature_bubble)))) - fs.state_block.pressure : 0.0 : True\n", - " eq_temperature_dew : Size=1, Index=None, Active=True\n", - " Key : Lower : Body : Upper : Active\n", - " None : 0.0 : fs.state_block.mole_frac_comp[benzene]*fs.state_block.pressure/(fs.state_block.activity_coeff_comp[benzene]*(fs.properties.pressure_critical[benzene]*exp((-6.98273*(1 - 1/fs.properties.temperature_critical[benzene]*fs.state_block.temperature_dew) + 1.33213*(1 - 1/fs.properties.temperature_critical[benzene]*fs.state_block.temperature_dew)**1.5 - 2.62863*(1 - 1/fs.properties.temperature_critical[benzene]*fs.state_block.temperature_dew)**3 - 3.33399*(1 - 1/fs.properties.temperature_critical[benzene]*fs.state_block.temperature_dew)**6)/(1 - (1 - 1/fs.properties.temperature_critical[benzene]*fs.state_block.temperature_dew))))) + fs.state_block.mole_frac_comp[toluene]*fs.state_block.pressure/(fs.state_block.activity_coeff_comp[toluene]*(fs.properties.pressure_critical[toluene]*exp((-7.28607*(1 - 1/fs.properties.temperature_critical[toluene]*fs.state_block.temperature_dew) + 1.38091*(1 - 1/fs.properties.temperature_critical[toluene]*fs.state_block.temperature_dew)**1.5 - 2.83433*(1 - 1/fs.properties.temperature_critical[toluene]*fs.state_block.temperature_dew)**3 - 2.79168*(1 - 1/fs.properties.temperature_critical[toluene]*fs.state_block.temperature_dew)**6)/(1 - (1 - 1/fs.properties.temperature_critical[toluene]*fs.state_block.temperature_dew))))) - 1 : 0.0 : True\n", - " eq_total : Size=1, Index=None, Active=True\n", - " Key : Lower : Body : Upper : Active\n", - " None : 0.0 : fs.state_block.flow_mol_phase[Liq] + fs.state_block.flow_mol_phase[Vap] - fs.state_block.flow_mol : 0.0 : True\n", - "\n", - " 42 Declarations: flow_mol mole_frac_comp pressure temperature flow_mol_phase mole_frac_phase_comp Gij_coeff activity_coeff_comp A B eq_Gij_coeff eq_A eq_B eq_activity_coeff eq_total eq_comp eq_sum_mol_frac _temperature_equilibrium _t1 eps_1 eps_2 _t1_constraint temperature_bubble _p_sat_bubbleT eq_temperature_bubble Gij_coeff_bubble A_bubble B_bubble activity_coeff_comp_bubble _teq_constraint temperature_dew _p_sat_dewT eq_temperature_dew Gij_coeff_dew A_dew B_dew activity_coeff_comp_dew eq_phase_equilibrium fug_phase_comp pressure_sat_comp _reduced_temp eq_P_vap\n", - "\n", - " 3 Declarations: _time properties state_block\n", - "\n", - "1 Declarations: fs\n" - ] - } - ], - "source": [ - "m.pprint()" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0.3896822835079589\n" - ] - } - ], - "source": [ - "print(pyo.value(m.fs.state_block.mole_frac_phase_comp[\"Liq\", \"benzene\"]))" + "assert value(m.fs.state_block.mole_frac_phase_comp[\"Liq\", \"benzene\"]) == pytest.approx(\n", + " 0.389, abs=1e-2\n", + ")\n", + "assert value(m.fs.state_block.mole_frac_phase_comp[\"Vap\", \"benzene\"]) == pytest.approx(\n", + " 0.610, abs=1e-2\n", + ")\n", + "\n", + "assert value(m.fs.state_block.mole_frac_phase_comp[\"Liq\", \"toluene\"]) == pytest.approx(\n", + " 0.610, abs=1e-2\n", + ")\n", + "assert value(m.fs.state_block.mole_frac_phase_comp[\"Vap\", \"toluene\"]) == pytest.approx(\n", + " 0.394, abs=1e-2\n", + ")" ] }, { @@ -716,54 +339,107 @@ "source": [ "In addition to providing a method to return an initialized model, the `parmest` tool needs the following:\n", "\n", - "* List of variable names to be estimated\n", - "* Dataset\n", - "* Expression to compute the sum of squared errors\n" + "* Experiment class to set up and label model with suffixes\n", + "* Dataset with multiple scenarios - organized into an experiment list\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ + "Here we build an experiment class to label our model problem for parameter estimation. The labels are defined as a `Suffix`, and the main labels for our model are `experiment_outputs`, `unknown_parameters`. and `measurement_error`.\n", + "\n", + "For this problem, the error will be computed for the mole fraction of benzene in the vapor and liquid phase between the model prediction and data. The `experimental_outputs` will therefore be the mole fraction of benzene in the two phases.\n", + "\n", "In this example, we only estimate the binary interaction parameter (`tau_ij`). Given that this variable is usually indexed as `tau_ij = Var(component_list, component_list)`, there are 2*2=4 degrees of freedom. However, when i=j, the binary interaction parameter is 0. Therefore, in this problem, we estimate the binary interaction parameter for the following variables only:\n", "\n", "* fs.properties.tau['benzene', 'toluene']\n", "* fs.properties.tau['toluene', 'benzene']\n", "\n", - "
\n", - "Inline Exercise:\n", - "Create a list called `variable_name` with the above-mentioned variables declared as strings.\n", - "
" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": { - "tags": [ - "exercise" - ] - }, - "outputs": [], - "source": [ - "# Todo: Create a list of vars to estimate" + "As shown below, these model components are used as our `unknown_parameters`.\n", + "\n", + "We define `measurement_error` as none so parmest calculates the value internally based on the experimental outputs. Refer to https://pyomo.readthedocs.io/en/stable/explanation/analysis/parmest/driver.html for more information. " ] }, { "cell_type": "code", - "execution_count": 12, - "metadata": { - "tags": [ - "solution" - ] - }, + "execution_count": 9, + "metadata": {}, "outputs": [], "source": [ - "# Todo: Create a list of vars to estimate\n", - "variable_name = [\n", - " \"fs.properties.tau['benzene', 'toluene']\",\n", - " \"fs.properties.tau['toluene', 'benzene']\",\n", - "]" + "# Build an experiment class to take advantage of new parmest interface\n", + "from pyomo.contrib.parmest.experiment import Experiment\n", + "\n", + "\n", + "class NRTLExperiment(Experiment):\n", + " \"\"\"Experiment class for parameter estimation of NRTL model using parmest\"\"\"\n", + "\n", + " def __init__(self, data, meas_error=None):\n", + " \"\"\"Initialize the NRTLExperiment class\n", + "\n", + " Args:\n", + " data: DataFrame containing the experimental data\n", + " meas_error: Measurement error for the data (optional)\n", + " \"\"\"\n", + " self.model = None\n", + " self.data = data\n", + " self.meas_error = meas_error\n", + "\n", + " def create_model(self):\n", + " \"\"\"Create the Pyomo model for the NRTL parameter estimation problem\"\"\"\n", + " self.model = NRTL_model(self.data)\n", + "\n", + " def label_model(self):\n", + " import pyomo.environ as pyo\n", + " import pandas as pd\n", + "\n", + " m = self.model\n", + "\n", + " # Parmest expects the first index of experiment outputs to be the data point\n", + " # This is a workaround that will be addressed and corrected in a future release.\n", + "\n", + " m.data_point = pyo.Set(initialize=[0])\n", + "\n", + " # Wrap IDAES variables in Expressions indexed by data point\n", + " m.liq_benzene_out = pyo.Expression(\n", + " m.data_point,\n", + " rule=lambda m, i: m.fs.state_block.mole_frac_phase_comp[\"Liq\", \"benzene\"],\n", + " )\n", + "\n", + " m.vap_benzene_out = pyo.Expression(\n", + " m.data_point,\n", + " rule=lambda m, i: m.fs.state_block.mole_frac_phase_comp[\"Vap\", \"benzene\"],\n", + " )\n", + "\n", + " m.experiment_outputs = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + "\n", + " m.experiment_outputs[m.liq_benzene_out[0]] = float(self.data[\"liq_benzene\"])\n", + " m.experiment_outputs[m.vap_benzene_out[0]] = float(self.data[\"vap_benzene\"])\n", + "\n", + " m.measurement_error = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + " m.measurement_error.update(\n", + " [\n", + " (m.liq_benzene_out[0], self.meas_error),\n", + " (m.vap_benzene_out[0], self.meas_error),\n", + " ]\n", + " )\n", + "\n", + " # Add unknown parameters to the model for easier access\n", + " m.unknown_parameters = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + " m.unknown_parameters.update(\n", + " (k, value(k))\n", + " for k in [\n", + " m.fs.properties.tau[\"benzene\", \"toluene\"],\n", + " m.fs.properties.tau[\"toluene\", \"benzene\"],\n", + " ]\n", + " )\n", + "\n", + " def get_labeled_model(self):\n", + " \"\"\"Return the labeled model\"\"\"\n", + " if self.model is None:\n", + " self.create_model()\n", + " self.label_model()\n", + " return self.model" ] }, { @@ -782,7 +458,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 10, "metadata": { "tags": [] }, @@ -1188,281 +864,31 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "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 mole fraction of benzene in the vapor and liquid phase between the model prediction and data. \n", - "\n", - "
\n", - "Inline Exercise:\n", - "Complete the following cell by adding an expression to compute the sum of square errors. \n", - "
" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": { - "tags": [ - "exercise" - ] - }, - "outputs": [], - "source": [ - "# Create method to return an expression that computes the sum of squared error\n", - "def SSE(m, data):\n", - " # Todo: Add expression for computing the sum of squared errors in mole fraction of benzene in the liquid\n", - " # and vapor phase. For example, the squared error for the vapor phase is:\n", - " # (float(data[\"vap_benzene\"]) - m.fs.state_block.mole_frac_phase_comp[\"Vap\", \"benzene\"])**2\n", - "\n", - " return expr * 1e4" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": { - "tags": [ - "solution" - ] - }, - "outputs": [], - "source": [ - "# Create method to return an expression that computes the sum of squared error\n", - "def SSE(m, data):\n", - " # Todo: Add expression for computing the sum of squared errors in mole fraction of benzene in the liquid\n", - " # and vapor phase. For example, the squared error for the vapor phase is:\n", - " # (float(data[\"vap_benzene\"]) - m.fs.state_block.mole_frac_phase_comp[\"Vap\", \"benzene\"])**2\n", - " expr = (\n", - " float(data.iloc[0][\"vap_benzene\"])\n", - " - m.fs.state_block.mole_frac_phase_comp[\"Vap\", \"benzene\"]\n", - " ) ** 2 + (\n", - " float(data.iloc[0][\"liq_benzene\"])\n", - " - m.fs.state_block.mole_frac_phase_comp[\"Liq\", \"benzene\"]\n", - " ) ** 2\n", - " return expr * 1e4" + "We define the `exp_list` by spliting the data into individual experiments, or data points." ] }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 11, "metadata": {}, "outputs": [], "source": [ - "# Build an experiment class to take advantage of new parmest interface\n", - "from pyomo.contrib.parmest.experiment import Experiment\n", - "\n", - "\n", - "class NRTLExperiment(Experiment):\n", - " \"\"\"Experiment class for parameter estimation of NRTL model using parmest\"\"\"\n", - "\n", - " def __init__(self, data, meas_error=None):\n", - " \"\"\"Initialize the NRTLExperiment class\n", - "\n", - " Args:\n", - " data: DataFrame containing the experimental data\n", - " meas_error: Measurement error for the data (optional)\n", - " \"\"\"\n", - " self.model = None\n", - " self.data = data\n", - " self.meas_error = meas_error\n", - "\n", - " def create_model(self):\n", - " \"\"\"Create the Pyomo model for the NRTL parameter estimation problem\"\"\"\n", - " self.model = NRTL_model(self.data)\n", - "\n", - " # # Add objective scaling to help with convergence\n", - " # self.model.obj_scaling_factor = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", - " # self.model.obj_scaling_factor.update(\n", - " # [(self.model.obj, 1e4)]\n", - " # ) # Scale the objective by 1e4 to help with convergence\n", - "\n", - " def label_model(self):\n", - " import pyomo.environ as pyo\n", - " import pandas as pd\n", - "\n", - " m = self.model\n", - "\n", - " # Extract the first row of data to label the model\n", - " if isinstance(self.data, pd.DataFrame):\n", - " row = self.data.iloc[0]\n", - " else:\n", - " row = self.data\n", - "\n", - " # Parmest expects the first index of experiment outputs to be the data point\n", - " m.data_point = pyo.Set(initialize=[0])\n", - "\n", - " # Wrap IDAES variables in Expressions indexed by data point\n", - " m.liq_benzene_out = pyo.Expression(\n", - " m.data_point,\n", - " rule=lambda m, i: m.fs.state_block.mole_frac_phase_comp[\"Liq\", \"benzene\"],\n", - " )\n", - "\n", - " m.vap_benzene_out = pyo.Expression(\n", - " m.data_point,\n", - " rule=lambda m, i: m.fs.state_block.mole_frac_phase_comp[\"Vap\", \"benzene\"],\n", - " )\n", - "\n", - " m.experiment_outputs = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", - "\n", - " m.experiment_outputs[m.liq_benzene_out[0]] = float(row[\"liq_benzene\"])\n", - " m.experiment_outputs[m.vap_benzene_out[0]] = float(row[\"vap_benzene\"])\n", - "\n", - " m.measurement_error = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", - " m.measurement_error.update(\n", - " [\n", - " (m.liq_benzene_out[0], self.meas_error),\n", - " (m.vap_benzene_out[0], self.meas_error),\n", - " ]\n", - " )\n", - "\n", - " # Add unknown parameters to the model for easier access\n", - " m.unknown_parameters = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", - " m.unknown_parameters.update(\n", - " (k, pyo.value(k))\n", - " for k in [\n", - " m.fs.properties.tau[\"benzene\", \"toluene\"],\n", - " m.fs.properties.tau[\"toluene\", \"benzene\"],\n", - " ]\n", - " )\n", - "\n", - " def get_labeled_model(self):\n", - " \"\"\"Return the labeled model\"\"\"\n", - " if self.model is None:\n", - " self.create_model()\n", - " self.label_model()\n", - " return self.model" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
\n", - "Note:\n", - "Notice that we have scaled the expression up by a factor of 10000 as the SSE computed here will be an extremely small number given that we are using the difference in mole fraction in our expression. This will help in using a well-scaled objective to improve solve robustness when using IPOPT. \n", - "
\n" + "# Update to new interface\n", + "exp_list = []\n", + "for i in range(data.shape[0]):\n", + " exp_list.append(NRTLExperiment(data.iloc[i]))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "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. " + "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." ] }, { "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "WARNING: DEPRECATED: You're using the deprecated parmest interface\n", - "(model_function, data, theta_names). This interface will be removed in a\n", - "future release, please update to the new parmest interface using experiment\n", - "lists. (deprecated in 6.7.2) (called from /Applications/anaconda3/envs/idaes-\n", - "examples-dev-py313-macmini/lib/python3.13/functools.py:974)\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3746\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2200\n", - "\n", - "Total number of variables............................: 1100\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 300\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1098\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 6.0671019e+01 3.15e+00 4.84e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 5.2961050e+00 1.76e+03 5.05e+00 -1.0 1.37e+04 - 9.74e-01 1.00e+00f 1\n", - " 2 5.2586169e+00 4.01e+02 1.09e+00 -1.0 5.15e+02 - 1.00e+00 1.00e+00h 1\n", - " 3 5.1450958e+00 7.04e+01 2.27e-01 -1.0 4.11e+01 - 1.00e+00 1.00e+00h 1\n", - " 4 5.0748980e+00 1.25e+02 2.08e-01 -1.7 5.74e+02 - 1.00e+00 1.00e+00h 1\n", - " 5 5.0775194e+00 7.87e+00 1.92e-01 -1.7 8.44e+01 - 1.00e+00 1.00e+00h 1\n", - " 6 5.0726692e+00 1.37e+01 1.90e-01 -2.5 1.38e+02 - 1.00e+00 1.00e+00h 1\n", - " 7 5.0750377e+00 2.85e+00 2.60e-02 -2.5 6.99e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 5.0749670e+00 7.36e-02 2.81e-03 -3.8 9.72e+00 - 1.00e+00 1.00e+00h 1\n", - " 9 5.0749687e+00 4.51e-04 4.80e-06 -3.8 1.01e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 5.0749686e+00 2.91e-04 1.36e-06 -5.7 5.81e-01 - 1.00e+00 1.00e+00h 1\n", - " 11 5.0749686e+00 4.78e-08 2.18e-10 -8.6 7.65e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 11\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 5.0749685783046257e+00 5.0749685783046257e+00\n", - "Dual infeasibility......: 2.1827323102666636e-10 2.1827323102666636e-10\n", - "Constraint violation....: 1.6625508263665860e-10 4.7832145355641842e-08\n", - "Complementarity.........: 2.5076274461670377e-09 2.5076274461670377e-09\n", - "Overall NLP error.......: 2.5076274461670377e-09 4.7832145355641842e-08\n", - "\n", - "\n", - "Number of objective function evaluations = 12\n", - "Number of objective gradient evaluations = 12\n", - "Number of equality constraint evaluations = 12\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 12\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 11\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.012\n", - "Total CPU secs in NLP function evaluations = 0.004\n", - "\n", - "EXIT: Optimal Solution Found.\n" - ] - } - ], - "source": [ - "import logging\n", - "\n", - "idaeslog.getIdaesLogger(\"core.property_meta\").setLevel(logging.ERROR)\n", - "# Initialize a parameter estimation object\n", - "pest = parmest.Estimator(NRTL_model, data, variable_name, SSE, tee=True)\n", - "\n", - "# Run parameter estimation using all data\n", - "obj_value, parameters = pest.theta_est()" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [], - "source": [ - "# Update to new interface\n", - "exp_list = []\n", - "for i in range(data.shape[0]):\n", - " exp_list.append(NRTLExperiment(data.iloc[i]))" - ] - }, - { - "cell_type": "code", - "execution_count": 19, + "execution_count": 12, "metadata": {}, "outputs": [ { @@ -1561,13 +987,17 @@ } ], "source": [ - "pest_new = parmest.Estimator(exp_list, obj_function=\"SSE\", tee=True)\n", - "obj_value_new, parameters_new = pest_new.theta_est()" + "import logging\n", + "\n", + "idaeslog.getIdaesLogger(\"core.property_meta\").setLevel(logging.ERROR)\n", + "\n", + "pest = parmest.Estimator(exp_list, obj_function=\"SSE\", tee=True)\n", + "obj_value, parameters = pest.theta_est()" ] }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 13, "metadata": { "tags": [ "testing" @@ -1576,7 +1006,7 @@ "outputs": [], "source": [ "# Check for values of the parameter estimation problem\n", - "assert obj_value == pytest.approx(5.07496, 1e-3)\n", + "assert obj_value == pytest.approx(5.07496e-4, 1e-3)\n", "assert parameters[\"fs.properties.tau[benzene,toluene]\"] == pytest.approx(-0.89876, 1e-3)\n", "assert parameters[\"fs.properties.tau[toluene,benzene]\"] == pytest.approx(1.41048, 1e-3)" ] @@ -1590,32 +1020,7 @@ }, { "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The SSE at the optimal solution is 0.000507\n", - "\n", - "The values for the parameters are as follows:\n", - "fs.properties.tau[benzene,toluene] = -0.8987624036283817\n", - "fs.properties.tau[toluene,benzene] = 1.4104861099366175\n" - ] - } - ], - "source": [ - "print(\"The SSE at the optimal solution is %0.6f\" % (obj_value * 1e-4))\n", - "print()\n", - "print(\"The values for the parameters are as follows:\")\n", - "for k, v in parameters.items():\n", - " print(k, \"=\", v)" - ] - }, - { - "cell_type": "code", - "execution_count": 22, + "execution_count": 14, "metadata": {}, "outputs": [ { @@ -1631,10 +1036,10 @@ } ], "source": [ - "print(\"The SSE at the optimal solution is %0.6f\" % (obj_value_new))\n", + "print(\"The SSE at the optimal solution is %0.6f\" % (obj_value))\n", "print()\n", "print(\"The values for the parameters are as follows:\")\n", - "for k, v in parameters_new.items():\n", + "for k, v in parameters.items():\n", " print(k, \"=\", v)" ] }, @@ -1657,7 +1062,20 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Pyomo's `parmest` tool allows for bootstrapping where the parameter estimation is repeated over `n` samples with resampling from the original data set. Parameter estimation with bootstrap resampling can be used to identify confidence regions around each parameter estimate. This analysis can be slow given the increased number of model instances that need to be solved. Please refer to https://pyomo.readthedocs.io/en/stable/contributed_packages/parmest/driver.html for more details. " + "Pyomo's `parmest` tool allows for bootstrapping where the parameter estimation is repeated over `n` samples with resampling from the original data set. Parameter estimation with bootstrap resampling can be used to identify confidence regions around each parameter estimate. This analysis can be slow given the increased number of model instances that need to be solved. Please refer to https://pyomo.readthedocs.io/en/stable/contributed_packages/parmest/driver.html for more details. \n", + "\n", + "For the example above, the bootstrapping can be run by uncommenting the code in the following cell:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "# Uncomment the following lines\n", + "# bootstrap_theta = pest.theta_est_bootstrap(4, seed=542)\n", + "# display(bootstrap_theta)" ] } ], diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb index 12f86b76..e641936c 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb @@ -54,7 +54,7 @@ "source": [ "
\n", "Inline Exercise:\n", - "import `ConcreteModel` from Pyomo, `FlowsheetBlock` and `Flash` from IDAES. \n", + "import `ConcreteModel`, `value`, and `Suffix` from Pyomo, `FlowsheetBlock` and `Flash` from IDAES. \n", "
" ] }, @@ -68,7 +68,7 @@ }, "outputs": [], "source": [ - "# Todo: import pyomo.environ as pyo\n", + "# Todo: import ConcreteModel, value, and Suffix from pyomo.environ\n", "\n", "# Todo: import FlowsheetBlock from idaes.core\n", "\n", @@ -85,8 +85,7 @@ }, "outputs": [], "source": [ - "# Todo: import ConcreteModel from pyomo.environ\n", - "# from pyomo.environ import ConcreteModel, value\n", + "# Todo: import ConcreteModel, value, and Suffix from pyomo.environ\n", "from pyomo.environ import ConcreteModel, value, Suffix\n", "\n", "# Todo: import FlowsheetBlock from idaes.core\n", @@ -435,36 +434,6 @@ " return self.model" ] }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": { - "tags": [ - "exercise" - ] - }, - "outputs": [], - "source": [ - "# Todo: Create a list of vars to estimate" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": { - "tags": [ - "solution" - ] - }, - "outputs": [], - "source": [ - "# Todo: Create a list of vars to estimate\n", - "variable_name = [\n", - " \"fs.properties.tau['benzene', 'toluene']\",\n", - " \"fs.properties.tau['toluene', 'benzene']\",\n", - "]" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -481,7 +450,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 10, "metadata": {}, "outputs": [ { @@ -890,7 +859,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 11, "metadata": {}, "outputs": [], "source": [ @@ -904,12 +873,12 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "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, dataset, list of variable names to estimate, and the SSE expression to the Estimator object. `tee=True` will print the solver output after solving the parameter estimation problem." + "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." ] }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 12, "metadata": {}, "outputs": [ { @@ -1072,13 +1041,17 @@ } ], "source": [ + "import logging\n", + "\n", + "idaeslog.getIdaesLogger(\"core.property_meta\").setLevel(logging.ERROR)\n", + "\n", "pest = parmest.Estimator(exp_list, obj_function=\"SSE\", tee=True)\n", "obj_value, parameters = pest.theta_est()" ] }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 13, "metadata": { "tags": [ "testing" @@ -1103,14 +1076,14 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "The SSE at the optimal solution is 0.000000\n", + "The SSE at the optimal solution is 0.000507\n", "\n", "The values for the parameters are as follows:\n", "fs.properties.tau[benzene,toluene] = -0.8987454466579063\n", @@ -1119,7 +1092,7 @@ } ], "source": [ - "print(\"The SSE at the optimal solution is %0.6f\" % (obj_value * 1e-4))\n", + "print(\"The SSE at the optimal solution is %0.6f\" % (obj_value))\n", "print()\n", "print(\"The values for the parameters are as follows:\")\n", "for k, v in parameters.items():\n", @@ -1152,7 +1125,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 15, "metadata": {}, "outputs": [], "source": [ diff --git a/idaes_examples/notebooks/docs/properties/parameter_estimation_pr.ipynb b/idaes_examples/notebooks/docs/properties/parameter_estimation_pr.ipynb index 280aedcc..1d59634c 100644 --- a/idaes_examples/notebooks/docs/properties/parameter_estimation_pr.ipynb +++ b/idaes_examples/notebooks/docs/properties/parameter_estimation_pr.ipynb @@ -16,7 +16,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", @@ -31,8 +31,8 @@ "source": [ "# Using Parameter Estimation with Modular Property Packages\n", "Author: Alejandro Garciadego \n", - "Maintainer: Andrew Lee \n", - "Updated: 2023-06-01 \n", + "Maintainer: Stephen Cini \n", + "Updated: 2026-06-11 \n", "## 1. Introduction\n", "\n", "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.\n", @@ -62,7 +62,7 @@ "outputs": [], "source": [ "# Import objects from pyomo package\n", - "from pyomo.environ import ConcreteModel, SolverFactory, value, Var, Suffix\n", + "from pyomo.environ import ConcreteModel, SolverFactory, value, Suffix\n", "\n", "# Import the main FlowsheetBlock from IDAES. The flowsheet block will contain the unit model\n", "from idaes.core import FlowsheetBlock\n", @@ -236,13 +236,137 @@ "name": "stdout", "output_type": "stream", "text": [ - "2026-06-11 00:33:41 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:33:41 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:41 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:33:41 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:33:41 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:41 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:41 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n" + "2026-06-11 12:42:22 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 39\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 25\n", + "\n", + "Total number of variables............................: 18\n", + " variables with only lower bounds: 4\n", + " variables with lower and upper bounds: 13\n", + " variables with only upper bounds: 1\n", + "Total number of equality constraints.................: 18\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 5.00e-01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 0.0000000e+00 1.76e-01 6.65e+03 -1.0 7.51e+04 - 2.67e-01 9.90e-01H 1\n", + " 2 0.0000000e+00 4.81e-02 1.40e+02 -1.0 6.76e+02 - 9.46e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 8.65e-03 1.76e+01 -1.0 9.79e+00 - 9.90e-01 9.90e-01h 1\n", + " 4 0.0000000e+00 1.81e-03 4.99e+04 -1.0 1.20e+00 - 9.90e-01 1.00e+00h 1\n", + " 5 0.0000000e+00 3.48e-03 9.81e+04 -1.0 5.29e+01 - 9.90e-01 1.00e+00h 1\n", + " 6 0.0000000e+00 1.57e-03 8.00e+02 -1.0 1.54e+02 - 9.92e-01 1.00e+00h 1\n", + " 7 0.0000000e+00 7.66e-04 2.93e-04 -2.5 2.52e+02 - 1.00e+00 1.00e+00h 1\n", + " 8 0.0000000e+00 3.81e-04 1.61e-04 -5.7 4.82e+02 - 1.00e+00 1.00e+00h 1\n", + " 9 0.0000000e+00 1.90e-04 6.49e-05 -5.7 9.53e+02 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 0.0000000e+00 9.50e-05 8.68e-05 -5.7 1.90e+03 - 1.00e+00 1.00e+00h 1\n", + " 11 0.0000000e+00 4.75e-05 3.47e-04 -5.7 3.81e+03 - 1.00e+00 1.00e+00h 1\n", + " 12 0.0000000e+00 2.72e-05 1.39e-03 -5.7 7.64e+03 - 1.00e+00 1.00e+00h 1\n", + " 13 0.0000000e+00 1.07e-04 5.57e-03 -5.7 1.54e+04 - 1.00e+00 1.00e+00h 1\n", + " 14 0.0000000e+00 4.09e-04 2.23e-02 -5.7 3.11e+04 - 1.00e+00 1.00e+00h 1\n", + " 15 0.0000000e+00 1.51e-03 8.91e-02 -5.7 6.38e+04 - 1.00e+00 1.00e+00h 1\n", + " 16 0.0000000e+00 5.12e-03 3.53e-01 -5.7 1.33e+05 - 1.00e+00 1.00e+00h 1\n", + " 17 0.0000000e+00 1.49e-02 1.34e+00 -5.7 2.89e+05 - 1.00e+00 1.00e+00h 1\n", + " 18 0.0000000e+00 3.14e-02 4.58e+00 -5.7 6.55e+05 - 1.00e+00 1.00e+00h 1\n", + " 19 0.0000000e+00 2.86e-02 4.32e+00 -5.7 1.51e+06 - 1.00e+00 1.25e-01h 4\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 0.0000000e+00 2.82e-02 4.26e+00 -5.7 1.73e+06 - 1.00e+00 1.56e-02h 7\n", + " 21 0.0000000e+00 2.79e-02 4.23e+00 -5.7 1.76e+06 - 1.00e+00 7.81e-03h 8\n", + " 22 0.0000000e+00 2.79e-02 4.22e+00 -5.7 1.77e+06 - 1.00e+00 4.88e-04h 12\n", + " 23 0.0000000e+00 2.79e-02 4.22e+00 -5.7 1.77e+06 - 1.00e+00 1.22e-04h 14\n", + " 24 0.0000000e+00 7.05e-03 1.51e+01 -5.7 1.77e+06 - 1.00e+00 1.00e+00h 1\n", + " 25 0.0000000e+00 9.63e-04 4.01e+00 -5.7 3.18e+06 - 1.00e+00 1.50e-01h 2\n", + " 26 0.0000000e+00 5.53e-04 8.54e+01 -5.7 3.24e+06 - 1.00e+00 6.53e-02h 2\n", + " 27 0.0000000e+00 5.53e-04 8.57e+01 -5.7 3.20e+06 - 1.00e+00 9.58e-04h 7\n", + " 28 0.0000000e+00 5.53e-04 9.27e+01 -5.7 3.19e+06 - 1.00e+00 9.42e-04h 7\n", + " 29 0.0000000e+00 5.53e-04 2.08e+02 -5.7 3.19e+06 - 1.00e+00 9.27e-04h 7\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30 0.0000000e+00 5.52e-04 7.91e+03 -5.7 1.83e+06 - 1.00e+00 3.17e-03h 6\n", + " 31 0.0000000e+00 3.77e-05 2.11e+06 -5.7 2.63e+04 - 1.00e+00 1.00e+00h 1\n", + " 32 0.0000000e+00 3.77e-05 2.10e+06 -5.7 1.03e+06 - 1.00e+00 5.67e-04h 9\n", + " 33 0.0000000e+00 3.77e-05 2.10e+06 -5.7 1.03e+06 - 1.00e+00 5.65e-04h 9\n", + " 34 0.0000000e+00 3.77e-05 2.10e+06 -5.7 1.02e+06 - 1.00e+00 5.63e-04h 9\n", + " 35 0.0000000e+00 3.77e-05 2.12e+06 -5.7 9.14e+05 - 1.00e+00 6.29e-04h 9\n", + " 36 0.0000000e+00 3.77e-05 2.23e+06 -5.7 9.36e+05 - 1.00e+00 6.11e-04h 9\n", + " 37 0.0000000e+00 3.76e-05 4.98e+06 -5.7 4.23e+05 - 1.00e+00 2.69e-03h 8\n", + " 38 0.0000000e+00 3.76e-05 6.97e+06 -5.7 8.98e+05 - 1.00e+00 6.29e-04h 9\n", + " 39 0.0000000e+00 3.76e-05 5.17e+07 -5.7 6.09e+05 - 1.00e+00 1.85e-03h 8\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 40 0.0000000e+00 3.76e-05 6.29e+07 -5.7 1.03e+06 - 1.00e+00 5.42e-04h 9\n", + " 41 0.0000000e+00 3.76e-05 7.41e+07 -5.7 1.02e+06 - 1.00e+00 5.43e-04h 9\n", + " 42 0.0000000e+00 8.59e-04 7.30e+11 -5.7 1.02e+06 - 1.00e+00 1.39e-01w 1\n", + " 43 0.0000000e+00 8.58e-04 7.30e+11 -5.7 7.14e+03 - 1.00e+00 2.07e-05w 1\n", + "In iteration 43, 2 Slacks too small, adjusting variable bounds\n", + " 44 0.0000000e+00 7.90e-04 5.95e+14 -5.7 4.69e+03 - 1.00e+00 8.02e-02w 1\n", + " 45 0.0000000e+00 3.76e-05 8.53e+07 -5.7 4.31e+03 - 1.00e+00 5.41e-04h 8\n", + " 46 0.0000000e+00 3.75e-05 9.64e+07 -5.7 1.02e+06 - 1.00e+00 5.39e-04h 9\n", + " 47 0.0000000e+00 3.75e-05 1.08e+08 -5.7 1.02e+06 - 1.00e+00 5.37e-04h 9\n", + " 48 0.0000000e+00 3.75e-05 1.19e+08 -5.7 1.02e+06 - 1.00e+00 5.35e-04h 9\n", + " 49 0.0000000e+00 3.75e-05 1.30e+08 -5.7 1.02e+06 - 1.00e+00 5.33e-04h 9\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 50 0.0000000e+00 3.75e-05 1.41e+08 -5.7 1.02e+06 - 1.00e+00 5.31e-04h 9\n", + " 51 0.0000000e+00 3.75e-05 1.52e+08 -5.7 1.02e+06 - 1.00e+00 5.29e-04h 9\n", + " 52 0.0000000e+00 3.75e-05 1.64e+08 -5.7 1.02e+06 - 1.00e+00 5.27e-04h 9\n", + " 53 0.0000000e+00 3.75e-05 1.75e+08 -5.7 1.02e+06 - 1.00e+00 5.25e-04h 9\n", + " 54 0.0000000e+00 3.75e-05 1.86e+08 -5.7 1.02e+06 - 1.00e+00 5.23e-04h 9\n", + " 55 0.0000000e+00 7.97e-04 7.34e+11 -5.7 1.02e+06 - 1.00e+00 1.33e-01w 1\n", + " 56 0.0000000e+00 7.97e-04 6.89e+11 -5.7 6.89e-05 16.0 2.81e-04 5.39e-01w 1\n", + " 57 0.0000000e+00 4.04e-07 2.66e+15 -5.7 4.36e+03 - 2.29e-07 1.00e+00h 1\n", + "Cannot recompute multipliers for feasibility problem. Error in eq_mult_calculator\n", + "\n", + "Number of Iterations....: 57\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 2.6563801083485440e+15 2.6563801083485440e+15\n", + "Constraint violation....: 4.0441652946975677e-07 4.0441652946975677e-07\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 4.0441652946975677e-07 2.6563801083485440e+15\n", + "\n", + "\n", + "Number of objective function evaluations = 337\n", + "Number of objective gradient evaluations = 59\n", + "Number of equality constraint evaluations = 337\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 59\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 58\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", + "Total CPU secs in NLP function evaluations = 0.008\n", + "\n", + "EXIT: Solved To Acceptable Level.\n" ] } ], @@ -260,7 +384,11 @@ "m = PR_model(test_data)\n", "\n", "# Check that degrees of freedom is 0\n", - "assert degrees_of_freedom(m) == 0" + "assert degrees_of_freedom(m) == 0\n", + "\n", + "# Solve the model with the default solver and display results\n", + "solver = SolverFactory(\"ipopt\")\n", + "results = solver.solve(m, tee=True)" ] }, { @@ -370,132 +498,132 @@ "name": "stdout", "output_type": "stream", "text": [ - "2026-06-11 00:33:41 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:33:41 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:41 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:33:41 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:33:41 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:41 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:41 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:41 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:33:41 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:41 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:33:41 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:33:41 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:41 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:41 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:41 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:33:42 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:33:43 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Starting initialization\n", - "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", - "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", - "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", - "2026-06-11 00:33:44 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", "Ipopt 3.13.2: \n", "\n", "******************************************************************************\n", @@ -584,7 +712,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 11, "metadata": {}, "outputs": [ { @@ -624,7 +752,7 @@ ], "metadata": { "kernelspec": { - "display_name": "idaes-examples-dev-py313-macmini", + "display_name": "idaes-pse-and-examples-dev-py313-macmini", "language": "python", "name": "python3" }, From 7fdc01be014b3ccc492637023b63de2766a80429 Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Thu, 11 Jun 2026 12:54:10 -0400 Subject: [PATCH 12/23] Apply changes to derivative notebooks using preprocessing --- ...stimation_nrtl_using_state_block_doc.ipynb | 1874 ++++++------- ...tion_nrtl_using_state_block_exercise.ipynb | 693 ++++- ...tion_nrtl_using_state_block_solution.ipynb | 755 +++++- ...timation_nrtl_using_state_block_test.ipynb | 716 ++++- ...stimation_nrtl_using_state_block_usr.ipynb | 755 +++++- ...estimation_nrtl_using_unit_model_doc.ipynb | 1928 +++++++------- ...ation_nrtl_using_unit_model_exercise.ipynb | 751 +++++- ...ation_nrtl_using_unit_model_solution.ipynb | 806 +++++- ...stimation_nrtl_using_unit_model_test.ipynb | 767 +++++- ...estimation_nrtl_using_unit_model_usr.ipynb | 806 +++++- .../parameter_estimation_pr_doc.ipynb | 2363 ++++++----------- .../parameter_estimation_pr_test.ipynb | 529 +++- .../parameter_estimation_pr_usr.ipynb | 529 +++- 13 files changed, 8932 insertions(+), 4340 deletions(-) diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_doc.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_doc.ipynb index 863667af..532e84f9 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_doc.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_doc.ipynb @@ -1,926 +1,970 @@ { - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "tags": [ - "header", - "hide-cell" - ] - }, - "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", - "metadata": {}, - "source": [ - "# Parameter Estimation Using the NRTL State Block\n", - "\n", - "Author: Jaffer Ghouse \n", - "Maintainer: Andrew Lee \n", - "Updated: 2023-06-01 \n", - "\n", - "In this module, we use Pyomo's `parmest` tool in conjunction with IDAES models for parameter estimation. We demonstrate these tools by estimating the parameters associated with the NRTL property model for a benzene-toluene mixture. The NRTL model has 2 sets of parameters: the non-randomness parameter (`alpha_ij`) and the binary interaction parameter (`tau_ij`), where `i` and `j` are the pure component species. In this example, we only estimate the binary interaction parameter (`tau_ij`) for a given dataset. 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 only the state block. \n", - "\n", - "We will complete the following tasks:\n", - "* Set up a method to return an initialized model\n", - "* Set up the parameter estimation problem using `parmest`\n", - "* Analyze the results\n", - "* Demonstrate advanced features using `parmest`\n", - "\n", - "## Key links to documentation:\n", - "* NRTL Model - https://idaes-pse.readthedocs.io/en/stable/reference_guides/model_libraries/generic/property_models/activity_coefficient.html\n", - "* parmest - https://pyomo.readthedocs.io/en/stable/contributed_packages/parmest/index.html\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
\n", - "Inline Exercise:\n", - "import `ConcreteModel` from Pyomo and `FlowsheetBlock` from IDAES. \n", - "
" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "tags": [ - "solution" - ] - }, - "outputs": [], - "source": [ - "# Todo: import ConcreteModel from pyomo.environ\n", - "from pyomo.environ import ConcreteModel, value\n", - "\n", - "# Todo: import FlowsheetBlock from idaes.core\n", - "from idaes.core import FlowsheetBlock" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In the next cell, we import the parameter block used in this module and the idaes logger. " - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "from idaes.models.properties.activity_coeff_models.BTX_activity_coeff_VLE import (\n", - " BTXParameterBlock,\n", - ")\n", - "import idaes.logger as idaeslog" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In the next cell, we import `parmest` from Pyomo and the `pandas` package. We need `pandas` as `parmest` uses `pandas.dataframe` for handling the input data and the results." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "import pyomo.contrib.parmest.parmest as parmest\n", - "import pandas as pd" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Setting up an initialized model\n", - "\n", - "We need to provide a method that returns an initialized model to the `parmest` tool in Pyomo." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
\n", - "Inline Exercise:\n", - "Using what you have learned from previous modules, fill in the missing code below to return an initialized IDAES model. \n", - "
" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": { - "tags": [ - "solution" - ] - }, - "outputs": [], - "source": [ - "def NRTL_model(data):\n", - "\n", - " # Todo: Create a ConcreteModel object\n", - " m = ConcreteModel()\n", - "\n", - " # Todo: Create FlowsheetBlock object\n", - " m.fs = FlowsheetBlock(dynamic=False)\n", - "\n", - " # Todo: Create a properties parameter object with the following options:\n", - " # \"valid_phase\": ('Liq', 'Vap')\n", - " # \"activity_coeff_model\": 'NRTL'\n", - " m.fs.properties = BTXParameterBlock(\n", - " valid_phase=(\"Liq\", \"Vap\"), activity_coeff_model=\"NRTL\"\n", - " )\n", - " m.fs.state_block = m.fs.properties.build_state_block(defined_state=True)\n", - "\n", - " # Fix the state variables on the state block\n", - " # hint: state variables exist on the state block i.e. on m.fs.state_block\n", - "\n", - " m.fs.state_block.flow_mol.fix(1)\n", - " m.fs.state_block.temperature.fix(368)\n", - " m.fs.state_block.pressure.fix(101325)\n", - " m.fs.state_block.mole_frac_comp[\"benzene\"].fix(0.5)\n", - " m.fs.state_block.mole_frac_comp[\"toluene\"].fix(0.5)\n", - "\n", - " # Fix NRTL specific parameters.\n", - "\n", - " # non-randomness parameter - alpha_ij (set at 0.3, 0 if i=j)\n", - " m.fs.properties.alpha[\"benzene\", \"benzene\"].fix(0)\n", - " m.fs.properties.alpha[\"benzene\", \"toluene\"].fix(0.3)\n", - " m.fs.properties.alpha[\"toluene\", \"toluene\"].fix(0)\n", - " m.fs.properties.alpha[\"toluene\", \"benzene\"].fix(0.3)\n", - "\n", - " # binary interaction parameter - tau_ij (0 if i=j, else to be estimated later but fixing to initialize)\n", - " m.fs.properties.tau[\"benzene\", \"benzene\"].fix(0)\n", - " m.fs.properties.tau[\"benzene\", \"toluene\"].fix(-0.9)\n", - " m.fs.properties.tau[\"toluene\", \"toluene\"].fix(0)\n", - " m.fs.properties.tau[\"toluene\", \"benzene\"].fix(1.4)\n", - "\n", - " # Initialize the flash unit\n", - " m.fs.state_block.initialize(outlvl=idaeslog.INFO_LOW)\n", - "\n", - " # Fix at actual temperature\n", - " m.fs.state_block.temperature.fix(float(data[\"temperature\"]))\n", - "\n", - " # Set bounds on variables to be estimated\n", - " m.fs.properties.tau[\"benzene\", \"toluene\"].setlb(-5)\n", - " m.fs.properties.tau[\"benzene\", \"toluene\"].setub(5)\n", - "\n", - " m.fs.properties.tau[\"toluene\", \"benzene\"].setlb(-5)\n", - " m.fs.properties.tau[\"toluene\", \"benzene\"].setub(5)\n", - "\n", - " # Return initialized flash model\n", - " return m" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Parameter estimation using parmest" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In addition to providing a method to return an initialized model, the `parmest` tool needs the following:\n", - "\n", - "* List of variable names to be estimated\n", - "* Dataset\n", - "* Expression to compute the sum of squared errors\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In this example, we only estimate the binary interaction parameter (`tau_ij`). Given that this variable is usually indexed as `tau_ij = Var(component_list, component_list)`, there are 2*2=4 degrees of freedom. However, when i=j, the binary interaction parameter is 0. Therefore, in this problem, we estimate the binary interaction parameter for the following variables only:\n", - "\n", - "* fs.properties.tau['benzene', 'toluene']\n", - "* fs.properties.tau['toluene', 'benzene']\n", - "\n", - "
\n", - "Inline Exercise:\n", - "Create a list called `variable_name` with the above-mentioned variables declared as strings.\n", - "
" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": { - "tags": [ - "solution" - ] - }, - "outputs": [], - "source": [ - "# Todo: Create a list of vars to estimate\n", - "variable_name = [\n", - " \"fs.properties.tau['benzene', 'toluene']\",\n", - " \"fs.properties.tau['toluene', 'benzene']\",\n", - "]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Pyomo's `parmest` tool supports the following data formats:\n", - "- pandas dataframe\n", - "- list of dictionaries\n", - "- list of json file names.\n", - "\n", - "Please see the documentation for more details. \n", - "\n", - "For this example, we load data from the csv file `BT_NRTL_dataset.csv`. The dataset consists of fifty data points which provide the mole fraction of benzene in the vapor and liquid phase as a function of temperature. " - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": { - "tags": [] - }, - "outputs": [ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "tags": [ + "header", + "hide-cell" + ] + }, + "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": [ + "# Parameter Estimation Using the NRTL State Block\n", + "\n", + "Author: Jaffer Ghouse \n", + "Maintainer: Stephen Cini \n", + "Updated: 2026-06-11 \n", + "\n", + "In this module, we use Pyomo's `parmest` tool in conjunction with IDAES models for parameter estimation. We demonstrate these tools by estimating the parameters associated with the NRTL property model for a benzene-toluene mixture. The NRTL model has 2 sets of parameters: the non-randomness parameter (`alpha_ij`) and the binary interaction parameter (`tau_ij`), where `i` and `j` are the pure component species. In this example, we only estimate the binary interaction parameter (`tau_ij`) for a given dataset. 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 only the state block. \n", + "\n", + "We will complete the following tasks:\n", + "* Set up a method to return an initialized model\n", + "* Set up the parameter estimation problem using `parmest`\n", + "* Analyze the results\n", + "* Demonstrate advanced features using `parmest`\n", + "\n", + "## Key links to documentation:\n", + "* NRTL Model - https://idaes-pse.readthedocs.io/en/stable/reference_guides/model_libraries/generic/property_models/activity_coefficient.html\n", + "* parmest - https://pyomo.readthedocs.io/en/stable/explanation/analysis/parmest/index.html\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "Inline Exercise:\n", + "import `ConcreteModel`, `value`, and `Suffix` from Pyomo, `FlowsheetBlock` and `Flash` from IDAES. \n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "tags": [ + "solution" + ] + }, + "outputs": [], + "source": [ + "# Todo: import ConcreteModel, value, and Suffix from pyomo.environ\n", + "from pyomo.environ import ConcreteModel, value, Suffix\n", + "\n", + "# Todo: import FlowsheetBlock from idaes.core\n", + "from idaes.core import FlowsheetBlock\n", + "\n", + "# Todo: import Flash unit model from idaes.models.unit_models\n", + "from idaes.models.unit_models import Flash" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In the next cell, we import the parameter block used in this module and the idaes logger. " + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "from idaes.models.properties.activity_coeff_models.BTX_activity_coeff_VLE import (\n", + " BTXParameterBlock,\n", + ")\n", + "import idaes.logger as idaeslog" + ] + }, { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
temperatureliq_benzenevap_benzene
0365.5000000.4809530.692110
1365.6176470.4624440.667699
2365.7352940.4779840.692441
3365.8529410.4405470.640336
4365.9705880.4274210.623328
5366.0882350.4427250.647796
6366.2058820.4343740.637691
7366.3235290.4446420.654933
8366.4411760.4271320.631229
9366.5588240.4463010.661743
10366.6764710.4380040.651591
11366.7941180.4253200.634814
12366.9117650.4394350.658047
13367.0294120.4356550.654539
14367.1470590.4013500.604987
15367.2647060.3978620.601703
16367.3823530.4158210.630930
17367.5000000.4206670.640380
18367.6176470.3916830.598214
19367.7352940.4049030.620432
20367.8529410.4095630.629626
21367.9705880.3894880.600722
22368.0000000.3967890.612483
23368.0882350.3981620.616106
24368.2058820.3623400.562505
25368.3235290.3869580.602680
26368.4411760.3636430.568210
27368.5588240.3681180.577072
28368.6764710.3840980.604078
29368.7941180.3536050.557925
30368.9117650.3464740.548445
31369.0294120.3507410.556996
32369.1470590.3623470.577286
33369.2647060.3625780.579519
34369.3823530.3407650.546411
35369.5000000.3374620.542857
36369.6176470.3557290.574083
37369.7352940.3486790.564513
38369.8529410.3381870.549284
39369.9705880.3243600.528514
40370.0882350.3107530.507964
41370.2058820.3110370.510055
42370.3235290.3112630.512055
43370.4411760.3080810.508437
44370.5588240.3082240.510293
45370.6764710.3181480.528399
46370.7941180.3083340.513728
47370.9117650.3179370.531410
48371.0294120.2891490.484824
49371.1470590.2986370.502318
\n", - "
" + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In the next cell, we import `parmest` from Pyomo and the `pandas` package. We need `pandas` as `parmest` uses `pandas.dataframe` for handling the input data and the results." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import pyomo.contrib.parmest.parmest as parmest\n", + "import pandas as pd" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Setting up an initialized model\n", + "\n", + "We need to provide a method that returns an initialized model to the `parmest` tool in Pyomo." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "Inline Exercise:\n", + "Using what you have learned from previous modules, fill in the missing code below to return an initialized IDAES model. \n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "tags": [ + "solution" + ] + }, + "outputs": [], + "source": [ + "def NRTL_model(data):\n", + "\n", + " # Todo: Create a ConcreteModel object\n", + " m = ConcreteModel()\n", + "\n", + " # Todo: Create FlowsheetBlock object\n", + " m.fs = FlowsheetBlock(dynamic=False)\n", + "\n", + " # Todo: Create a properties parameter object with the following options:\n", + " # \"valid_phase\": ('Liq', 'Vap')\n", + " # \"activity_coeff_model\": 'NRTL'\n", + " m.fs.properties = BTXParameterBlock(\n", + " valid_phase=(\"Liq\", \"Vap\"), activity_coeff_model=\"NRTL\"\n", + " )\n", + " m.fs.state_block = m.fs.properties.build_state_block(defined_state=True)\n", + "\n", + " # Fix the state variables on the state block\n", + " # hint: state variables exist on the state block i.e. on m.fs.state_block\n", + "\n", + " m.fs.state_block.flow_mol.fix(1)\n", + " m.fs.state_block.temperature.fix(368)\n", + " m.fs.state_block.pressure.fix(101325)\n", + " m.fs.state_block.mole_frac_comp[\"benzene\"].fix(0.5)\n", + " m.fs.state_block.mole_frac_comp[\"toluene\"].fix(0.5)\n", + "\n", + " # Fix NRTL specific parameters.\n", + "\n", + " # non-randomness parameter - alpha_ij (set at 0.3, 0 if i=j)\n", + " m.fs.properties.alpha[\"benzene\", \"benzene\"].fix(0)\n", + " m.fs.properties.alpha[\"benzene\", \"toluene\"].fix(0.3)\n", + " m.fs.properties.alpha[\"toluene\", \"toluene\"].fix(0)\n", + " m.fs.properties.alpha[\"toluene\", \"benzene\"].fix(0.3)\n", + "\n", + " # binary interaction parameter - tau_ij (0 if i=j, else to be estimated later but fixing to initialize)\n", + " m.fs.properties.tau[\"benzene\", \"benzene\"].fix(0)\n", + " m.fs.properties.tau[\"benzene\", \"toluene\"].fix(-0.9)\n", + " m.fs.properties.tau[\"toluene\", \"toluene\"].fix(0)\n", + " m.fs.properties.tau[\"toluene\", \"benzene\"].fix(1.4)\n", + "\n", + " # Initialize the flash unit\n", + " m.fs.state_block.initialize(outlvl=idaeslog.INFO_LOW)\n", + "\n", + " # Fix at actual temperature\n", + " if isinstance(data, dict) or isinstance(data, pd.Series):\n", + " m.fs.state_block.temperature.fix(float(data[\"temperature\"]))\n", + " elif isinstance(data, pd.DataFrame):\n", + " m.fs.state_block.temperature.fix(float(data.iloc[0][\"temperature\"]))\n", + " else:\n", + " raise ValueError(\"Unrecognized data type.\")\n", + "\n", + " # Set bounds on variables to be estimated\n", + " m.fs.properties.tau[\"benzene\", \"toluene\"].setlb(-5)\n", + " m.fs.properties.tau[\"benzene\", \"toluene\"].setub(5)\n", + "\n", + " m.fs.properties.tau[\"toluene\", \"benzene\"].setlb(-5)\n", + " m.fs.properties.tau[\"toluene\", \"benzene\"].setub(5)\n", + "\n", + " # Return initialized flash model\n", + " return m" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Parameter estimation using parmest" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In addition to providing a method to return an initialized model, the `parmest` tool needs the following:\n", + "\n", + "* Experiment class to set up and label model with suffixes\n", + "* Dataset with multiple scenarios - organized into an experiment list\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here we build an experiment class to label our model problem for parameter estimation. The labels are defined as a `Suffix`, and the main labels for our model are `experiment_outputs`, `unknown_parameters`. and `measurement_error`.\n", + "\n", + "For this problem, the error will be computed for the mole fraction of benzene in the vapor and liquid phase between the model prediction and data. The `experimental_outputs` will therefore be the mole fraction of benzene in the two phases.\n", + "\n", + "In this example, we only estimate the binary interaction parameter (`tau_ij`). Given that this variable is usually indexed as `tau_ij = Var(component_list, component_list)`, there are 2*2=4 degrees of freedom. However, when i=j, the binary interaction parameter is 0. Therefore, in this problem, we estimate the binary interaction parameter for the following variables only:\n", + "\n", + "* fs.properties.tau['benzene', 'toluene']\n", + "* fs.properties.tau['toluene', 'benzene']\n", + "\n", + "As shown below, these model components are used as our `unknown_parameters`.\n", + "\n", + "We define `measurement_error` as none so parmest calculates the value internally based on the experimental outputs. Refer to https://pyomo.readthedocs.io/en/stable/explanation/analysis/parmest/driver.html for more information. " + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "# Build an experiment class to take advantage of new parmest interface\n", + "from pyomo.contrib.parmest.experiment import Experiment\n", + "\n", + "\n", + "class NRTLExperiment(Experiment):\n", + " \"\"\"Experiment class for parameter estimation of NRTL model using parmest\"\"\"\n", + "\n", + " def __init__(self, data, meas_error=None):\n", + " \"\"\"Initialize the NRTLExperiment class\n", + "\n", + " Args:\n", + " data: DataFrame containing the experimental data\n", + " meas_error: Measurement error for the data (optional)\n", + " \"\"\"\n", + " self.model = None\n", + " self.data = data\n", + " self.meas_error = meas_error\n", + "\n", + " def create_model(self):\n", + " \"\"\"Create the Pyomo model for the NRTL parameter estimation problem\"\"\"\n", + " self.model = NRTL_model(self.data)\n", + "\n", + " def label_model(self):\n", + " import pyomo.environ as pyo\n", + " import pandas as pd\n", + "\n", + " m = self.model\n", + "\n", + " # Parmest expects the first index of experiment outputs to be the data point\n", + " # This is a workaround that will be addressed and corrected in a future release.\n", + "\n", + " m.data_point = pyo.Set(initialize=[0])\n", + "\n", + " # Wrap IDAES variables in Expressions indexed by data point\n", + " m.liq_benzene_out = pyo.Expression(\n", + " m.data_point,\n", + " rule=lambda m, i: m.fs.state_block.mole_frac_phase_comp[\"Liq\", \"benzene\"],\n", + " )\n", + "\n", + " m.vap_benzene_out = pyo.Expression(\n", + " m.data_point,\n", + " rule=lambda m, i: m.fs.state_block.mole_frac_phase_comp[\"Vap\", \"benzene\"],\n", + " )\n", + "\n", + " m.experiment_outputs = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + "\n", + " m.experiment_outputs[m.liq_benzene_out[0]] = float(self.data[\"liq_benzene\"])\n", + " m.experiment_outputs[m.vap_benzene_out[0]] = float(self.data[\"vap_benzene\"])\n", + "\n", + " m.measurement_error = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + " m.measurement_error.update(\n", + " [\n", + " (m.liq_benzene_out[0], self.meas_error),\n", + " (m.vap_benzene_out[0], self.meas_error),\n", + " ]\n", + " )\n", + "\n", + " # Add unknown parameters to the model for easier access\n", + " m.unknown_parameters = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + " m.unknown_parameters.update(\n", + " (k, value(k))\n", + " for k in [\n", + " m.fs.properties.tau[\"benzene\", \"toluene\"],\n", + " m.fs.properties.tau[\"toluene\", \"benzene\"],\n", + " ]\n", + " )\n", + "\n", + " def get_labeled_model(self):\n", + " \"\"\"Return the labeled model\"\"\"\n", + " if self.model is None:\n", + " self.create_model()\n", + " self.label_model()\n", + " return self.model" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Pyomo's `parmest` tool supports the following data formats:\n", + "- pandas dataframe\n", + "- list of dictionaries\n", + "- list of json file names.\n", + "\n", + "Please see the documentation for more details. \n", + "\n", + "For this example, we load data from the csv file `BT_NRTL_dataset.csv`. The dataset consists of fifty data points which provide the mole fraction of benzene in the vapor and liquid phase as a function of temperature. " + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
temperatureliq_benzenevap_benzene
0365.5000000.4809530.692110
1365.6176470.4624440.667699
2365.7352940.4779840.692441
3365.8529410.4405470.640336
4365.9705880.4274210.623328
5366.0882350.4427250.647796
6366.2058820.4343740.637691
7366.3235290.4446420.654933
8366.4411760.4271320.631229
9366.5588240.4463010.661743
10366.6764710.4380040.651591
11366.7941180.4253200.634814
12366.9117650.4394350.658047
13367.0294120.4356550.654539
14367.1470590.4013500.604987
15367.2647060.3978620.601703
16367.3823530.4158210.630930
17367.5000000.4206670.640380
18367.6176470.3916830.598214
19367.7352940.4049030.620432
20367.8529410.4095630.629626
21367.9705880.3894880.600722
22368.0000000.3967890.612483
23368.0882350.3981620.616106
24368.2058820.3623400.562505
25368.3235290.3869580.602680
26368.4411760.3636430.568210
27368.5588240.3681180.577072
28368.6764710.3840980.604078
29368.7941180.3536050.557925
30368.9117650.3464740.548445
31369.0294120.3507410.556996
32369.1470590.3623470.577286
33369.2647060.3625780.579519
34369.3823530.3407650.546411
35369.5000000.3374620.542857
36369.6176470.3557290.574083
37369.7352940.3486790.564513
38369.8529410.3381870.549284
39369.9705880.3243600.528514
40370.0882350.3107530.507964
41370.2058820.3110370.510055
42370.3235290.3112630.512055
43370.4411760.3080810.508437
44370.5588240.3082240.510293
45370.6764710.3181480.528399
46370.7941180.3083340.513728
47370.9117650.3179370.531410
48371.0294120.2891490.484824
49371.1470590.2986370.502318
\n", + "
" + ], + "text/plain": [ + " temperature liq_benzene vap_benzene\n", + "0 365.500000 0.480953 0.692110\n", + "1 365.617647 0.462444 0.667699\n", + "2 365.735294 0.477984 0.692441\n", + "3 365.852941 0.440547 0.640336\n", + "4 365.970588 0.427421 0.623328\n", + "5 366.088235 0.442725 0.647796\n", + "6 366.205882 0.434374 0.637691\n", + "7 366.323529 0.444642 0.654933\n", + "8 366.441176 0.427132 0.631229\n", + "9 366.558824 0.446301 0.661743\n", + "10 366.676471 0.438004 0.651591\n", + "11 366.794118 0.425320 0.634814\n", + "12 366.911765 0.439435 0.658047\n", + "13 367.029412 0.435655 0.654539\n", + "14 367.147059 0.401350 0.604987\n", + "15 367.264706 0.397862 0.601703\n", + "16 367.382353 0.415821 0.630930\n", + "17 367.500000 0.420667 0.640380\n", + "18 367.617647 0.391683 0.598214\n", + "19 367.735294 0.404903 0.620432\n", + "20 367.852941 0.409563 0.629626\n", + "21 367.970588 0.389488 0.600722\n", + "22 368.000000 0.396789 0.612483\n", + "23 368.088235 0.398162 0.616106\n", + "24 368.205882 0.362340 0.562505\n", + "25 368.323529 0.386958 0.602680\n", + "26 368.441176 0.363643 0.568210\n", + "27 368.558824 0.368118 0.577072\n", + "28 368.676471 0.384098 0.604078\n", + "29 368.794118 0.353605 0.557925\n", + "30 368.911765 0.346474 0.548445\n", + "31 369.029412 0.350741 0.556996\n", + "32 369.147059 0.362347 0.577286\n", + "33 369.264706 0.362578 0.579519\n", + "34 369.382353 0.340765 0.546411\n", + "35 369.500000 0.337462 0.542857\n", + "36 369.617647 0.355729 0.574083\n", + "37 369.735294 0.348679 0.564513\n", + "38 369.852941 0.338187 0.549284\n", + "39 369.970588 0.324360 0.528514\n", + "40 370.088235 0.310753 0.507964\n", + "41 370.205882 0.311037 0.510055\n", + "42 370.323529 0.311263 0.512055\n", + "43 370.441176 0.308081 0.508437\n", + "44 370.558824 0.308224 0.510293\n", + "45 370.676471 0.318148 0.528399\n", + "46 370.794118 0.308334 0.513728\n", + "47 370.911765 0.317937 0.531410\n", + "48 371.029412 0.289149 0.484824\n", + "49 371.147059 0.298637 0.502318" + ] + }, + "metadata": {}, + "output_type": "display_data" + } ], - "text/plain": [ - " temperature liq_benzene vap_benzene\n", - "0 365.500000 0.480953 0.692110\n", - "1 365.617647 0.462444 0.667699\n", - "2 365.735294 0.477984 0.692441\n", - "3 365.852941 0.440547 0.640336\n", - "4 365.970588 0.427421 0.623328\n", - "5 366.088235 0.442725 0.647796\n", - "6 366.205882 0.434374 0.637691\n", - "7 366.323529 0.444642 0.654933\n", - "8 366.441176 0.427132 0.631229\n", - "9 366.558824 0.446301 0.661743\n", - "10 366.676471 0.438004 0.651591\n", - "11 366.794118 0.425320 0.634814\n", - "12 366.911765 0.439435 0.658047\n", - "13 367.029412 0.435655 0.654539\n", - "14 367.147059 0.401350 0.604987\n", - "15 367.264706 0.397862 0.601703\n", - "16 367.382353 0.415821 0.630930\n", - "17 367.500000 0.420667 0.640380\n", - "18 367.617647 0.391683 0.598214\n", - "19 367.735294 0.404903 0.620432\n", - "20 367.852941 0.409563 0.629626\n", - "21 367.970588 0.389488 0.600722\n", - "22 368.000000 0.396789 0.612483\n", - "23 368.088235 0.398162 0.616106\n", - "24 368.205882 0.362340 0.562505\n", - "25 368.323529 0.386958 0.602680\n", - "26 368.441176 0.363643 0.568210\n", - "27 368.558824 0.368118 0.577072\n", - "28 368.676471 0.384098 0.604078\n", - "29 368.794118 0.353605 0.557925\n", - "30 368.911765 0.346474 0.548445\n", - "31 369.029412 0.350741 0.556996\n", - "32 369.147059 0.362347 0.577286\n", - "33 369.264706 0.362578 0.579519\n", - "34 369.382353 0.340765 0.546411\n", - "35 369.500000 0.337462 0.542857\n", - "36 369.617647 0.355729 0.574083\n", - "37 369.735294 0.348679 0.564513\n", - "38 369.852941 0.338187 0.549284\n", - "39 369.970588 0.324360 0.528514\n", - "40 370.088235 0.310753 0.507964\n", - "41 370.205882 0.311037 0.510055\n", - "42 370.323529 0.311263 0.512055\n", - "43 370.441176 0.308081 0.508437\n", - "44 370.558824 0.308224 0.510293\n", - "45 370.676471 0.318148 0.528399\n", - "46 370.794118 0.308334 0.513728\n", - "47 370.911765 0.317937 0.531410\n", - "48 371.029412 0.289149 0.484824\n", - "49 371.147059 0.298637 0.502318" + "source": [ + "# Load data from csv\n", + "data = pd.read_csv(\"BT_NRTL_dataset.csv\")\n", + "\n", + "# Display the dataset\n", + "display(data)" ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# Load data from csv\n", - "data = pd.read_csv(\"BT_NRTL_dataset.csv\")\n", - "\n", - "# Display the dataset\n", - "display(data)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "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 mole fraction of benzene in the vapor and liquid phase between the model prediction and data. \n", - "\n", - "
\n", - "Inline Exercise:\n", - "Complete the following cell by adding an expression to compute the sum of square errors. \n", - "
" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": { - "tags": [ - "solution" - ] - }, - "outputs": [], - "source": [ - "# Create method to return an expression that computes the sum of squared error\n", - "def SSE(m, data):\n", - " # Todo: Add expression for computing the sum of squared errors in mole fraction of benzene in the liquid\n", - " # and vapor phase. For example, the squared error for the vapor phase is:\n", - " # (float(data[\"vap_benzene\"]) - m.fs.state_block.mole_frac_phase_comp[\"Vap\", \"benzene\"])**2\n", - " expr = (\n", - " float(data[\"vap_benzene\"])\n", - " - m.fs.state_block.mole_frac_phase_comp[\"Vap\", \"benzene\"]\n", - " ) ** 2 + (\n", - " float(data[\"liq_benzene\"])\n", - " - m.fs.state_block.mole_frac_phase_comp[\"Liq\", \"benzene\"]\n", - " ) ** 2\n", - " return expr * 1e4" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
\n", - "Note:\n", - "Notice that we have scaled the expression up by a factor of 10000 as the SSE computed here will be an extremely small number given that we are using the difference in mole fraction in our expression. This will help in using a well-scaled objective to improve solve robustness when using IPOPT. \n", - "
\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "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. " - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ + }, { - "name": "stderr", - "output_type": "stream", - "text": [ - "C:\\Users\\dkgun\\AppData\\Local\\Temp\\ipykernel_11124\\1110609025.py:44: FutureWarning: Calling float on a single element Series is deprecated and will raise a TypeError in the future. Use float(ser.iloc[0]) instead\n", - " m.fs.state_block.temperature.fix(float(data[\"temperature\"]))\n", - "C:\\Users\\dkgun\\AppData\\Local\\Temp\\ipykernel_11124\\426137296.py:7: FutureWarning: Calling float on a single element Series is deprecated and will raise a TypeError in the future. Use float(ser.iloc[0]) instead\n", - " float(data[\"vap_benzene\"])\n", - "C:\\Users\\dkgun\\AppData\\Local\\Temp\\ipykernel_11124\\426137296.py:10: FutureWarning: Calling float on a single element Series is deprecated and will raise a TypeError in the future. Use float(ser.iloc[0]) instead\n", - " float(data[\"liq_benzene\"])\n" - ] + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We define the `exp_list` by spliting the data into individual experiments, or data points." + ] }, { - "name": "stdout", - "output_type": "stream", - "text": [ - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3746\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2200\n", - "\n", - "Total number of variables............................: 1100\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 300\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1098\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 6.0671019e+01 3.15e+00 4.84e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 5.2961050e+00 1.76e+03 5.05e+00 -1.0 1.37e+04 - 9.74e-01 1.00e+00f 1\n", - " 2 5.2586169e+00 4.01e+02 1.09e+00 -1.0 5.15e+02 - 1.00e+00 1.00e+00h 1\n", - " 3 5.1450958e+00 7.04e+01 2.27e-01 -1.0 4.11e+01 - 1.00e+00 1.00e+00h 1\n", - " 4 5.0748980e+00 1.25e+02 2.08e-01 -1.7 5.74e+02 - 1.00e+00 1.00e+00h 1\n", - " 5 5.0775194e+00 7.87e+00 1.92e-01 -1.7 8.44e+01 - 1.00e+00 1.00e+00h 1\n", - " 6 5.0726692e+00 1.37e+01 1.90e-01 -2.5 1.38e+02 - 1.00e+00 1.00e+00h 1\n", - " 7 5.0750377e+00 2.85e+00 2.60e-02 -2.5 6.99e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 5.0749670e+00 7.36e-02 2.81e-03 -3.8 9.72e+00 - 1.00e+00 1.00e+00h 1\n", - " 9 5.0749687e+00 4.51e-04 4.80e-06 -3.8 1.01e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 5.0749686e+00 2.91e-04 1.36e-06 -5.7 5.81e-01 - 1.00e+00 1.00e+00h 1\n", - " 11 5.0749686e+00 4.78e-08 2.18e-10 -8.6 7.65e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 11\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 5.0749685783046434e+00 5.0749685783046434e+00\n", - "Dual infeasibility......: 2.1827409324437497e-10 2.1827409324437497e-10\n", - "Constraint violation....: 1.6625508263665860e-10 4.7832145355641842e-08\n", - "Complementarity.........: 2.5076274461651402e-09 2.5076274461651402e-09\n", - "Overall NLP error.......: 2.5076274461651402e-09 4.7832145355641842e-08\n", - "\n", - "\n", - "Number of objective function evaluations = 12\n", - "Number of objective gradient evaluations = 12\n", - "Number of equality constraint evaluations = 12\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 12\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 11\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.002\n", - "Total CPU secs in NLP function evaluations = 0.010\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "\b\b\b\b\b\b\b\b\b\b\b\b\b\b" - ] - } - ], - "source": [ - "import logging\n", - "\n", - "idaeslog.getIdaesLogger(\"core.property_meta\").setLevel(logging.ERROR)\n", - "# Initialize a parameter estimation object\n", - "pest = parmest.Estimator(NRTL_model, data, variable_name, SSE, tee=True)\n", - "\n", - "# Run parameter estimation using all data\n", - "obj_value, parameters = pest.theta_est()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You will notice that the resulting parameter estimation problem will have 1102 variables and 1100 constraints. Let us display the results by running the next cell. " - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "# Update to new interface\n", + "exp_list = []\n", + "for i in range(data.shape[0]):\n", + " exp_list.append(NRTLExperiment(data.iloc[i]))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "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." + ] + }, { - "name": "stdout", - "output_type": "stream", - "text": [ - "The SSE at the optimal solution is 0.000507\n", - "\n", - "The values for the parameters are as follows:\n", - "fs.properties.tau[benzene,toluene] = -0.8987624036283798\n", - "fs.properties.tau[toluene,benzene] = 1.4104861099366137\n" - ] + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3750\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2200\n", + "\n", + "Total number of variables............................: 1102\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 300\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1100\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 6.0671019e-03 3.15e+00 1.97e-05 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 8.6249856e-04 1.40e+03 2.15e-01 -1.0 1.37e+04 - 9.95e-01 1.00e+00h 1\n", + " 2 1.1627234e-03 9.11e+03 8.21e-01 -1.7 4.74e+02 - 8.66e-01 1.00e+00h 1\n", + " 3 1.0978149e-03 9.02e+03 7.99e-01 -1.7 5.89e+00 -4.0 5.44e-01 2.64e-02h 6\n", + " 4 8.5702670e-04 8.63e+02 3.17e-02 -1.7 6.93e-01 -2.7 1.00e+00 1.00e+00h 1\n", + " 5 1.3332724e-03 3.57e+03 7.92e-03 -1.7 7.75e-01 - 1.00e+00 1.00e+00h 1\n", + " 6 1.5692588e-03 1.64e+02 2.34e-04 -1.7 1.98e-01 - 1.00e+00 1.00e+00h 1\n", + " 7 1.5828905e-03 1.20e+01 1.13e-05 -1.7 4.29e-02 - 1.00e+00 1.00e+00h 1\n", + " 8 1.4366151e-03 9.18e-01 2.34e-04 -2.5 5.49e-02 - 1.00e+00 1.00e+00h 1\n", + " 9 8.9194043e-04 2.19e+01 2.00e-04 -3.8 2.51e-01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 5.9835646e-04 3.72e+01 2.34e-05 -3.8 3.13e-01 - 1.00e+00 1.00e+00h 1\n", + " 11 5.9839648e-04 1.26e+00 4.06e-08 -3.8 2.87e-02 - 1.00e+00 1.00e+00h 1\n", + " 12 5.9838953e-04 4.33e-05 1.60e-12 -3.8 9.40e-05 - 1.00e+00 1.00e+00h 1\n", + " 13 5.9077073e-04 1.21e+01 2.96e-06 -5.7 4.79e-02 - 1.00e+00 1.00e+00h 1\n", + " 14 5.9066394e-04 1.19e-03 4.25e-07 -5.7 5.98e-04 -3.1 1.00e+00 1.00e+00h 1\n", + " 15 5.9059984e-04 1.08e-02 2.96e-07 -8.6 1.25e-03 -3.6 1.00e+00 1.00e+00h 1\n", + " 16 5.9042438e-04 9.67e-02 2.92e-07 -8.6 3.70e-03 -4.1 1.00e+00 1.00e+00h 1\n", + " 17 5.8992758e-04 8.72e-01 2.91e-07 -8.6 1.11e-02 -4.6 1.00e+00 1.00e+00h 1\n", + " 18 5.8840706e-04 8.23e+00 3.09e-07 -8.6 3.40e-02 -5.1 1.00e+00 1.00e+00h 1\n", + " 19 5.8319289e-04 9.25e+01 1.97e-06 -8.6 1.15e-01 -5.5 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 5.4836946e-04 3.88e+03 1.22e-04 -8.6 7.95e-01 -6.0 1.00e+00 1.00e+00h 1\n", + " 21 5.0847689e-04 4.45e+02 1.04e-04 -8.6 3.55e-01 -5.6 1.00e+00 1.00e+00h 1\n", + " 22 5.0727291e-04 4.20e+00 1.54e-05 -8.6 6.20e+02 - 1.00e+00 1.00e+00h 1\n", + " 23 5.0749772e-04 1.36e+00 1.44e-06 -8.6 5.13e+01 - 1.00e+00 1.00e+00h 1\n", + " 24 5.0749686e-04 6.93e-06 4.21e-11 -8.6 3.55e-01 - 1.00e+00 1.00e+00h 1\n", + " 25 5.0749686e-04 3.36e-06 1.49e-12 -9.0 6.25e-02 - 1.00e+00 1.00e+00h 1\n", + " 26 5.0749686e-04 1.02e-10 2.36e-18 -9.0 5.08e-06 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 26\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 5.0749685787934424e-04 5.0749685787934424e-04\n", + "Dual infeasibility......: 2.3583858113882067e-18 2.3583858113882067e-18\n", + "Constraint violation....: 3.5405706676501683e-13 1.0186340659856796e-10\n", + "Complementarity.........: 9.0909090909091344e-10 9.0909090909091344e-10\n", + "Overall NLP error.......: 9.0909090909091344e-10 9.0909090909091344e-10\n", + "\n", + "\n", + "Number of objective function evaluations = 33\n", + "Number of objective gradient evaluations = 27\n", + "Number of equality constraint evaluations = 34\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 27\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 26\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.035\n", + "Total CPU secs in NLP function evaluations = 0.009\n", + "\n", + "EXIT: Optimal Solution Found.\n" + ] + } + ], + "source": [ + "import logging\n", + "\n", + "idaeslog.getIdaesLogger(\"core.property_meta\").setLevel(logging.ERROR)\n", + "\n", + "pest = parmest.Estimator(exp_list, obj_function=\"SSE\", tee=True)\n", + "obj_value, parameters = pest.theta_est()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You will notice that the resulting parameter estimation problem will have 1102 variables and 1100 constraints. Let us display the results by running the next cell. " + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The SSE at the optimal solution is 0.000507\n", + "\n", + "The values for the parameters are as follows:\n", + "fs.properties.tau[benzene,toluene] = -0.8987550041842163\n", + "fs.properties.tau[toluene,benzene] = 1.4104702103547941\n" + ] + } + ], + "source": [ + "print(\"The SSE at the optimal solution is %0.6f\" % (obj_value))\n", + "print()\n", + "print(\"The values for the parameters are as follows:\")\n", + "for k, v in parameters.items():\n", + " print(k, \"=\", v)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Using the data that was provided, we have estimated the binary interaction parameters in the NRTL model for a benzene-toluene mixture. Although the dataset that was provided was temperature dependent, in this example we have estimated a single value that fits best for all temperatures." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Advanced options for parmest: bootstrapping\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Pyomo's `parmest` tool allows for bootstrapping where the parameter estimation is repeated over `n` samples with resampling from the original data set. Parameter estimation with bootstrap resampling can be used to identify confidence regions around each parameter estimate. This analysis can be slow given the increased number of model instances that need to be solved. Please refer to https://pyomo.readthedocs.io/en/stable/contributed_packages/parmest/driver.html for more details. \n", + "\n", + "For the example above, the bootstrapping can be run by uncommenting the code in the following cell:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "# Uncomment the following lines\n", + "# bootstrap_theta = pest.theta_est_bootstrap(4, seed=542)\n", + "# display(bootstrap_theta)" + ] + } + ], + "metadata": { + "celltoolbar": "Tags", + "kernelspec": { + "display_name": "idaes-examples-dev-py313-macmini", + "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.13.13" } - ], - "source": [ - "print(\"The SSE at the optimal solution is %0.6f\" % (obj_value * 1e-4))\n", - "print()\n", - "print(\"The values for the parameters are as follows:\")\n", - "for k, v in parameters.items():\n", - " print(k, \"=\", v)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Using the data that was provided, we have estimated the binary interaction parameters in the NRTL model for a benzene-toluene mixture. Although the dataset that was provided was temperature dependent, in this example we have estimated a single value that fits best for all temperatures." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Advanced options for parmest: bootstrapping\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Pyomo's `parmest` tool allows for bootstrapping where the parameter estimation is repeated over `n` samples with resampling from the original data set. Parameter estimation with bootstrap resampling can be used to identify confidence regions around each parameter estimate. This analysis can be slow given the increased number of model instances that need to be solved. Please refer to https://pyomo.readthedocs.io/en/stable/contributed_packages/parmest/driver.html for more details. \n", - "\n", - "For the example above, the bootstrapping can be run by uncommenting the code in the following cell:" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [], - "source": [ - "# Run parameter estimation using bootstrap resample of the data (10 samples),\n", - "# plot results along with confidence regions\n", - "\n", - "# Uncomment the following code:\n", - "# bootstrap_theta = pest.theta_est_bootstrap(4)\n", - "# display(bootstrap_theta)" - ] - } - ], - "metadata": { - "celltoolbar": "Tags", - "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.11.5" - } - }, - "nbformat": 4, - "nbformat_minor": 3 + "nbformat": 4, + "nbformat_minor": 3 } \ No newline at end of file diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_exercise.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_exercise.ipynb index 23756bea..390d71fa 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_exercise.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_exercise.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 10, + "execution_count": 1, "metadata": { "tags": [ "header", @@ -16,7 +16,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", @@ -32,8 +32,8 @@ "# Parameter Estimation Using the NRTL State Block\n", "\n", "Author: Jaffer Ghouse \n", - "Maintainer: Andrew Lee \n", - "Updated: 2023-06-01 \n", + "Maintainer: Stephen Cini \n", + "Updated: 2026-06-11 \n", "\n", "In this module, we use Pyomo's `parmest` tool in conjunction with IDAES models for parameter estimation. We demonstrate these tools by estimating the parameters associated with the NRTL property model for a benzene-toluene mixture. The NRTL model has 2 sets of parameters: the non-randomness parameter (`alpha_ij`) and the binary interaction parameter (`tau_ij`), where `i` and `j` are the pure component species. In this example, we only estimate the binary interaction parameter (`tau_ij`) for a given dataset. 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 only the state block. \n", "\n", @@ -45,8 +45,7 @@ "\n", "## Key links to documentation:\n", "* NRTL Model - https://idaes-pse.readthedocs.io/en/stable/reference_guides/model_libraries/generic/property_models/activity_coefficient.html\n", - "* parmest - https://pyomo.readthedocs.io/en/stable/contributed_packages/parmest/index.html\n", - "" + "* parmest - https://pyomo.readthedocs.io/en/stable/explanation/analysis/parmest/index.html\n" ] }, { @@ -55,13 +54,13 @@ "source": [ "
\n", "Inline Exercise:\n", - "import `ConcreteModel` from Pyomo and `FlowsheetBlock` from IDAES. \n", + "import `ConcreteModel`, `value`, and `Suffix` from Pyomo, `FlowsheetBlock` and `Flash` from IDAES. \n", "
" ] }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 2, "metadata": { "tags": [ "exercise" @@ -69,7 +68,7 @@ }, "outputs": [], "source": [ - "# Todo: import ConcreteModel from pyomo.environ\n", + "# Todo: import ConcreteModel, value, and Suffix from pyomo.environ\n", "\n", "# Todo: import FlowsheetBlock from idaes.core" ] @@ -83,7 +82,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 4, "metadata": { "tags": [] }, @@ -104,7 +103,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 5, "metadata": { "tags": [] }, @@ -135,7 +134,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 6, "metadata": { "tags": [ "exercise" @@ -181,7 +180,12 @@ " m.fs.state_block.initialize(outlvl=idaeslog.INFO)\n", "\n", " # Fix at actual temperature\n", - " m.fs.state_block.temperature.fix(float(data[\"temperature\"]))\n", + " if isinstance(data, dict) or isinstance(data, pd.Series):\n", + " m.fs.state_block.temperature.fix(float(data[\"temperature\"]))\n", + " elif isinstance(data, pd.DataFrame):\n", + " m.fs.state_block.temperature.fix(float(data.iloc[0][\"temperature\"]))\n", + " else:\n", + " raise ValueError(\"Unrecognized data type.\")\n", "\n", " # Set bounds on variables to be estimated\n", " m.fs.properties.tau[\"benzene\", \"toluene\"].setlb(-5)\n", @@ -207,37 +211,107 @@ "source": [ "In addition to providing a method to return an initialized model, the `parmest` tool needs the following:\n", "\n", - "* List of variable names to be estimated\n", - "* Dataset\n", - "* Expression to compute the sum of squared errors\n" + "* Experiment class to set up and label model with suffixes\n", + "* Dataset with multiple scenarios - organized into an experiment list\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ + "Here we build an experiment class to label our model problem for parameter estimation. The labels are defined as a `Suffix`, and the main labels for our model are `experiment_outputs`, `unknown_parameters`. and `measurement_error`.\n", + "\n", + "For this problem, the error will be computed for the mole fraction of benzene in the vapor and liquid phase between the model prediction and data. The `experimental_outputs` will therefore be the mole fraction of benzene in the two phases.\n", + "\n", "In this example, we only estimate the binary interaction parameter (`tau_ij`). Given that this variable is usually indexed as `tau_ij = Var(component_list, component_list)`, there are 2*2=4 degrees of freedom. However, when i=j, the binary interaction parameter is 0. Therefore, in this problem, we estimate the binary interaction parameter for the following variables only:\n", "\n", "* fs.properties.tau['benzene', 'toluene']\n", "* fs.properties.tau['toluene', 'benzene']\n", "\n", - "
\n", - "Inline Exercise:\n", - "Create a list called `variable_name` with the above-mentioned variables declared as strings.\n", - "
" + "As shown below, these model components are used as our `unknown_parameters`.\n", + "\n", + "We define `measurement_error` as none so parmest calculates the value internally based on the experimental outputs. Refer to https://pyomo.readthedocs.io/en/stable/explanation/analysis/parmest/driver.html for more information. " ] }, { "cell_type": "code", - "execution_count": 18, - "metadata": { - "tags": [ - "exercise" - ] - }, + "execution_count": 9, + "metadata": {}, "outputs": [], "source": [ - "# Todo: Create a list of vars to estimate" + "# Build an experiment class to take advantage of new parmest interface\n", + "from pyomo.contrib.parmest.experiment import Experiment\n", + "\n", + "\n", + "class NRTLExperiment(Experiment):\n", + " \"\"\"Experiment class for parameter estimation of NRTL model using parmest\"\"\"\n", + "\n", + " def __init__(self, data, meas_error=None):\n", + " \"\"\"Initialize the NRTLExperiment class\n", + "\n", + " Args:\n", + " data: DataFrame containing the experimental data\n", + " meas_error: Measurement error for the data (optional)\n", + " \"\"\"\n", + " self.model = None\n", + " self.data = data\n", + " self.meas_error = meas_error\n", + "\n", + " def create_model(self):\n", + " \"\"\"Create the Pyomo model for the NRTL parameter estimation problem\"\"\"\n", + " self.model = NRTL_model(self.data)\n", + "\n", + " def label_model(self):\n", + " import pyomo.environ as pyo\n", + " import pandas as pd\n", + "\n", + " m = self.model\n", + "\n", + " # Parmest expects the first index of experiment outputs to be the data point\n", + " # This is a workaround that will be addressed and corrected in a future release.\n", + "\n", + " m.data_point = pyo.Set(initialize=[0])\n", + "\n", + " # Wrap IDAES variables in Expressions indexed by data point\n", + " m.liq_benzene_out = pyo.Expression(\n", + " m.data_point,\n", + " rule=lambda m, i: m.fs.state_block.mole_frac_phase_comp[\"Liq\", \"benzene\"],\n", + " )\n", + "\n", + " m.vap_benzene_out = pyo.Expression(\n", + " m.data_point,\n", + " rule=lambda m, i: m.fs.state_block.mole_frac_phase_comp[\"Vap\", \"benzene\"],\n", + " )\n", + "\n", + " m.experiment_outputs = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + "\n", + " m.experiment_outputs[m.liq_benzene_out[0]] = float(self.data[\"liq_benzene\"])\n", + " m.experiment_outputs[m.vap_benzene_out[0]] = float(self.data[\"vap_benzene\"])\n", + "\n", + " m.measurement_error = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + " m.measurement_error.update(\n", + " [\n", + " (m.liq_benzene_out[0], self.meas_error),\n", + " (m.vap_benzene_out[0], self.meas_error),\n", + " ]\n", + " )\n", + "\n", + " # Add unknown parameters to the model for easier access\n", + " m.unknown_parameters = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + " m.unknown_parameters.update(\n", + " (k, value(k))\n", + " for k in [\n", + " m.fs.properties.tau[\"benzene\", \"toluene\"],\n", + " m.fs.properties.tau[\"toluene\", \"benzene\"],\n", + " ]\n", + " )\n", + "\n", + " def get_labeled_model(self):\n", + " \"\"\"Return the labeled model\"\"\"\n", + " if self.model is None:\n", + " self.create_model()\n", + " self.label_model()\n", + " return self.model" ] }, { @@ -256,11 +330,400 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 10, "metadata": { "tags": [] }, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
temperatureliq_benzenevap_benzene
0365.5000000.4809530.692110
1365.6176470.4624440.667699
2365.7352940.4779840.692441
3365.8529410.4405470.640336
4365.9705880.4274210.623328
5366.0882350.4427250.647796
6366.2058820.4343740.637691
7366.3235290.4446420.654933
8366.4411760.4271320.631229
9366.5588240.4463010.661743
10366.6764710.4380040.651591
11366.7941180.4253200.634814
12366.9117650.4394350.658047
13367.0294120.4356550.654539
14367.1470590.4013500.604987
15367.2647060.3978620.601703
16367.3823530.4158210.630930
17367.5000000.4206670.640380
18367.6176470.3916830.598214
19367.7352940.4049030.620432
20367.8529410.4095630.629626
21367.9705880.3894880.600722
22368.0000000.3967890.612483
23368.0882350.3981620.616106
24368.2058820.3623400.562505
25368.3235290.3869580.602680
26368.4411760.3636430.568210
27368.5588240.3681180.577072
28368.6764710.3840980.604078
29368.7941180.3536050.557925
30368.9117650.3464740.548445
31369.0294120.3507410.556996
32369.1470590.3623470.577286
33369.2647060.3625780.579519
34369.3823530.3407650.546411
35369.5000000.3374620.542857
36369.6176470.3557290.574083
37369.7352940.3486790.564513
38369.8529410.3381870.549284
39369.9705880.3243600.528514
40370.0882350.3107530.507964
41370.2058820.3110370.510055
42370.3235290.3112630.512055
43370.4411760.3080810.508437
44370.5588240.3082240.510293
45370.6764710.3181480.528399
46370.7941180.3083340.513728
47370.9117650.3179370.531410
48371.0294120.2891490.484824
49371.1470590.2986370.502318
\n", + "
" + ], + "text/plain": [ + " temperature liq_benzene vap_benzene\n", + "0 365.500000 0.480953 0.692110\n", + "1 365.617647 0.462444 0.667699\n", + "2 365.735294 0.477984 0.692441\n", + "3 365.852941 0.440547 0.640336\n", + "4 365.970588 0.427421 0.623328\n", + "5 366.088235 0.442725 0.647796\n", + "6 366.205882 0.434374 0.637691\n", + "7 366.323529 0.444642 0.654933\n", + "8 366.441176 0.427132 0.631229\n", + "9 366.558824 0.446301 0.661743\n", + "10 366.676471 0.438004 0.651591\n", + "11 366.794118 0.425320 0.634814\n", + "12 366.911765 0.439435 0.658047\n", + "13 367.029412 0.435655 0.654539\n", + "14 367.147059 0.401350 0.604987\n", + "15 367.264706 0.397862 0.601703\n", + "16 367.382353 0.415821 0.630930\n", + "17 367.500000 0.420667 0.640380\n", + "18 367.617647 0.391683 0.598214\n", + "19 367.735294 0.404903 0.620432\n", + "20 367.852941 0.409563 0.629626\n", + "21 367.970588 0.389488 0.600722\n", + "22 368.000000 0.396789 0.612483\n", + "23 368.088235 0.398162 0.616106\n", + "24 368.205882 0.362340 0.562505\n", + "25 368.323529 0.386958 0.602680\n", + "26 368.441176 0.363643 0.568210\n", + "27 368.558824 0.368118 0.577072\n", + "28 368.676471 0.384098 0.604078\n", + "29 368.794118 0.353605 0.557925\n", + "30 368.911765 0.346474 0.548445\n", + "31 369.029412 0.350741 0.556996\n", + "32 369.147059 0.362347 0.577286\n", + "33 369.264706 0.362578 0.579519\n", + "34 369.382353 0.340765 0.546411\n", + "35 369.500000 0.337462 0.542857\n", + "36 369.617647 0.355729 0.574083\n", + "37 369.735294 0.348679 0.564513\n", + "38 369.852941 0.338187 0.549284\n", + "39 369.970588 0.324360 0.528514\n", + "40 370.088235 0.310753 0.507964\n", + "41 370.205882 0.311037 0.510055\n", + "42 370.323529 0.311263 0.512055\n", + "43 370.441176 0.308081 0.508437\n", + "44 370.558824 0.308224 0.510293\n", + "45 370.676471 0.318148 0.528399\n", + "46 370.794118 0.308334 0.513728\n", + "47 370.911765 0.317937 0.531410\n", + "48 371.029412 0.289149 0.484824\n", + "49 371.147059 0.298637 0.502318" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "# Load data from csv\n", "data = pd.read_csv(\"BT_NRTL_dataset.csv\")\n", @@ -273,63 +736,134 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "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 mole fraction of benzene in the vapor and liquid phase between the model prediction and data. \n", - "\n", - "
\n", - "Inline Exercise:\n", - "Complete the following cell by adding an expression to compute the sum of square errors. \n", - "
" + "We define the `exp_list` by spliting the data into individual experiments, or data points." ] }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "exercise" - ] - }, - "outputs": [], - "source": [ - "# Create method to return an expression that computes the sum of squared error\n", - "def SSE(m, data):\n", - " # Todo: Add expression for computing the sum of squared errors in mole fraction of benzene in the liquid\n", - " # and vapor phase. For example, the squared error for the vapor phase is:\n", - " # (float(data[\"vap_benzene\"]) - m.fs.state_block.mole_frac_phase_comp[\"Vap\", \"benzene\"])**2\n", - "\n", - " return expr * 1e4" - ] - }, - { - "cell_type": "markdown", + "execution_count": 11, "metadata": {}, + "outputs": [], "source": [ - "
\n", - "Note:\n", - "Notice that we have scaled the expression up by a factor of 10000 as the SSE computed here will be an extremely small number given that we are using the difference in mole fraction in our expression. This will help in using a well-scaled objective to improve solve robustness when using IPOPT. \n", - "
\n" + "# Update to new interface\n", + "exp_list = []\n", + "for i in range(data.shape[0]):\n", + " exp_list.append(NRTLExperiment(data.iloc[i]))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "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. " + "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." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3750\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2200\n", + "\n", + "Total number of variables............................: 1102\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 300\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1100\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 6.0671019e-03 3.15e+00 1.97e-05 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 8.6249856e-04 1.40e+03 2.15e-01 -1.0 1.37e+04 - 9.95e-01 1.00e+00h 1\n", + " 2 1.1627234e-03 9.11e+03 8.21e-01 -1.7 4.74e+02 - 8.66e-01 1.00e+00h 1\n", + " 3 1.0978149e-03 9.02e+03 7.99e-01 -1.7 5.89e+00 -4.0 5.44e-01 2.64e-02h 6\n", + " 4 8.5702670e-04 8.63e+02 3.17e-02 -1.7 6.93e-01 -2.7 1.00e+00 1.00e+00h 1\n", + " 5 1.3332724e-03 3.57e+03 7.92e-03 -1.7 7.75e-01 - 1.00e+00 1.00e+00h 1\n", + " 6 1.5692588e-03 1.64e+02 2.34e-04 -1.7 1.98e-01 - 1.00e+00 1.00e+00h 1\n", + " 7 1.5828905e-03 1.20e+01 1.13e-05 -1.7 4.29e-02 - 1.00e+00 1.00e+00h 1\n", + " 8 1.4366151e-03 9.18e-01 2.34e-04 -2.5 5.49e-02 - 1.00e+00 1.00e+00h 1\n", + " 9 8.9194043e-04 2.19e+01 2.00e-04 -3.8 2.51e-01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 5.9835646e-04 3.72e+01 2.34e-05 -3.8 3.13e-01 - 1.00e+00 1.00e+00h 1\n", + " 11 5.9839648e-04 1.26e+00 4.06e-08 -3.8 2.87e-02 - 1.00e+00 1.00e+00h 1\n", + " 12 5.9838953e-04 4.33e-05 1.60e-12 -3.8 9.40e-05 - 1.00e+00 1.00e+00h 1\n", + " 13 5.9077073e-04 1.21e+01 2.96e-06 -5.7 4.79e-02 - 1.00e+00 1.00e+00h 1\n", + " 14 5.9066394e-04 1.19e-03 4.25e-07 -5.7 5.98e-04 -3.1 1.00e+00 1.00e+00h 1\n", + " 15 5.9059984e-04 1.08e-02 2.96e-07 -8.6 1.25e-03 -3.6 1.00e+00 1.00e+00h 1\n", + " 16 5.9042438e-04 9.67e-02 2.92e-07 -8.6 3.70e-03 -4.1 1.00e+00 1.00e+00h 1\n", + " 17 5.8992758e-04 8.72e-01 2.91e-07 -8.6 1.11e-02 -4.6 1.00e+00 1.00e+00h 1\n", + " 18 5.8840706e-04 8.23e+00 3.09e-07 -8.6 3.40e-02 -5.1 1.00e+00 1.00e+00h 1\n", + " 19 5.8319289e-04 9.25e+01 1.97e-06 -8.6 1.15e-01 -5.5 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 5.4836946e-04 3.88e+03 1.22e-04 -8.6 7.95e-01 -6.0 1.00e+00 1.00e+00h 1\n", + " 21 5.0847689e-04 4.45e+02 1.04e-04 -8.6 3.55e-01 -5.6 1.00e+00 1.00e+00h 1\n", + " 22 5.0727291e-04 4.20e+00 1.54e-05 -8.6 6.20e+02 - 1.00e+00 1.00e+00h 1\n", + " 23 5.0749772e-04 1.36e+00 1.44e-06 -8.6 5.13e+01 - 1.00e+00 1.00e+00h 1\n", + " 24 5.0749686e-04 6.93e-06 4.21e-11 -8.6 3.55e-01 - 1.00e+00 1.00e+00h 1\n", + " 25 5.0749686e-04 3.36e-06 1.49e-12 -9.0 6.25e-02 - 1.00e+00 1.00e+00h 1\n", + " 26 5.0749686e-04 1.02e-10 2.36e-18 -9.0 5.08e-06 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 26\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 5.0749685787934424e-04 5.0749685787934424e-04\n", + "Dual infeasibility......: 2.3583858113882067e-18 2.3583858113882067e-18\n", + "Constraint violation....: 3.5405706676501683e-13 1.0186340659856796e-10\n", + "Complementarity.........: 9.0909090909091344e-10 9.0909090909091344e-10\n", + "Overall NLP error.......: 9.0909090909091344e-10 9.0909090909091344e-10\n", + "\n", + "\n", + "Number of objective function evaluations = 33\n", + "Number of objective gradient evaluations = 27\n", + "Number of equality constraint evaluations = 34\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 27\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 26\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.035\n", + "Total CPU secs in NLP function evaluations = 0.009\n", + "\n", + "EXIT: Optimal Solution Found.\n" + ] + } + ], "source": [ "import logging\n", "\n", "idaeslog.getIdaesLogger(\"core.property_meta\").setLevel(logging.ERROR)\n", - "# Initialize a parameter estimation object\n", - "pest = parmest.Estimator(NRTL_model, data, variable_name, SSE, tee=True)\n", "\n", - "# Run parameter estimation using all data\n", + "pest = parmest.Estimator(exp_list, obj_function=\"SSE\", tee=True)\n", "obj_value, parameters = pest.theta_est()" ] }, @@ -342,11 +876,23 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The SSE at the optimal solution is 0.000507\n", + "\n", + "The values for the parameters are as follows:\n", + "fs.properties.tau[benzene,toluene] = -0.8987550041842163\n", + "fs.properties.tau[toluene,benzene] = 1.4104702103547941\n" + ] + } + ], "source": [ - "print(\"The SSE at the optimal solution is %0.6f\" % (obj_value * 1e-4))\n", + "print(\"The SSE at the optimal solution is %0.6f\" % (obj_value))\n", "print()\n", "print(\"The values for the parameters are as follows:\")\n", "for k, v in parameters.items():\n", @@ -379,15 +925,12 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "metadata": {}, "outputs": [], "source": [ - "# Run parameter estimation using bootstrap resample of the data (10 samples),\n", - "# plot results along with confidence regions\n", - "\n", - "# Uncomment the following code:\n", - "# bootstrap_theta = pest.theta_est_bootstrap(4)\n", + "# Uncomment the following lines\n", + "# bootstrap_theta = pest.theta_est_bootstrap(4, seed=542)\n", "# display(bootstrap_theta)" ] } @@ -395,7 +938,7 @@ "metadata": { "celltoolbar": "Tags", "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "idaes-examples-dev-py313-macmini", "language": "python", "name": "python3" }, @@ -409,7 +952,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.9" + "version": "3.13.13" } }, "nbformat": 4, diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_solution.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_solution.ipynb index 5bdce840..97ab497e 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_solution.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_solution.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 10, + "execution_count": 1, "metadata": { "tags": [ "header", @@ -16,7 +16,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", @@ -32,8 +32,8 @@ "# Parameter Estimation Using the NRTL State Block\n", "\n", "Author: Jaffer Ghouse \n", - "Maintainer: Andrew Lee \n", - "Updated: 2023-06-01 \n", + "Maintainer: Stephen Cini \n", + "Updated: 2026-06-11 \n", "\n", "In this module, we use Pyomo's `parmest` tool in conjunction with IDAES models for parameter estimation. We demonstrate these tools by estimating the parameters associated with the NRTL property model for a benzene-toluene mixture. The NRTL model has 2 sets of parameters: the non-randomness parameter (`alpha_ij`) and the binary interaction parameter (`tau_ij`), where `i` and `j` are the pure component species. In this example, we only estimate the binary interaction parameter (`tau_ij`) for a given dataset. 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 only the state block. \n", "\n", @@ -45,8 +45,7 @@ "\n", "## Key links to documentation:\n", "* NRTL Model - https://idaes-pse.readthedocs.io/en/stable/reference_guides/model_libraries/generic/property_models/activity_coefficient.html\n", - "* parmest - https://pyomo.readthedocs.io/en/stable/contributed_packages/parmest/index.html\n", - "" + "* parmest - https://pyomo.readthedocs.io/en/stable/explanation/analysis/parmest/index.html\n" ] }, { @@ -55,13 +54,13 @@ "source": [ "
\n", "Inline Exercise:\n", - "import `ConcreteModel` from Pyomo and `FlowsheetBlock` from IDAES. \n", + "import `ConcreteModel`, `value`, and `Suffix` from Pyomo, `FlowsheetBlock` and `Flash` from IDAES. \n", "
" ] }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 2, "metadata": { "tags": [ "exercise" @@ -69,14 +68,14 @@ }, "outputs": [], "source": [ - "# Todo: import ConcreteModel from pyomo.environ\n", + "# Todo: import ConcreteModel, value, and Suffix from pyomo.environ\n", "\n", "# Todo: import FlowsheetBlock from idaes.core" ] }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 3, "metadata": { "tags": [ "solution" @@ -84,11 +83,14 @@ }, "outputs": [], "source": [ - "# Todo: import ConcreteModel from pyomo.environ\n", - "from pyomo.environ import ConcreteModel, value\n", + "# Todo: import ConcreteModel, value, and Suffix from pyomo.environ\n", + "from pyomo.environ import ConcreteModel, value, Suffix\n", "\n", "# Todo: import FlowsheetBlock from idaes.core\n", - "from idaes.core import FlowsheetBlock" + "from idaes.core import FlowsheetBlock\n", + "\n", + "# Todo: import Flash unit model from idaes.models.unit_models\n", + "from idaes.models.unit_models import Flash" ] }, { @@ -100,7 +102,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 4, "metadata": { "tags": [] }, @@ -121,7 +123,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 5, "metadata": { "tags": [] }, @@ -152,7 +154,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 6, "metadata": { "tags": [ "exercise" @@ -198,7 +200,12 @@ " m.fs.state_block.initialize(outlvl=idaeslog.INFO)\n", "\n", " # Fix at actual temperature\n", - " m.fs.state_block.temperature.fix(float(data[\"temperature\"]))\n", + " if isinstance(data, dict) or isinstance(data, pd.Series):\n", + " m.fs.state_block.temperature.fix(float(data[\"temperature\"]))\n", + " elif isinstance(data, pd.DataFrame):\n", + " m.fs.state_block.temperature.fix(float(data.iloc[0][\"temperature\"]))\n", + " else:\n", + " raise ValueError(\"Unrecognized data type.\")\n", "\n", " # Set bounds on variables to be estimated\n", " m.fs.properties.tau[\"benzene\", \"toluene\"].setlb(-5)\n", @@ -213,7 +220,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 7, "metadata": { "tags": [ "solution" @@ -264,7 +271,12 @@ " m.fs.state_block.initialize(outlvl=idaeslog.INFO_LOW)\n", "\n", " # Fix at actual temperature\n", - " m.fs.state_block.temperature.fix(float(data[\"temperature\"]))\n", + " if isinstance(data, dict) or isinstance(data, pd.Series):\n", + " m.fs.state_block.temperature.fix(float(data[\"temperature\"]))\n", + " elif isinstance(data, pd.DataFrame):\n", + " m.fs.state_block.temperature.fix(float(data.iloc[0][\"temperature\"]))\n", + " else:\n", + " raise ValueError(\"Unrecognized data type.\")\n", "\n", " # Set bounds on variables to be estimated\n", " m.fs.properties.tau[\"benzene\", \"toluene\"].setlb(-5)\n", @@ -290,54 +302,107 @@ "source": [ "In addition to providing a method to return an initialized model, the `parmest` tool needs the following:\n", "\n", - "* List of variable names to be estimated\n", - "* Dataset\n", - "* Expression to compute the sum of squared errors\n" + "* Experiment class to set up and label model with suffixes\n", + "* Dataset with multiple scenarios - organized into an experiment list\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ + "Here we build an experiment class to label our model problem for parameter estimation. The labels are defined as a `Suffix`, and the main labels for our model are `experiment_outputs`, `unknown_parameters`. and `measurement_error`.\n", + "\n", + "For this problem, the error will be computed for the mole fraction of benzene in the vapor and liquid phase between the model prediction and data. The `experimental_outputs` will therefore be the mole fraction of benzene in the two phases.\n", + "\n", "In this example, we only estimate the binary interaction parameter (`tau_ij`). Given that this variable is usually indexed as `tau_ij = Var(component_list, component_list)`, there are 2*2=4 degrees of freedom. However, when i=j, the binary interaction parameter is 0. Therefore, in this problem, we estimate the binary interaction parameter for the following variables only:\n", "\n", "* fs.properties.tau['benzene', 'toluene']\n", "* fs.properties.tau['toluene', 'benzene']\n", "\n", - "
\n", - "Inline Exercise:\n", - "Create a list called `variable_name` with the above-mentioned variables declared as strings.\n", - "
" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": { - "tags": [ - "exercise" - ] - }, - "outputs": [], - "source": [ - "# Todo: Create a list of vars to estimate" + "As shown below, these model components are used as our `unknown_parameters`.\n", + "\n", + "We define `measurement_error` as none so parmest calculates the value internally based on the experimental outputs. Refer to https://pyomo.readthedocs.io/en/stable/explanation/analysis/parmest/driver.html for more information. " ] }, { "cell_type": "code", - "execution_count": 19, - "metadata": { - "tags": [ - "solution" - ] - }, + "execution_count": 9, + "metadata": {}, "outputs": [], "source": [ - "# Todo: Create a list of vars to estimate\n", - "variable_name = [\n", - " \"fs.properties.tau['benzene', 'toluene']\",\n", - " \"fs.properties.tau['toluene', 'benzene']\",\n", - "]" + "# Build an experiment class to take advantage of new parmest interface\n", + "from pyomo.contrib.parmest.experiment import Experiment\n", + "\n", + "\n", + "class NRTLExperiment(Experiment):\n", + " \"\"\"Experiment class for parameter estimation of NRTL model using parmest\"\"\"\n", + "\n", + " def __init__(self, data, meas_error=None):\n", + " \"\"\"Initialize the NRTLExperiment class\n", + "\n", + " Args:\n", + " data: DataFrame containing the experimental data\n", + " meas_error: Measurement error for the data (optional)\n", + " \"\"\"\n", + " self.model = None\n", + " self.data = data\n", + " self.meas_error = meas_error\n", + "\n", + " def create_model(self):\n", + " \"\"\"Create the Pyomo model for the NRTL parameter estimation problem\"\"\"\n", + " self.model = NRTL_model(self.data)\n", + "\n", + " def label_model(self):\n", + " import pyomo.environ as pyo\n", + " import pandas as pd\n", + "\n", + " m = self.model\n", + "\n", + " # Parmest expects the first index of experiment outputs to be the data point\n", + " # This is a workaround that will be addressed and corrected in a future release.\n", + "\n", + " m.data_point = pyo.Set(initialize=[0])\n", + "\n", + " # Wrap IDAES variables in Expressions indexed by data point\n", + " m.liq_benzene_out = pyo.Expression(\n", + " m.data_point,\n", + " rule=lambda m, i: m.fs.state_block.mole_frac_phase_comp[\"Liq\", \"benzene\"],\n", + " )\n", + "\n", + " m.vap_benzene_out = pyo.Expression(\n", + " m.data_point,\n", + " rule=lambda m, i: m.fs.state_block.mole_frac_phase_comp[\"Vap\", \"benzene\"],\n", + " )\n", + "\n", + " m.experiment_outputs = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + "\n", + " m.experiment_outputs[m.liq_benzene_out[0]] = float(self.data[\"liq_benzene\"])\n", + " m.experiment_outputs[m.vap_benzene_out[0]] = float(self.data[\"vap_benzene\"])\n", + "\n", + " m.measurement_error = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + " m.measurement_error.update(\n", + " [\n", + " (m.liq_benzene_out[0], self.meas_error),\n", + " (m.vap_benzene_out[0], self.meas_error),\n", + " ]\n", + " )\n", + "\n", + " # Add unknown parameters to the model for easier access\n", + " m.unknown_parameters = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + " m.unknown_parameters.update(\n", + " (k, value(k))\n", + " for k in [\n", + " m.fs.properties.tau[\"benzene\", \"toluene\"],\n", + " m.fs.properties.tau[\"toluene\", \"benzene\"],\n", + " ]\n", + " )\n", + "\n", + " def get_labeled_model(self):\n", + " \"\"\"Return the labeled model\"\"\"\n", + " if self.model is None:\n", + " self.create_model()\n", + " self.label_model()\n", + " return self.model" ] }, { @@ -356,11 +421,400 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 10, "metadata": { "tags": [] }, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
temperatureliq_benzenevap_benzene
0365.5000000.4809530.692110
1365.6176470.4624440.667699
2365.7352940.4779840.692441
3365.8529410.4405470.640336
4365.9705880.4274210.623328
5366.0882350.4427250.647796
6366.2058820.4343740.637691
7366.3235290.4446420.654933
8366.4411760.4271320.631229
9366.5588240.4463010.661743
10366.6764710.4380040.651591
11366.7941180.4253200.634814
12366.9117650.4394350.658047
13367.0294120.4356550.654539
14367.1470590.4013500.604987
15367.2647060.3978620.601703
16367.3823530.4158210.630930
17367.5000000.4206670.640380
18367.6176470.3916830.598214
19367.7352940.4049030.620432
20367.8529410.4095630.629626
21367.9705880.3894880.600722
22368.0000000.3967890.612483
23368.0882350.3981620.616106
24368.2058820.3623400.562505
25368.3235290.3869580.602680
26368.4411760.3636430.568210
27368.5588240.3681180.577072
28368.6764710.3840980.604078
29368.7941180.3536050.557925
30368.9117650.3464740.548445
31369.0294120.3507410.556996
32369.1470590.3623470.577286
33369.2647060.3625780.579519
34369.3823530.3407650.546411
35369.5000000.3374620.542857
36369.6176470.3557290.574083
37369.7352940.3486790.564513
38369.8529410.3381870.549284
39369.9705880.3243600.528514
40370.0882350.3107530.507964
41370.2058820.3110370.510055
42370.3235290.3112630.512055
43370.4411760.3080810.508437
44370.5588240.3082240.510293
45370.6764710.3181480.528399
46370.7941180.3083340.513728
47370.9117650.3179370.531410
48371.0294120.2891490.484824
49371.1470590.2986370.502318
\n", + "
" + ], + "text/plain": [ + " temperature liq_benzene vap_benzene\n", + "0 365.500000 0.480953 0.692110\n", + "1 365.617647 0.462444 0.667699\n", + "2 365.735294 0.477984 0.692441\n", + "3 365.852941 0.440547 0.640336\n", + "4 365.970588 0.427421 0.623328\n", + "5 366.088235 0.442725 0.647796\n", + "6 366.205882 0.434374 0.637691\n", + "7 366.323529 0.444642 0.654933\n", + "8 366.441176 0.427132 0.631229\n", + "9 366.558824 0.446301 0.661743\n", + "10 366.676471 0.438004 0.651591\n", + "11 366.794118 0.425320 0.634814\n", + "12 366.911765 0.439435 0.658047\n", + "13 367.029412 0.435655 0.654539\n", + "14 367.147059 0.401350 0.604987\n", + "15 367.264706 0.397862 0.601703\n", + "16 367.382353 0.415821 0.630930\n", + "17 367.500000 0.420667 0.640380\n", + "18 367.617647 0.391683 0.598214\n", + "19 367.735294 0.404903 0.620432\n", + "20 367.852941 0.409563 0.629626\n", + "21 367.970588 0.389488 0.600722\n", + "22 368.000000 0.396789 0.612483\n", + "23 368.088235 0.398162 0.616106\n", + "24 368.205882 0.362340 0.562505\n", + "25 368.323529 0.386958 0.602680\n", + "26 368.441176 0.363643 0.568210\n", + "27 368.558824 0.368118 0.577072\n", + "28 368.676471 0.384098 0.604078\n", + "29 368.794118 0.353605 0.557925\n", + "30 368.911765 0.346474 0.548445\n", + "31 369.029412 0.350741 0.556996\n", + "32 369.147059 0.362347 0.577286\n", + "33 369.264706 0.362578 0.579519\n", + "34 369.382353 0.340765 0.546411\n", + "35 369.500000 0.337462 0.542857\n", + "36 369.617647 0.355729 0.574083\n", + "37 369.735294 0.348679 0.564513\n", + "38 369.852941 0.338187 0.549284\n", + "39 369.970588 0.324360 0.528514\n", + "40 370.088235 0.310753 0.507964\n", + "41 370.205882 0.311037 0.510055\n", + "42 370.323529 0.311263 0.512055\n", + "43 370.441176 0.308081 0.508437\n", + "44 370.558824 0.308224 0.510293\n", + "45 370.676471 0.318148 0.528399\n", + "46 370.794118 0.308334 0.513728\n", + "47 370.911765 0.317937 0.531410\n", + "48 371.029412 0.289149 0.484824\n", + "49 371.147059 0.298637 0.502318" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "# Load data from csv\n", "data = pd.read_csv(\"BT_NRTL_dataset.csv\")\n", @@ -373,88 +827,134 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "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 mole fraction of benzene in the vapor and liquid phase between the model prediction and data. \n", - "\n", - "
\n", - "Inline Exercise:\n", - "Complete the following cell by adding an expression to compute the sum of square errors. \n", - "
" + "We define the `exp_list` by spliting the data into individual experiments, or data points." ] }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "exercise" - ] - }, - "outputs": [], - "source": [ - "# Create method to return an expression that computes the sum of squared error\n", - "def SSE(m, data):\n", - " # Todo: Add expression for computing the sum of squared errors in mole fraction of benzene in the liquid\n", - " # and vapor phase. For example, the squared error for the vapor phase is:\n", - " # (float(data[\"vap_benzene\"]) - m.fs.state_block.mole_frac_phase_comp[\"Vap\", \"benzene\"])**2\n", - "\n", - " return expr * 1e4" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "solution" - ] - }, - "outputs": [], - "source": [ - "# Create method to return an expression that computes the sum of squared error\n", - "def SSE(m, data):\n", - " # Todo: Add expression for computing the sum of squared errors in mole fraction of benzene in the liquid\n", - " # and vapor phase. For example, the squared error for the vapor phase is:\n", - " # (float(data[\"vap_benzene\"]) - m.fs.state_block.mole_frac_phase_comp[\"Vap\", \"benzene\"])**2\n", - " expr = (\n", - " float(data[\"vap_benzene\"])\n", - " - m.fs.state_block.mole_frac_phase_comp[\"Vap\", \"benzene\"]\n", - " ) ** 2 + (\n", - " float(data[\"liq_benzene\"])\n", - " - m.fs.state_block.mole_frac_phase_comp[\"Liq\", \"benzene\"]\n", - " ) ** 2\n", - " return expr * 1e4" - ] - }, - { - "cell_type": "markdown", + "execution_count": 11, "metadata": {}, + "outputs": [], "source": [ - "
\n", - "Note:\n", - "Notice that we have scaled the expression up by a factor of 10000 as the SSE computed here will be an extremely small number given that we are using the difference in mole fraction in our expression. This will help in using a well-scaled objective to improve solve robustness when using IPOPT. \n", - "
\n" + "# Update to new interface\n", + "exp_list = []\n", + "for i in range(data.shape[0]):\n", + " exp_list.append(NRTLExperiment(data.iloc[i]))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "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. " + "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." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3750\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2200\n", + "\n", + "Total number of variables............................: 1102\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 300\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1100\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 6.0671019e-03 3.15e+00 1.97e-05 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 8.6249856e-04 1.40e+03 2.15e-01 -1.0 1.37e+04 - 9.95e-01 1.00e+00h 1\n", + " 2 1.1627234e-03 9.11e+03 8.21e-01 -1.7 4.74e+02 - 8.66e-01 1.00e+00h 1\n", + " 3 1.0978149e-03 9.02e+03 7.99e-01 -1.7 5.89e+00 -4.0 5.44e-01 2.64e-02h 6\n", + " 4 8.5702670e-04 8.63e+02 3.17e-02 -1.7 6.93e-01 -2.7 1.00e+00 1.00e+00h 1\n", + " 5 1.3332724e-03 3.57e+03 7.92e-03 -1.7 7.75e-01 - 1.00e+00 1.00e+00h 1\n", + " 6 1.5692588e-03 1.64e+02 2.34e-04 -1.7 1.98e-01 - 1.00e+00 1.00e+00h 1\n", + " 7 1.5828905e-03 1.20e+01 1.13e-05 -1.7 4.29e-02 - 1.00e+00 1.00e+00h 1\n", + " 8 1.4366151e-03 9.18e-01 2.34e-04 -2.5 5.49e-02 - 1.00e+00 1.00e+00h 1\n", + " 9 8.9194043e-04 2.19e+01 2.00e-04 -3.8 2.51e-01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 5.9835646e-04 3.72e+01 2.34e-05 -3.8 3.13e-01 - 1.00e+00 1.00e+00h 1\n", + " 11 5.9839648e-04 1.26e+00 4.06e-08 -3.8 2.87e-02 - 1.00e+00 1.00e+00h 1\n", + " 12 5.9838953e-04 4.33e-05 1.60e-12 -3.8 9.40e-05 - 1.00e+00 1.00e+00h 1\n", + " 13 5.9077073e-04 1.21e+01 2.96e-06 -5.7 4.79e-02 - 1.00e+00 1.00e+00h 1\n", + " 14 5.9066394e-04 1.19e-03 4.25e-07 -5.7 5.98e-04 -3.1 1.00e+00 1.00e+00h 1\n", + " 15 5.9059984e-04 1.08e-02 2.96e-07 -8.6 1.25e-03 -3.6 1.00e+00 1.00e+00h 1\n", + " 16 5.9042438e-04 9.67e-02 2.92e-07 -8.6 3.70e-03 -4.1 1.00e+00 1.00e+00h 1\n", + " 17 5.8992758e-04 8.72e-01 2.91e-07 -8.6 1.11e-02 -4.6 1.00e+00 1.00e+00h 1\n", + " 18 5.8840706e-04 8.23e+00 3.09e-07 -8.6 3.40e-02 -5.1 1.00e+00 1.00e+00h 1\n", + " 19 5.8319289e-04 9.25e+01 1.97e-06 -8.6 1.15e-01 -5.5 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 5.4836946e-04 3.88e+03 1.22e-04 -8.6 7.95e-01 -6.0 1.00e+00 1.00e+00h 1\n", + " 21 5.0847689e-04 4.45e+02 1.04e-04 -8.6 3.55e-01 -5.6 1.00e+00 1.00e+00h 1\n", + " 22 5.0727291e-04 4.20e+00 1.54e-05 -8.6 6.20e+02 - 1.00e+00 1.00e+00h 1\n", + " 23 5.0749772e-04 1.36e+00 1.44e-06 -8.6 5.13e+01 - 1.00e+00 1.00e+00h 1\n", + " 24 5.0749686e-04 6.93e-06 4.21e-11 -8.6 3.55e-01 - 1.00e+00 1.00e+00h 1\n", + " 25 5.0749686e-04 3.36e-06 1.49e-12 -9.0 6.25e-02 - 1.00e+00 1.00e+00h 1\n", + " 26 5.0749686e-04 1.02e-10 2.36e-18 -9.0 5.08e-06 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 26\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 5.0749685787934424e-04 5.0749685787934424e-04\n", + "Dual infeasibility......: 2.3583858113882067e-18 2.3583858113882067e-18\n", + "Constraint violation....: 3.5405706676501683e-13 1.0186340659856796e-10\n", + "Complementarity.........: 9.0909090909091344e-10 9.0909090909091344e-10\n", + "Overall NLP error.......: 9.0909090909091344e-10 9.0909090909091344e-10\n", + "\n", + "\n", + "Number of objective function evaluations = 33\n", + "Number of objective gradient evaluations = 27\n", + "Number of equality constraint evaluations = 34\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 27\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 26\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.035\n", + "Total CPU secs in NLP function evaluations = 0.009\n", + "\n", + "EXIT: Optimal Solution Found.\n" + ] + } + ], "source": [ "import logging\n", "\n", "idaeslog.getIdaesLogger(\"core.property_meta\").setLevel(logging.ERROR)\n", - "# Initialize a parameter estimation object\n", - "pest = parmest.Estimator(NRTL_model, data, variable_name, SSE, tee=True)\n", "\n", - "# Run parameter estimation using all data\n", + "pest = parmest.Estimator(exp_list, obj_function=\"SSE\", tee=True)\n", "obj_value, parameters = pest.theta_est()" ] }, @@ -467,11 +967,23 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The SSE at the optimal solution is 0.000507\n", + "\n", + "The values for the parameters are as follows:\n", + "fs.properties.tau[benzene,toluene] = -0.8987550041842163\n", + "fs.properties.tau[toluene,benzene] = 1.4104702103547941\n" + ] + } + ], "source": [ - "print(\"The SSE at the optimal solution is %0.6f\" % (obj_value * 1e-4))\n", + "print(\"The SSE at the optimal solution is %0.6f\" % (obj_value))\n", "print()\n", "print(\"The values for the parameters are as follows:\")\n", "for k, v in parameters.items():\n", @@ -504,15 +1016,12 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "metadata": {}, "outputs": [], "source": [ - "# Run parameter estimation using bootstrap resample of the data (10 samples),\n", - "# plot results along with confidence regions\n", - "\n", - "# Uncomment the following code:\n", - "# bootstrap_theta = pest.theta_est_bootstrap(4)\n", + "# Uncomment the following lines\n", + "# bootstrap_theta = pest.theta_est_bootstrap(4, seed=542)\n", "# display(bootstrap_theta)" ] } @@ -520,7 +1029,7 @@ "metadata": { "celltoolbar": "Tags", "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "idaes-examples-dev-py313-macmini", "language": "python", "name": "python3" }, @@ -534,7 +1043,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.9" + "version": "3.13.13" } }, "nbformat": 4, diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_test.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_test.ipynb index 7d253335..9e504a6e 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_test.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_test.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 10, + "execution_count": 1, "metadata": { "tags": [ "header", @@ -16,7 +16,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", @@ -32,8 +32,8 @@ "# Parameter Estimation Using the NRTL State Block\n", "\n", "Author: Jaffer Ghouse \n", - "Maintainer: Andrew Lee \n", - "Updated: 2023-06-01 \n", + "Maintainer: Stephen Cini \n", + "Updated: 2026-06-11 \n", "\n", "In this module, we use Pyomo's `parmest` tool in conjunction with IDAES models for parameter estimation. We demonstrate these tools by estimating the parameters associated with the NRTL property model for a benzene-toluene mixture. The NRTL model has 2 sets of parameters: the non-randomness parameter (`alpha_ij`) and the binary interaction parameter (`tau_ij`), where `i` and `j` are the pure component species. In this example, we only estimate the binary interaction parameter (`tau_ij`) for a given dataset. 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 only the state block. \n", "\n", @@ -45,8 +45,7 @@ "\n", "## Key links to documentation:\n", "* NRTL Model - https://idaes-pse.readthedocs.io/en/stable/reference_guides/model_libraries/generic/property_models/activity_coefficient.html\n", - "* parmest - https://pyomo.readthedocs.io/en/stable/contributed_packages/parmest/index.html\n", - "" + "* parmest - https://pyomo.readthedocs.io/en/stable/explanation/analysis/parmest/index.html\n" ] }, { @@ -55,13 +54,13 @@ "source": [ "
\n", "Inline Exercise:\n", - "import `ConcreteModel` from Pyomo and `FlowsheetBlock` from IDAES. \n", + "import `ConcreteModel`, `value`, and `Suffix` from Pyomo, `FlowsheetBlock` and `Flash` from IDAES. \n", "
" ] }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 3, "metadata": { "tags": [ "solution" @@ -69,11 +68,14 @@ }, "outputs": [], "source": [ - "# Todo: import ConcreteModel from pyomo.environ\n", - "from pyomo.environ import ConcreteModel, value\n", + "# Todo: import ConcreteModel, value, and Suffix from pyomo.environ\n", + "from pyomo.environ import ConcreteModel, value, Suffix\n", "\n", "# Todo: import FlowsheetBlock from idaes.core\n", - "from idaes.core import FlowsheetBlock" + "from idaes.core import FlowsheetBlock\n", + "\n", + "# Todo: import Flash unit model from idaes.models.unit_models\n", + "from idaes.models.unit_models import Flash" ] }, { @@ -85,7 +87,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 4, "metadata": { "tags": [] }, @@ -106,7 +108,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 5, "metadata": { "tags": [] }, @@ -137,7 +139,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 7, "metadata": { "tags": [ "solution" @@ -188,7 +190,12 @@ " m.fs.state_block.initialize(outlvl=idaeslog.INFO_LOW)\n", "\n", " # Fix at actual temperature\n", - " m.fs.state_block.temperature.fix(float(data[\"temperature\"]))\n", + " if isinstance(data, dict) or isinstance(data, pd.Series):\n", + " m.fs.state_block.temperature.fix(float(data[\"temperature\"]))\n", + " elif isinstance(data, pd.DataFrame):\n", + " m.fs.state_block.temperature.fix(float(data.iloc[0][\"temperature\"]))\n", + " else:\n", + " raise ValueError(\"Unrecognized data type.\")\n", "\n", " # Set bounds on variables to be estimated\n", " m.fs.properties.tau[\"benzene\", \"toluene\"].setlb(-5)\n", @@ -203,7 +210,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 8, "metadata": { "tags": [ "testing" @@ -251,41 +258,107 @@ "source": [ "In addition to providing a method to return an initialized model, the `parmest` tool needs the following:\n", "\n", - "* List of variable names to be estimated\n", - "* Dataset\n", - "* Expression to compute the sum of squared errors\n" + "* Experiment class to set up and label model with suffixes\n", + "* Dataset with multiple scenarios - organized into an experiment list\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ + "Here we build an experiment class to label our model problem for parameter estimation. The labels are defined as a `Suffix`, and the main labels for our model are `experiment_outputs`, `unknown_parameters`. and `measurement_error`.\n", + "\n", + "For this problem, the error will be computed for the mole fraction of benzene in the vapor and liquid phase between the model prediction and data. The `experimental_outputs` will therefore be the mole fraction of benzene in the two phases.\n", + "\n", "In this example, we only estimate the binary interaction parameter (`tau_ij`). Given that this variable is usually indexed as `tau_ij = Var(component_list, component_list)`, there are 2*2=4 degrees of freedom. However, when i=j, the binary interaction parameter is 0. Therefore, in this problem, we estimate the binary interaction parameter for the following variables only:\n", "\n", "* fs.properties.tau['benzene', 'toluene']\n", "* fs.properties.tau['toluene', 'benzene']\n", "\n", - "
\n", - "Inline Exercise:\n", - "Create a list called `variable_name` with the above-mentioned variables declared as strings.\n", - "
" + "As shown below, these model components are used as our `unknown_parameters`.\n", + "\n", + "We define `measurement_error` as none so parmest calculates the value internally based on the experimental outputs. Refer to https://pyomo.readthedocs.io/en/stable/explanation/analysis/parmest/driver.html for more information. " ] }, { "cell_type": "code", - "execution_count": 19, - "metadata": { - "tags": [ - "solution" - ] - }, + "execution_count": 9, + "metadata": {}, "outputs": [], "source": [ - "# Todo: Create a list of vars to estimate\n", - "variable_name = [\n", - " \"fs.properties.tau['benzene', 'toluene']\",\n", - " \"fs.properties.tau['toluene', 'benzene']\",\n", - "]" + "# Build an experiment class to take advantage of new parmest interface\n", + "from pyomo.contrib.parmest.experiment import Experiment\n", + "\n", + "\n", + "class NRTLExperiment(Experiment):\n", + " \"\"\"Experiment class for parameter estimation of NRTL model using parmest\"\"\"\n", + "\n", + " def __init__(self, data, meas_error=None):\n", + " \"\"\"Initialize the NRTLExperiment class\n", + "\n", + " Args:\n", + " data: DataFrame containing the experimental data\n", + " meas_error: Measurement error for the data (optional)\n", + " \"\"\"\n", + " self.model = None\n", + " self.data = data\n", + " self.meas_error = meas_error\n", + "\n", + " def create_model(self):\n", + " \"\"\"Create the Pyomo model for the NRTL parameter estimation problem\"\"\"\n", + " self.model = NRTL_model(self.data)\n", + "\n", + " def label_model(self):\n", + " import pyomo.environ as pyo\n", + " import pandas as pd\n", + "\n", + " m = self.model\n", + "\n", + " # Parmest expects the first index of experiment outputs to be the data point\n", + " # This is a workaround that will be addressed and corrected in a future release.\n", + "\n", + " m.data_point = pyo.Set(initialize=[0])\n", + "\n", + " # Wrap IDAES variables in Expressions indexed by data point\n", + " m.liq_benzene_out = pyo.Expression(\n", + " m.data_point,\n", + " rule=lambda m, i: m.fs.state_block.mole_frac_phase_comp[\"Liq\", \"benzene\"],\n", + " )\n", + "\n", + " m.vap_benzene_out = pyo.Expression(\n", + " m.data_point,\n", + " rule=lambda m, i: m.fs.state_block.mole_frac_phase_comp[\"Vap\", \"benzene\"],\n", + " )\n", + "\n", + " m.experiment_outputs = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + "\n", + " m.experiment_outputs[m.liq_benzene_out[0]] = float(self.data[\"liq_benzene\"])\n", + " m.experiment_outputs[m.vap_benzene_out[0]] = float(self.data[\"vap_benzene\"])\n", + "\n", + " m.measurement_error = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + " m.measurement_error.update(\n", + " [\n", + " (m.liq_benzene_out[0], self.meas_error),\n", + " (m.vap_benzene_out[0], self.meas_error),\n", + " ]\n", + " )\n", + "\n", + " # Add unknown parameters to the model for easier access\n", + " m.unknown_parameters = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + " m.unknown_parameters.update(\n", + " (k, value(k))\n", + " for k in [\n", + " m.fs.properties.tau[\"benzene\", \"toluene\"],\n", + " m.fs.properties.tau[\"toluene\", \"benzene\"],\n", + " ]\n", + " )\n", + "\n", + " def get_labeled_model(self):\n", + " \"\"\"Return the labeled model\"\"\"\n", + " if self.model is None:\n", + " self.create_model()\n", + " self.label_model()\n", + " return self.model" ] }, { @@ -304,11 +377,400 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 10, "metadata": { "tags": [] }, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
temperatureliq_benzenevap_benzene
0365.5000000.4809530.692110
1365.6176470.4624440.667699
2365.7352940.4779840.692441
3365.8529410.4405470.640336
4365.9705880.4274210.623328
5366.0882350.4427250.647796
6366.2058820.4343740.637691
7366.3235290.4446420.654933
8366.4411760.4271320.631229
9366.5588240.4463010.661743
10366.6764710.4380040.651591
11366.7941180.4253200.634814
12366.9117650.4394350.658047
13367.0294120.4356550.654539
14367.1470590.4013500.604987
15367.2647060.3978620.601703
16367.3823530.4158210.630930
17367.5000000.4206670.640380
18367.6176470.3916830.598214
19367.7352940.4049030.620432
20367.8529410.4095630.629626
21367.9705880.3894880.600722
22368.0000000.3967890.612483
23368.0882350.3981620.616106
24368.2058820.3623400.562505
25368.3235290.3869580.602680
26368.4411760.3636430.568210
27368.5588240.3681180.577072
28368.6764710.3840980.604078
29368.7941180.3536050.557925
30368.9117650.3464740.548445
31369.0294120.3507410.556996
32369.1470590.3623470.577286
33369.2647060.3625780.579519
34369.3823530.3407650.546411
35369.5000000.3374620.542857
36369.6176470.3557290.574083
37369.7352940.3486790.564513
38369.8529410.3381870.549284
39369.9705880.3243600.528514
40370.0882350.3107530.507964
41370.2058820.3110370.510055
42370.3235290.3112630.512055
43370.4411760.3080810.508437
44370.5588240.3082240.510293
45370.6764710.3181480.528399
46370.7941180.3083340.513728
47370.9117650.3179370.531410
48371.0294120.2891490.484824
49371.1470590.2986370.502318
\n", + "
" + ], + "text/plain": [ + " temperature liq_benzene vap_benzene\n", + "0 365.500000 0.480953 0.692110\n", + "1 365.617647 0.462444 0.667699\n", + "2 365.735294 0.477984 0.692441\n", + "3 365.852941 0.440547 0.640336\n", + "4 365.970588 0.427421 0.623328\n", + "5 366.088235 0.442725 0.647796\n", + "6 366.205882 0.434374 0.637691\n", + "7 366.323529 0.444642 0.654933\n", + "8 366.441176 0.427132 0.631229\n", + "9 366.558824 0.446301 0.661743\n", + "10 366.676471 0.438004 0.651591\n", + "11 366.794118 0.425320 0.634814\n", + "12 366.911765 0.439435 0.658047\n", + "13 367.029412 0.435655 0.654539\n", + "14 367.147059 0.401350 0.604987\n", + "15 367.264706 0.397862 0.601703\n", + "16 367.382353 0.415821 0.630930\n", + "17 367.500000 0.420667 0.640380\n", + "18 367.617647 0.391683 0.598214\n", + "19 367.735294 0.404903 0.620432\n", + "20 367.852941 0.409563 0.629626\n", + "21 367.970588 0.389488 0.600722\n", + "22 368.000000 0.396789 0.612483\n", + "23 368.088235 0.398162 0.616106\n", + "24 368.205882 0.362340 0.562505\n", + "25 368.323529 0.386958 0.602680\n", + "26 368.441176 0.363643 0.568210\n", + "27 368.558824 0.368118 0.577072\n", + "28 368.676471 0.384098 0.604078\n", + "29 368.794118 0.353605 0.557925\n", + "30 368.911765 0.346474 0.548445\n", + "31 369.029412 0.350741 0.556996\n", + "32 369.147059 0.362347 0.577286\n", + "33 369.264706 0.362578 0.579519\n", + "34 369.382353 0.340765 0.546411\n", + "35 369.500000 0.337462 0.542857\n", + "36 369.617647 0.355729 0.574083\n", + "37 369.735294 0.348679 0.564513\n", + "38 369.852941 0.338187 0.549284\n", + "39 369.970588 0.324360 0.528514\n", + "40 370.088235 0.310753 0.507964\n", + "41 370.205882 0.311037 0.510055\n", + "42 370.323529 0.311263 0.512055\n", + "43 370.441176 0.308081 0.508437\n", + "44 370.558824 0.308224 0.510293\n", + "45 370.676471 0.318148 0.528399\n", + "46 370.794118 0.308334 0.513728\n", + "47 370.911765 0.317937 0.531410\n", + "48 371.029412 0.289149 0.484824\n", + "49 371.147059 0.298637 0.502318" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "# Load data from csv\n", "data = pd.read_csv(\"BT_NRTL_dataset.csv\")\n", @@ -321,75 +783,140 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "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 mole fraction of benzene in the vapor and liquid phase between the model prediction and data. \n", - "\n", - "
\n", - "Inline Exercise:\n", - "Complete the following cell by adding an expression to compute the sum of square errors. \n", - "
" + "We define the `exp_list` by spliting the data into individual experiments, or data points." ] }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "solution" - ] - }, - "outputs": [], - "source": [ - "# Create method to return an expression that computes the sum of squared error\n", - "def SSE(m, data):\n", - " # Todo: Add expression for computing the sum of squared errors in mole fraction of benzene in the liquid\n", - " # and vapor phase. For example, the squared error for the vapor phase is:\n", - " # (float(data[\"vap_benzene\"]) - m.fs.state_block.mole_frac_phase_comp[\"Vap\", \"benzene\"])**2\n", - " expr = (\n", - " float(data[\"vap_benzene\"])\n", - " - m.fs.state_block.mole_frac_phase_comp[\"Vap\", \"benzene\"]\n", - " ) ** 2 + (\n", - " float(data[\"liq_benzene\"])\n", - " - m.fs.state_block.mole_frac_phase_comp[\"Liq\", \"benzene\"]\n", - " ) ** 2\n", - " return expr * 1e4" - ] - }, - { - "cell_type": "markdown", + "execution_count": 11, "metadata": {}, + "outputs": [], "source": [ - "
\n", - "Note:\n", - "Notice that we have scaled the expression up by a factor of 10000 as the SSE computed here will be an extremely small number given that we are using the difference in mole fraction in our expression. This will help in using a well-scaled objective to improve solve robustness when using IPOPT. \n", - "
\n" + "# Update to new interface\n", + "exp_list = []\n", + "for i in range(data.shape[0]):\n", + " exp_list.append(NRTLExperiment(data.iloc[i]))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "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. " + "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." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3750\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2200\n", + "\n", + "Total number of variables............................: 1102\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 300\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1100\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 6.0671019e-03 3.15e+00 1.97e-05 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 8.6249856e-04 1.40e+03 2.15e-01 -1.0 1.37e+04 - 9.95e-01 1.00e+00h 1\n", + " 2 1.1627234e-03 9.11e+03 8.21e-01 -1.7 4.74e+02 - 8.66e-01 1.00e+00h 1\n", + " 3 1.0978149e-03 9.02e+03 7.99e-01 -1.7 5.89e+00 -4.0 5.44e-01 2.64e-02h 6\n", + " 4 8.5702670e-04 8.63e+02 3.17e-02 -1.7 6.93e-01 -2.7 1.00e+00 1.00e+00h 1\n", + " 5 1.3332724e-03 3.57e+03 7.92e-03 -1.7 7.75e-01 - 1.00e+00 1.00e+00h 1\n", + " 6 1.5692588e-03 1.64e+02 2.34e-04 -1.7 1.98e-01 - 1.00e+00 1.00e+00h 1\n", + " 7 1.5828905e-03 1.20e+01 1.13e-05 -1.7 4.29e-02 - 1.00e+00 1.00e+00h 1\n", + " 8 1.4366151e-03 9.18e-01 2.34e-04 -2.5 5.49e-02 - 1.00e+00 1.00e+00h 1\n", + " 9 8.9194043e-04 2.19e+01 2.00e-04 -3.8 2.51e-01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 5.9835646e-04 3.72e+01 2.34e-05 -3.8 3.13e-01 - 1.00e+00 1.00e+00h 1\n", + " 11 5.9839648e-04 1.26e+00 4.06e-08 -3.8 2.87e-02 - 1.00e+00 1.00e+00h 1\n", + " 12 5.9838953e-04 4.33e-05 1.60e-12 -3.8 9.40e-05 - 1.00e+00 1.00e+00h 1\n", + " 13 5.9077073e-04 1.21e+01 2.96e-06 -5.7 4.79e-02 - 1.00e+00 1.00e+00h 1\n", + " 14 5.9066394e-04 1.19e-03 4.25e-07 -5.7 5.98e-04 -3.1 1.00e+00 1.00e+00h 1\n", + " 15 5.9059984e-04 1.08e-02 2.96e-07 -8.6 1.25e-03 -3.6 1.00e+00 1.00e+00h 1\n", + " 16 5.9042438e-04 9.67e-02 2.92e-07 -8.6 3.70e-03 -4.1 1.00e+00 1.00e+00h 1\n", + " 17 5.8992758e-04 8.72e-01 2.91e-07 -8.6 1.11e-02 -4.6 1.00e+00 1.00e+00h 1\n", + " 18 5.8840706e-04 8.23e+00 3.09e-07 -8.6 3.40e-02 -5.1 1.00e+00 1.00e+00h 1\n", + " 19 5.8319289e-04 9.25e+01 1.97e-06 -8.6 1.15e-01 -5.5 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 5.4836946e-04 3.88e+03 1.22e-04 -8.6 7.95e-01 -6.0 1.00e+00 1.00e+00h 1\n", + " 21 5.0847689e-04 4.45e+02 1.04e-04 -8.6 3.55e-01 -5.6 1.00e+00 1.00e+00h 1\n", + " 22 5.0727291e-04 4.20e+00 1.54e-05 -8.6 6.20e+02 - 1.00e+00 1.00e+00h 1\n", + " 23 5.0749772e-04 1.36e+00 1.44e-06 -8.6 5.13e+01 - 1.00e+00 1.00e+00h 1\n", + " 24 5.0749686e-04 6.93e-06 4.21e-11 -8.6 3.55e-01 - 1.00e+00 1.00e+00h 1\n", + " 25 5.0749686e-04 3.36e-06 1.49e-12 -9.0 6.25e-02 - 1.00e+00 1.00e+00h 1\n", + " 26 5.0749686e-04 1.02e-10 2.36e-18 -9.0 5.08e-06 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 26\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 5.0749685787934424e-04 5.0749685787934424e-04\n", + "Dual infeasibility......: 2.3583858113882067e-18 2.3583858113882067e-18\n", + "Constraint violation....: 3.5405706676501683e-13 1.0186340659856796e-10\n", + "Complementarity.........: 9.0909090909091344e-10 9.0909090909091344e-10\n", + "Overall NLP error.......: 9.0909090909091344e-10 9.0909090909091344e-10\n", + "\n", + "\n", + "Number of objective function evaluations = 33\n", + "Number of objective gradient evaluations = 27\n", + "Number of equality constraint evaluations = 34\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 27\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 26\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.035\n", + "Total CPU secs in NLP function evaluations = 0.009\n", + "\n", + "EXIT: Optimal Solution Found.\n" + ] + } + ], "source": [ "import logging\n", "\n", "idaeslog.getIdaesLogger(\"core.property_meta\").setLevel(logging.ERROR)\n", - "# Initialize a parameter estimation object\n", - "pest = parmest.Estimator(NRTL_model, data, variable_name, SSE, tee=True)\n", "\n", - "# Run parameter estimation using all data\n", + "pest = parmest.Estimator(exp_list, obj_function=\"SSE\", tee=True)\n", "obj_value, parameters = pest.theta_est()" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "metadata": { "tags": [ "testing" @@ -398,7 +925,7 @@ "outputs": [], "source": [ "# Check for values of the parameter estimation problem\n", - "assert obj_value == pytest.approx(5.07496, 1e-3)\n", + "assert obj_value == pytest.approx(5.07496e-4, 1e-3)\n", "assert parameters[\"fs.properties.tau[benzene,toluene]\"] == pytest.approx(-0.89876, 1e-3)\n", "assert parameters[\"fs.properties.tau[toluene,benzene]\"] == pytest.approx(1.41048, 1e-3)" ] @@ -412,11 +939,23 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The SSE at the optimal solution is 0.000507\n", + "\n", + "The values for the parameters are as follows:\n", + "fs.properties.tau[benzene,toluene] = -0.8987550041842163\n", + "fs.properties.tau[toluene,benzene] = 1.4104702103547941\n" + ] + } + ], "source": [ - "print(\"The SSE at the optimal solution is %0.6f\" % (obj_value * 1e-4))\n", + "print(\"The SSE at the optimal solution is %0.6f\" % (obj_value))\n", "print()\n", "print(\"The values for the parameters are as follows:\")\n", "for k, v in parameters.items():\n", @@ -449,15 +988,12 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "metadata": {}, "outputs": [], "source": [ - "# Run parameter estimation using bootstrap resample of the data (10 samples),\n", - "# plot results along with confidence regions\n", - "\n", - "# Uncomment the following code:\n", - "# bootstrap_theta = pest.theta_est_bootstrap(4)\n", + "# Uncomment the following lines\n", + "# bootstrap_theta = pest.theta_est_bootstrap(4, seed=542)\n", "# display(bootstrap_theta)" ] } @@ -465,7 +1001,7 @@ "metadata": { "celltoolbar": "Tags", "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "idaes-examples-dev-py313-macmini", "language": "python", "name": "python3" }, @@ -479,7 +1015,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.9" + "version": "3.13.13" } }, "nbformat": 4, diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_usr.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_usr.ipynb index 5bdce840..97ab497e 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_usr.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_usr.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 10, + "execution_count": 1, "metadata": { "tags": [ "header", @@ -16,7 +16,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", @@ -32,8 +32,8 @@ "# Parameter Estimation Using the NRTL State Block\n", "\n", "Author: Jaffer Ghouse \n", - "Maintainer: Andrew Lee \n", - "Updated: 2023-06-01 \n", + "Maintainer: Stephen Cini \n", + "Updated: 2026-06-11 \n", "\n", "In this module, we use Pyomo's `parmest` tool in conjunction with IDAES models for parameter estimation. We demonstrate these tools by estimating the parameters associated with the NRTL property model for a benzene-toluene mixture. The NRTL model has 2 sets of parameters: the non-randomness parameter (`alpha_ij`) and the binary interaction parameter (`tau_ij`), where `i` and `j` are the pure component species. In this example, we only estimate the binary interaction parameter (`tau_ij`) for a given dataset. 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 only the state block. \n", "\n", @@ -45,8 +45,7 @@ "\n", "## Key links to documentation:\n", "* NRTL Model - https://idaes-pse.readthedocs.io/en/stable/reference_guides/model_libraries/generic/property_models/activity_coefficient.html\n", - "* parmest - https://pyomo.readthedocs.io/en/stable/contributed_packages/parmest/index.html\n", - "" + "* parmest - https://pyomo.readthedocs.io/en/stable/explanation/analysis/parmest/index.html\n" ] }, { @@ -55,13 +54,13 @@ "source": [ "
\n", "Inline Exercise:\n", - "import `ConcreteModel` from Pyomo and `FlowsheetBlock` from IDAES. \n", + "import `ConcreteModel`, `value`, and `Suffix` from Pyomo, `FlowsheetBlock` and `Flash` from IDAES. \n", "
" ] }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 2, "metadata": { "tags": [ "exercise" @@ -69,14 +68,14 @@ }, "outputs": [], "source": [ - "# Todo: import ConcreteModel from pyomo.environ\n", + "# Todo: import ConcreteModel, value, and Suffix from pyomo.environ\n", "\n", "# Todo: import FlowsheetBlock from idaes.core" ] }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 3, "metadata": { "tags": [ "solution" @@ -84,11 +83,14 @@ }, "outputs": [], "source": [ - "# Todo: import ConcreteModel from pyomo.environ\n", - "from pyomo.environ import ConcreteModel, value\n", + "# Todo: import ConcreteModel, value, and Suffix from pyomo.environ\n", + "from pyomo.environ import ConcreteModel, value, Suffix\n", "\n", "# Todo: import FlowsheetBlock from idaes.core\n", - "from idaes.core import FlowsheetBlock" + "from idaes.core import FlowsheetBlock\n", + "\n", + "# Todo: import Flash unit model from idaes.models.unit_models\n", + "from idaes.models.unit_models import Flash" ] }, { @@ -100,7 +102,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 4, "metadata": { "tags": [] }, @@ -121,7 +123,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 5, "metadata": { "tags": [] }, @@ -152,7 +154,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 6, "metadata": { "tags": [ "exercise" @@ -198,7 +200,12 @@ " m.fs.state_block.initialize(outlvl=idaeslog.INFO)\n", "\n", " # Fix at actual temperature\n", - " m.fs.state_block.temperature.fix(float(data[\"temperature\"]))\n", + " if isinstance(data, dict) or isinstance(data, pd.Series):\n", + " m.fs.state_block.temperature.fix(float(data[\"temperature\"]))\n", + " elif isinstance(data, pd.DataFrame):\n", + " m.fs.state_block.temperature.fix(float(data.iloc[0][\"temperature\"]))\n", + " else:\n", + " raise ValueError(\"Unrecognized data type.\")\n", "\n", " # Set bounds on variables to be estimated\n", " m.fs.properties.tau[\"benzene\", \"toluene\"].setlb(-5)\n", @@ -213,7 +220,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 7, "metadata": { "tags": [ "solution" @@ -264,7 +271,12 @@ " m.fs.state_block.initialize(outlvl=idaeslog.INFO_LOW)\n", "\n", " # Fix at actual temperature\n", - " m.fs.state_block.temperature.fix(float(data[\"temperature\"]))\n", + " if isinstance(data, dict) or isinstance(data, pd.Series):\n", + " m.fs.state_block.temperature.fix(float(data[\"temperature\"]))\n", + " elif isinstance(data, pd.DataFrame):\n", + " m.fs.state_block.temperature.fix(float(data.iloc[0][\"temperature\"]))\n", + " else:\n", + " raise ValueError(\"Unrecognized data type.\")\n", "\n", " # Set bounds on variables to be estimated\n", " m.fs.properties.tau[\"benzene\", \"toluene\"].setlb(-5)\n", @@ -290,54 +302,107 @@ "source": [ "In addition to providing a method to return an initialized model, the `parmest` tool needs the following:\n", "\n", - "* List of variable names to be estimated\n", - "* Dataset\n", - "* Expression to compute the sum of squared errors\n" + "* Experiment class to set up and label model with suffixes\n", + "* Dataset with multiple scenarios - organized into an experiment list\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ + "Here we build an experiment class to label our model problem for parameter estimation. The labels are defined as a `Suffix`, and the main labels for our model are `experiment_outputs`, `unknown_parameters`. and `measurement_error`.\n", + "\n", + "For this problem, the error will be computed for the mole fraction of benzene in the vapor and liquid phase between the model prediction and data. The `experimental_outputs` will therefore be the mole fraction of benzene in the two phases.\n", + "\n", "In this example, we only estimate the binary interaction parameter (`tau_ij`). Given that this variable is usually indexed as `tau_ij = Var(component_list, component_list)`, there are 2*2=4 degrees of freedom. However, when i=j, the binary interaction parameter is 0. Therefore, in this problem, we estimate the binary interaction parameter for the following variables only:\n", "\n", "* fs.properties.tau['benzene', 'toluene']\n", "* fs.properties.tau['toluene', 'benzene']\n", "\n", - "
\n", - "Inline Exercise:\n", - "Create a list called `variable_name` with the above-mentioned variables declared as strings.\n", - "
" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": { - "tags": [ - "exercise" - ] - }, - "outputs": [], - "source": [ - "# Todo: Create a list of vars to estimate" + "As shown below, these model components are used as our `unknown_parameters`.\n", + "\n", + "We define `measurement_error` as none so parmest calculates the value internally based on the experimental outputs. Refer to https://pyomo.readthedocs.io/en/stable/explanation/analysis/parmest/driver.html for more information. " ] }, { "cell_type": "code", - "execution_count": 19, - "metadata": { - "tags": [ - "solution" - ] - }, + "execution_count": 9, + "metadata": {}, "outputs": [], "source": [ - "# Todo: Create a list of vars to estimate\n", - "variable_name = [\n", - " \"fs.properties.tau['benzene', 'toluene']\",\n", - " \"fs.properties.tau['toluene', 'benzene']\",\n", - "]" + "# Build an experiment class to take advantage of new parmest interface\n", + "from pyomo.contrib.parmest.experiment import Experiment\n", + "\n", + "\n", + "class NRTLExperiment(Experiment):\n", + " \"\"\"Experiment class for parameter estimation of NRTL model using parmest\"\"\"\n", + "\n", + " def __init__(self, data, meas_error=None):\n", + " \"\"\"Initialize the NRTLExperiment class\n", + "\n", + " Args:\n", + " data: DataFrame containing the experimental data\n", + " meas_error: Measurement error for the data (optional)\n", + " \"\"\"\n", + " self.model = None\n", + " self.data = data\n", + " self.meas_error = meas_error\n", + "\n", + " def create_model(self):\n", + " \"\"\"Create the Pyomo model for the NRTL parameter estimation problem\"\"\"\n", + " self.model = NRTL_model(self.data)\n", + "\n", + " def label_model(self):\n", + " import pyomo.environ as pyo\n", + " import pandas as pd\n", + "\n", + " m = self.model\n", + "\n", + " # Parmest expects the first index of experiment outputs to be the data point\n", + " # This is a workaround that will be addressed and corrected in a future release.\n", + "\n", + " m.data_point = pyo.Set(initialize=[0])\n", + "\n", + " # Wrap IDAES variables in Expressions indexed by data point\n", + " m.liq_benzene_out = pyo.Expression(\n", + " m.data_point,\n", + " rule=lambda m, i: m.fs.state_block.mole_frac_phase_comp[\"Liq\", \"benzene\"],\n", + " )\n", + "\n", + " m.vap_benzene_out = pyo.Expression(\n", + " m.data_point,\n", + " rule=lambda m, i: m.fs.state_block.mole_frac_phase_comp[\"Vap\", \"benzene\"],\n", + " )\n", + "\n", + " m.experiment_outputs = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + "\n", + " m.experiment_outputs[m.liq_benzene_out[0]] = float(self.data[\"liq_benzene\"])\n", + " m.experiment_outputs[m.vap_benzene_out[0]] = float(self.data[\"vap_benzene\"])\n", + "\n", + " m.measurement_error = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + " m.measurement_error.update(\n", + " [\n", + " (m.liq_benzene_out[0], self.meas_error),\n", + " (m.vap_benzene_out[0], self.meas_error),\n", + " ]\n", + " )\n", + "\n", + " # Add unknown parameters to the model for easier access\n", + " m.unknown_parameters = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + " m.unknown_parameters.update(\n", + " (k, value(k))\n", + " for k in [\n", + " m.fs.properties.tau[\"benzene\", \"toluene\"],\n", + " m.fs.properties.tau[\"toluene\", \"benzene\"],\n", + " ]\n", + " )\n", + "\n", + " def get_labeled_model(self):\n", + " \"\"\"Return the labeled model\"\"\"\n", + " if self.model is None:\n", + " self.create_model()\n", + " self.label_model()\n", + " return self.model" ] }, { @@ -356,11 +421,400 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 10, "metadata": { "tags": [] }, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
temperatureliq_benzenevap_benzene
0365.5000000.4809530.692110
1365.6176470.4624440.667699
2365.7352940.4779840.692441
3365.8529410.4405470.640336
4365.9705880.4274210.623328
5366.0882350.4427250.647796
6366.2058820.4343740.637691
7366.3235290.4446420.654933
8366.4411760.4271320.631229
9366.5588240.4463010.661743
10366.6764710.4380040.651591
11366.7941180.4253200.634814
12366.9117650.4394350.658047
13367.0294120.4356550.654539
14367.1470590.4013500.604987
15367.2647060.3978620.601703
16367.3823530.4158210.630930
17367.5000000.4206670.640380
18367.6176470.3916830.598214
19367.7352940.4049030.620432
20367.8529410.4095630.629626
21367.9705880.3894880.600722
22368.0000000.3967890.612483
23368.0882350.3981620.616106
24368.2058820.3623400.562505
25368.3235290.3869580.602680
26368.4411760.3636430.568210
27368.5588240.3681180.577072
28368.6764710.3840980.604078
29368.7941180.3536050.557925
30368.9117650.3464740.548445
31369.0294120.3507410.556996
32369.1470590.3623470.577286
33369.2647060.3625780.579519
34369.3823530.3407650.546411
35369.5000000.3374620.542857
36369.6176470.3557290.574083
37369.7352940.3486790.564513
38369.8529410.3381870.549284
39369.9705880.3243600.528514
40370.0882350.3107530.507964
41370.2058820.3110370.510055
42370.3235290.3112630.512055
43370.4411760.3080810.508437
44370.5588240.3082240.510293
45370.6764710.3181480.528399
46370.7941180.3083340.513728
47370.9117650.3179370.531410
48371.0294120.2891490.484824
49371.1470590.2986370.502318
\n", + "
" + ], + "text/plain": [ + " temperature liq_benzene vap_benzene\n", + "0 365.500000 0.480953 0.692110\n", + "1 365.617647 0.462444 0.667699\n", + "2 365.735294 0.477984 0.692441\n", + "3 365.852941 0.440547 0.640336\n", + "4 365.970588 0.427421 0.623328\n", + "5 366.088235 0.442725 0.647796\n", + "6 366.205882 0.434374 0.637691\n", + "7 366.323529 0.444642 0.654933\n", + "8 366.441176 0.427132 0.631229\n", + "9 366.558824 0.446301 0.661743\n", + "10 366.676471 0.438004 0.651591\n", + "11 366.794118 0.425320 0.634814\n", + "12 366.911765 0.439435 0.658047\n", + "13 367.029412 0.435655 0.654539\n", + "14 367.147059 0.401350 0.604987\n", + "15 367.264706 0.397862 0.601703\n", + "16 367.382353 0.415821 0.630930\n", + "17 367.500000 0.420667 0.640380\n", + "18 367.617647 0.391683 0.598214\n", + "19 367.735294 0.404903 0.620432\n", + "20 367.852941 0.409563 0.629626\n", + "21 367.970588 0.389488 0.600722\n", + "22 368.000000 0.396789 0.612483\n", + "23 368.088235 0.398162 0.616106\n", + "24 368.205882 0.362340 0.562505\n", + "25 368.323529 0.386958 0.602680\n", + "26 368.441176 0.363643 0.568210\n", + "27 368.558824 0.368118 0.577072\n", + "28 368.676471 0.384098 0.604078\n", + "29 368.794118 0.353605 0.557925\n", + "30 368.911765 0.346474 0.548445\n", + "31 369.029412 0.350741 0.556996\n", + "32 369.147059 0.362347 0.577286\n", + "33 369.264706 0.362578 0.579519\n", + "34 369.382353 0.340765 0.546411\n", + "35 369.500000 0.337462 0.542857\n", + "36 369.617647 0.355729 0.574083\n", + "37 369.735294 0.348679 0.564513\n", + "38 369.852941 0.338187 0.549284\n", + "39 369.970588 0.324360 0.528514\n", + "40 370.088235 0.310753 0.507964\n", + "41 370.205882 0.311037 0.510055\n", + "42 370.323529 0.311263 0.512055\n", + "43 370.441176 0.308081 0.508437\n", + "44 370.558824 0.308224 0.510293\n", + "45 370.676471 0.318148 0.528399\n", + "46 370.794118 0.308334 0.513728\n", + "47 370.911765 0.317937 0.531410\n", + "48 371.029412 0.289149 0.484824\n", + "49 371.147059 0.298637 0.502318" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "# Load data from csv\n", "data = pd.read_csv(\"BT_NRTL_dataset.csv\")\n", @@ -373,88 +827,134 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "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 mole fraction of benzene in the vapor and liquid phase between the model prediction and data. \n", - "\n", - "
\n", - "Inline Exercise:\n", - "Complete the following cell by adding an expression to compute the sum of square errors. \n", - "
" + "We define the `exp_list` by spliting the data into individual experiments, or data points." ] }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "exercise" - ] - }, - "outputs": [], - "source": [ - "# Create method to return an expression that computes the sum of squared error\n", - "def SSE(m, data):\n", - " # Todo: Add expression for computing the sum of squared errors in mole fraction of benzene in the liquid\n", - " # and vapor phase. For example, the squared error for the vapor phase is:\n", - " # (float(data[\"vap_benzene\"]) - m.fs.state_block.mole_frac_phase_comp[\"Vap\", \"benzene\"])**2\n", - "\n", - " return expr * 1e4" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "solution" - ] - }, - "outputs": [], - "source": [ - "# Create method to return an expression that computes the sum of squared error\n", - "def SSE(m, data):\n", - " # Todo: Add expression for computing the sum of squared errors in mole fraction of benzene in the liquid\n", - " # and vapor phase. For example, the squared error for the vapor phase is:\n", - " # (float(data[\"vap_benzene\"]) - m.fs.state_block.mole_frac_phase_comp[\"Vap\", \"benzene\"])**2\n", - " expr = (\n", - " float(data[\"vap_benzene\"])\n", - " - m.fs.state_block.mole_frac_phase_comp[\"Vap\", \"benzene\"]\n", - " ) ** 2 + (\n", - " float(data[\"liq_benzene\"])\n", - " - m.fs.state_block.mole_frac_phase_comp[\"Liq\", \"benzene\"]\n", - " ) ** 2\n", - " return expr * 1e4" - ] - }, - { - "cell_type": "markdown", + "execution_count": 11, "metadata": {}, + "outputs": [], "source": [ - "
\n", - "Note:\n", - "Notice that we have scaled the expression up by a factor of 10000 as the SSE computed here will be an extremely small number given that we are using the difference in mole fraction in our expression. This will help in using a well-scaled objective to improve solve robustness when using IPOPT. \n", - "
\n" + "# Update to new interface\n", + "exp_list = []\n", + "for i in range(data.shape[0]):\n", + " exp_list.append(NRTLExperiment(data.iloc[i]))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "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. " + "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." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3750\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2200\n", + "\n", + "Total number of variables............................: 1102\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 300\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1100\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 6.0671019e-03 3.15e+00 1.97e-05 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 8.6249856e-04 1.40e+03 2.15e-01 -1.0 1.37e+04 - 9.95e-01 1.00e+00h 1\n", + " 2 1.1627234e-03 9.11e+03 8.21e-01 -1.7 4.74e+02 - 8.66e-01 1.00e+00h 1\n", + " 3 1.0978149e-03 9.02e+03 7.99e-01 -1.7 5.89e+00 -4.0 5.44e-01 2.64e-02h 6\n", + " 4 8.5702670e-04 8.63e+02 3.17e-02 -1.7 6.93e-01 -2.7 1.00e+00 1.00e+00h 1\n", + " 5 1.3332724e-03 3.57e+03 7.92e-03 -1.7 7.75e-01 - 1.00e+00 1.00e+00h 1\n", + " 6 1.5692588e-03 1.64e+02 2.34e-04 -1.7 1.98e-01 - 1.00e+00 1.00e+00h 1\n", + " 7 1.5828905e-03 1.20e+01 1.13e-05 -1.7 4.29e-02 - 1.00e+00 1.00e+00h 1\n", + " 8 1.4366151e-03 9.18e-01 2.34e-04 -2.5 5.49e-02 - 1.00e+00 1.00e+00h 1\n", + " 9 8.9194043e-04 2.19e+01 2.00e-04 -3.8 2.51e-01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 5.9835646e-04 3.72e+01 2.34e-05 -3.8 3.13e-01 - 1.00e+00 1.00e+00h 1\n", + " 11 5.9839648e-04 1.26e+00 4.06e-08 -3.8 2.87e-02 - 1.00e+00 1.00e+00h 1\n", + " 12 5.9838953e-04 4.33e-05 1.60e-12 -3.8 9.40e-05 - 1.00e+00 1.00e+00h 1\n", + " 13 5.9077073e-04 1.21e+01 2.96e-06 -5.7 4.79e-02 - 1.00e+00 1.00e+00h 1\n", + " 14 5.9066394e-04 1.19e-03 4.25e-07 -5.7 5.98e-04 -3.1 1.00e+00 1.00e+00h 1\n", + " 15 5.9059984e-04 1.08e-02 2.96e-07 -8.6 1.25e-03 -3.6 1.00e+00 1.00e+00h 1\n", + " 16 5.9042438e-04 9.67e-02 2.92e-07 -8.6 3.70e-03 -4.1 1.00e+00 1.00e+00h 1\n", + " 17 5.8992758e-04 8.72e-01 2.91e-07 -8.6 1.11e-02 -4.6 1.00e+00 1.00e+00h 1\n", + " 18 5.8840706e-04 8.23e+00 3.09e-07 -8.6 3.40e-02 -5.1 1.00e+00 1.00e+00h 1\n", + " 19 5.8319289e-04 9.25e+01 1.97e-06 -8.6 1.15e-01 -5.5 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 5.4836946e-04 3.88e+03 1.22e-04 -8.6 7.95e-01 -6.0 1.00e+00 1.00e+00h 1\n", + " 21 5.0847689e-04 4.45e+02 1.04e-04 -8.6 3.55e-01 -5.6 1.00e+00 1.00e+00h 1\n", + " 22 5.0727291e-04 4.20e+00 1.54e-05 -8.6 6.20e+02 - 1.00e+00 1.00e+00h 1\n", + " 23 5.0749772e-04 1.36e+00 1.44e-06 -8.6 5.13e+01 - 1.00e+00 1.00e+00h 1\n", + " 24 5.0749686e-04 6.93e-06 4.21e-11 -8.6 3.55e-01 - 1.00e+00 1.00e+00h 1\n", + " 25 5.0749686e-04 3.36e-06 1.49e-12 -9.0 6.25e-02 - 1.00e+00 1.00e+00h 1\n", + " 26 5.0749686e-04 1.02e-10 2.36e-18 -9.0 5.08e-06 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 26\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 5.0749685787934424e-04 5.0749685787934424e-04\n", + "Dual infeasibility......: 2.3583858113882067e-18 2.3583858113882067e-18\n", + "Constraint violation....: 3.5405706676501683e-13 1.0186340659856796e-10\n", + "Complementarity.........: 9.0909090909091344e-10 9.0909090909091344e-10\n", + "Overall NLP error.......: 9.0909090909091344e-10 9.0909090909091344e-10\n", + "\n", + "\n", + "Number of objective function evaluations = 33\n", + "Number of objective gradient evaluations = 27\n", + "Number of equality constraint evaluations = 34\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 27\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 26\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.035\n", + "Total CPU secs in NLP function evaluations = 0.009\n", + "\n", + "EXIT: Optimal Solution Found.\n" + ] + } + ], "source": [ "import logging\n", "\n", "idaeslog.getIdaesLogger(\"core.property_meta\").setLevel(logging.ERROR)\n", - "# Initialize a parameter estimation object\n", - "pest = parmest.Estimator(NRTL_model, data, variable_name, SSE, tee=True)\n", "\n", - "# Run parameter estimation using all data\n", + "pest = parmest.Estimator(exp_list, obj_function=\"SSE\", tee=True)\n", "obj_value, parameters = pest.theta_est()" ] }, @@ -467,11 +967,23 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The SSE at the optimal solution is 0.000507\n", + "\n", + "The values for the parameters are as follows:\n", + "fs.properties.tau[benzene,toluene] = -0.8987550041842163\n", + "fs.properties.tau[toluene,benzene] = 1.4104702103547941\n" + ] + } + ], "source": [ - "print(\"The SSE at the optimal solution is %0.6f\" % (obj_value * 1e-4))\n", + "print(\"The SSE at the optimal solution is %0.6f\" % (obj_value))\n", "print()\n", "print(\"The values for the parameters are as follows:\")\n", "for k, v in parameters.items():\n", @@ -504,15 +1016,12 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "metadata": {}, "outputs": [], "source": [ - "# Run parameter estimation using bootstrap resample of the data (10 samples),\n", - "# plot results along with confidence regions\n", - "\n", - "# Uncomment the following code:\n", - "# bootstrap_theta = pest.theta_est_bootstrap(4)\n", + "# Uncomment the following lines\n", + "# bootstrap_theta = pest.theta_est_bootstrap(4, seed=542)\n", "# display(bootstrap_theta)" ] } @@ -520,7 +1029,7 @@ "metadata": { "celltoolbar": "Tags", "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "idaes-examples-dev-py313-macmini", "language": "python", "name": "python3" }, @@ -534,7 +1043,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.9" + "version": "3.13.13" } }, "nbformat": 4, diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_doc.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_doc.ipynb index edb05ee6..56377f29 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_doc.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_doc.ipynb @@ -1,923 +1,1025 @@ { - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "tags": [ - "header", - "hide-cell" - ] - }, - "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", - "metadata": {}, - "source": [ - "# Parameter Estimation Using Flash Unit Model\n", - "\n", - "Author: Jaffer Ghouse \n", - "Maintainer: Andrew Lee \n", - "Updated: 2023-06-01 \n", - "\n", - "In this module, we will be using Pyomo's `parmest` tool in conjunction with IDAES models for parameter estimation. We demonstrate these tools by estimating the parameters associated with the NRTL property model for a benzene-toluene mixture. The NRTL model has 2 sets of parameters: the non-randomness parameter (`alpha_ij`) and the binary interaction parameter (`tau_ij`), where `i` and `j` is the pure component species. In this example, we will be only estimate the binary interaction parameter (`tau_ij`) for a given dataset. 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 the NRTL property package. \n", - "\n", - "We will complete the following tasks:\n", - "* Set up a method to return an initialized model\n", - "* Set up the parameter estimation problem using `parmest`\n", - "* Analyze the results\n", - "* Demonstrate advanced features from `parmest`\n", - "\n", - "## Key links to documentation:\n", - "* NRTL Model - https://idaes-pse.readthedocs.io/en/stable/reference_guides/model_libraries/generic/property_models/activity_coefficient.html\n", - "* parmest - https://pyomo.readthedocs.io/en/stable/contributed_packages/parmest/index.html\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
\n", - "Inline Exercise:\n", - "import `ConcreteModel` from Pyomo, `FlowsheetBlock` and `Flash` from IDAES. \n", - "
" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "tags": [ - "solution" - ] - }, - "outputs": [], - "source": [ - "# Todo: import ConcreteModel from pyomo.environ\n", - "from pyomo.environ import ConcreteModel, value\n", - "\n", - "# Todo: import FlowsheetBlock from idaes.core\n", - "from idaes.core import FlowsheetBlock\n", - "\n", - "# Todo: import Flash unit model from idaes.models.unit_models\n", - "from idaes.models.unit_models import Flash" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In the next cell, we will be importing the parameter block that we will be using in this module and the idaes logger. " - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "from idaes.models.properties.activity_coeff_models.BTX_activity_coeff_VLE import (\n", - " BTXParameterBlock,\n", - ")\n", - "import idaes.logger as idaeslog" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In the next cell, we import `parmest` from Pyomo and the `pandas` package. We need `pandas` as `parmest` uses `pandas.dataframe` for handling the input data and the results." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [], - "source": [ - "import pyomo.contrib.parmest.parmest as parmest\n", - "import pandas as pd" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Setting up an initialized model\n", - "\n", - "We need to provide a method that returns an initialized model to the `parmest` tool in Pyomo." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
\n", - "Inline Exercise:\n", - "Using what you have learned from previous modules, fill in the missing code below to return an initialized IDAES model. \n", - "
" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": { - "tags": [ - "solution" - ] - }, - "outputs": [], - "source": [ - "def NRTL_model(data):\n", - "\n", - " # Todo: Create a ConcreteModel object\n", - " m = ConcreteModel()\n", - "\n", - " # Todo: Create FlowsheetBlock object\n", - " m.fs = FlowsheetBlock(dynamic=False)\n", - "\n", - " # Todo: Create a properties parameter object with the following options:\n", - " # \"valid_phase\": ('Liq', 'Vap')\n", - " # \"activity_coeff_model\": 'NRTL'\n", - " m.fs.properties = BTXParameterBlock(\n", - " valid_phase=(\"Liq\", \"Vap\"), activity_coeff_model=\"NRTL\"\n", - " )\n", - " m.fs.flash = Flash(property_package=m.fs.properties)\n", - "\n", - " # Initialize at a certain inlet condition\n", - " m.fs.flash.inlet.flow_mol.fix(1)\n", - " m.fs.flash.inlet.temperature.fix(368)\n", - " m.fs.flash.inlet.pressure.fix(101325)\n", - " m.fs.flash.inlet.mole_frac_comp[0, \"benzene\"].fix(0.5)\n", - " m.fs.flash.inlet.mole_frac_comp[0, \"toluene\"].fix(0.5)\n", - "\n", - " # Set Flash unit specifications\n", - " m.fs.flash.heat_duty.fix(0)\n", - " m.fs.flash.deltaP.fix(0)\n", - "\n", - " # Fix NRTL specific variables\n", - " # alpha values (set at 0.3)\n", - " m.fs.properties.alpha[\"benzene\", \"benzene\"].fix(0)\n", - " m.fs.properties.alpha[\"benzene\", \"toluene\"].fix(0.3)\n", - " m.fs.properties.alpha[\"toluene\", \"toluene\"].fix(0)\n", - " m.fs.properties.alpha[\"toluene\", \"benzene\"].fix(0.3)\n", - "\n", - " # initial tau values\n", - " m.fs.properties.tau[\"benzene\", \"benzene\"].fix(0)\n", - " m.fs.properties.tau[\"benzene\", \"toluene\"].fix(-0.9)\n", - " m.fs.properties.tau[\"toluene\", \"toluene\"].fix(0)\n", - " m.fs.properties.tau[\"toluene\", \"benzene\"].fix(1.4)\n", - "\n", - " # Initialize the flash unit\n", - " m.fs.flash.initialize(outlvl=idaeslog.INFO_LOW)\n", - "\n", - " # Fix at actual temperature\n", - " m.fs.flash.inlet.temperature.fix(float(data[\"temperature\"]))\n", - "\n", - " # Set bounds on variables to be estimated\n", - " m.fs.properties.tau[\"benzene\", \"toluene\"].setlb(-5)\n", - " m.fs.properties.tau[\"benzene\", \"toluene\"].setub(5)\n", - "\n", - " m.fs.properties.tau[\"toluene\", \"benzene\"].setlb(-5)\n", - " m.fs.properties.tau[\"toluene\", \"benzene\"].setub(5)\n", - "\n", - " # Return initialized flash model\n", - " return m" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Parameter estimation using parmest" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In addition to providing a method to return an initialized model, the `parmest` tool needs the following:\n", - "\n", - "* List of variable names to be estimated\n", - "* Dataset with multiple scenarios\n", - "* Expression to compute the sum of squared errors\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In this example, we only estimate the binary interaction parameter (`tau_ij`). Given that this variable is usually indexed as `tau_ij = Var(component_list, component_list)`, there are 2*2=4 degrees of freedom. However, when i=j, the binary interaction parameter is 0. Therefore, in this problem, we estimate the binary interaction parameter for the following variables only:\n", - "\n", - "* fs.properties.tau['benzene', 'toluene']\n", - "* fs.properties.tau['toluene', 'benzene']\n", - "\n", - "
\n", - "Inline Exercise:\n", - "Create a list called `variable_name` with the above-mentioned variables declared as strings.\n", - "
" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": { - "tags": [ - "solution" - ] - }, - "outputs": [], - "source": [ - "# Todo: Create a list of vars to estimate\n", - "variable_name = [\n", - " \"fs.properties.tau['benzene', 'toluene']\",\n", - " \"fs.properties.tau['toluene', 'benzene']\",\n", - "]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Pyomo's `parmest` tool supports the following data formats:\n", - "- pandas dataframe\n", - "- list of dictionaries\n", - "- list of json file names.\n", - "\n", - "Please see the documentation for more details. \n", - "\n", - "For this example, we load data from the csv file `BT_NRTL_dataset.csv`. The dataset consists of fifty data points which provide the mole fraction of benzene in the vapor and liquid phase as a function of temperature. " - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "tags": [ + "header", + "hide-cell" + ] + }, + "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": [ + "# Parameter Estimation Using Flash Unit Model\n", + "\n", + "Author: Jaffer Ghouse \n", + "Maintainer: Stephen Cini \n", + "Updated: 2026-06-11 \n", + "\n", + "In this module, we will be using Pyomo's `parmest` tool in conjunction with IDAES models for parameter estimation. We demonstrate these tools by estimating the parameters associated with the NRTL property model for a benzene-toluene mixture. The NRTL model has 2 sets of parameters: the non-randomness parameter (`alpha_ij`) and the binary interaction parameter (`tau_ij`), where `i` and `j` is the pure component species. In this example, we will be only estimate the binary interaction parameter (`tau_ij`) for a given dataset. 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 the NRTL property package. \n", + "\n", + "We will complete the following tasks:\n", + "* Set up a method to return an initialized model\n", + "* Set up the parameter estimation problem using `parmest`\n", + "* Analyze the results\n", + "* Demonstrate advanced features from `parmest`\n", + "\n", + "## Key links to documentation:\n", + "* NRTL Model - https://idaes-pse.readthedocs.io/en/stable/reference_guides/model_libraries/generic/property_models/activity_coefficient.html\n", + "* parmest - https://pyomo.readthedocs.io/en/stable/explanation/analysis/parmest/index.html" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "Inline Exercise:\n", + "import `ConcreteModel`, `value`, and `Suffix` from Pyomo, `FlowsheetBlock` and `Flash` from IDAES. \n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "tags": [ + "solution" + ] + }, + "outputs": [], + "source": [ + "# Todo: import ConcreteModel, value, and Suffix from pyomo.environ\n", + "from pyomo.environ import ConcreteModel, value, Suffix\n", + "\n", + "# Todo: import FlowsheetBlock from idaes.core\n", + "from idaes.core import FlowsheetBlock\n", + "\n", + "# Todo: import Flash unit model from idaes.models.unit_models\n", + "from idaes.models.unit_models import Flash" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In the next cell, we will be importing the parameter block that we will be using in this module and the idaes logger. " + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "from idaes.models.properties.activity_coeff_models.BTX_activity_coeff_VLE import (\n", + " BTXParameterBlock,\n", + ")\n", + "import idaes.logger as idaeslog" + ] + }, { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
temperatureliq_benzenevap_benzene
0365.5000000.4809530.692110
1365.6176470.4624440.667699
2365.7352940.4779840.692441
3365.8529410.4405470.640336
4365.9705880.4274210.623328
5366.0882350.4427250.647796
6366.2058820.4343740.637691
7366.3235290.4446420.654933
8366.4411760.4271320.631229
9366.5588240.4463010.661743
10366.6764710.4380040.651591
11366.7941180.4253200.634814
12366.9117650.4394350.658047
13367.0294120.4356550.654539
14367.1470590.4013500.604987
15367.2647060.3978620.601703
16367.3823530.4158210.630930
17367.5000000.4206670.640380
18367.6176470.3916830.598214
19367.7352940.4049030.620432
20367.8529410.4095630.629626
21367.9705880.3894880.600722
22368.0000000.3967890.612483
23368.0882350.3981620.616106
24368.2058820.3623400.562505
25368.3235290.3869580.602680
26368.4411760.3636430.568210
27368.5588240.3681180.577072
28368.6764710.3840980.604078
29368.7941180.3536050.557925
30368.9117650.3464740.548445
31369.0294120.3507410.556996
32369.1470590.3623470.577286
33369.2647060.3625780.579519
34369.3823530.3407650.546411
35369.5000000.3374620.542857
36369.6176470.3557290.574083
37369.7352940.3486790.564513
38369.8529410.3381870.549284
39369.9705880.3243600.528514
40370.0882350.3107530.507964
41370.2058820.3110370.510055
42370.3235290.3112630.512055
43370.4411760.3080810.508437
44370.5588240.3082240.510293
45370.6764710.3181480.528399
46370.7941180.3083340.513728
47370.9117650.3179370.531410
48371.0294120.2891490.484824
49371.1470590.2986370.502318
\n", - "
" + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In the next cell, we import `parmest` from Pyomo and the `pandas` package. We need `pandas` as `parmest` uses `pandas.dataframe` for handling the input data and the results." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "import pyomo.contrib.parmest.parmest as parmest\n", + "import pandas as pd" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Setting up an initialized model\n", + "\n", + "We need to provide a method that returns an initialized model to the `parmest` tool in Pyomo." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "Inline Exercise:\n", + "Using what you have learned from previous modules, fill in the missing code below to return an initialized IDAES model. \n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "tags": [ + "solution" + ] + }, + "outputs": [], + "source": [ + "def NRTL_model(data):\n", + "\n", + " # Todo: Create a ConcreteModel object\n", + " m = ConcreteModel()\n", + "\n", + " # Todo: Create FlowsheetBlock object\n", + " m.fs = FlowsheetBlock(dynamic=False)\n", + "\n", + " # Todo: Create a properties parameter object with the following options:\n", + " # \"valid_phase\": ('Liq', 'Vap')\n", + " # \"activity_coeff_model\": 'NRTL'\n", + " m.fs.properties = BTXParameterBlock(\n", + " valid_phase=(\"Liq\", \"Vap\"), activity_coeff_model=\"NRTL\"\n", + " )\n", + " m.fs.flash = Flash(property_package=m.fs.properties)\n", + "\n", + " # Initialize at a certain inlet condition\n", + " m.fs.flash.inlet.flow_mol.fix(1)\n", + " m.fs.flash.inlet.temperature.fix(368)\n", + " m.fs.flash.inlet.pressure.fix(101325)\n", + " m.fs.flash.inlet.mole_frac_comp[0, \"benzene\"].fix(0.5)\n", + " m.fs.flash.inlet.mole_frac_comp[0, \"toluene\"].fix(0.5)\n", + "\n", + " # Set Flash unit specifications\n", + " m.fs.flash.heat_duty.fix(0)\n", + " m.fs.flash.deltaP.fix(0)\n", + "\n", + " # Fix NRTL specific variables\n", + " # alpha values (set at 0.3)\n", + " m.fs.properties.alpha[\"benzene\", \"benzene\"].fix(0)\n", + " m.fs.properties.alpha[\"benzene\", \"toluene\"].fix(0.3)\n", + " m.fs.properties.alpha[\"toluene\", \"toluene\"].fix(0)\n", + " m.fs.properties.alpha[\"toluene\", \"benzene\"].fix(0.3)\n", + "\n", + " # initial tau values\n", + " m.fs.properties.tau[\"benzene\", \"benzene\"].fix(0)\n", + " m.fs.properties.tau[\"benzene\", \"toluene\"].fix(-0.9)\n", + " m.fs.properties.tau[\"toluene\", \"toluene\"].fix(0)\n", + " m.fs.properties.tau[\"toluene\", \"benzene\"].fix(1.4)\n", + "\n", + " # Initialize the flash unit\n", + " m.fs.flash.initialize(outlvl=idaeslog.INFO_LOW)\n", + "\n", + " # Fix at actual temperature\n", + " if isinstance(data, dict) or isinstance(data, pd.Series):\n", + " m.fs.flash.inlet.temperature.fix(float(data[\"temperature\"]))\n", + " elif isinstance(data, pd.DataFrame):\n", + " m.fs.flash.inlet.temperature.fix(float(data.iloc[0][\"temperature\"]))\n", + " else:\n", + " raise ValueError(\"Unrecognized data type.\")\n", + "\n", + " # Set bounds on variables to be estimated\n", + " m.fs.properties.tau[\"benzene\", \"toluene\"].setlb(-5)\n", + " m.fs.properties.tau[\"benzene\", \"toluene\"].setub(5)\n", + "\n", + " m.fs.properties.tau[\"toluene\", \"benzene\"].setlb(-5)\n", + " m.fs.properties.tau[\"toluene\", \"benzene\"].setub(5)\n", + "\n", + " # Return initialized flash model\n", + " return m" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Parameter estimation using parmest" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In addition to providing a method to return an initialized model, the `parmest` tool needs the following:\n", + "\n", + "* Experiment class to set up and label model with suffixes\n", + "* Dataset with multiple scenarios - organized into an experiment list" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here we build an experiment class to label our model problem for parameter estimation. The labels are defined as a `Suffix`, and the main labels for our model are `experiment_outputs`, `unknown_parameters`. and `measurement_error`.\n", + "\n", + "For this problem, the error will be computed for the mole fraction of benzene in the vapor and liquid phase between the model prediction and data. The `experimental_outputs` will therefore be the mole fraction of benzene in the two phases.\n", + "\n", + "In this example, we only estimate the binary interaction parameter (`tau_ij`). Given that this variable is usually indexed as `tau_ij = Var(component_list, component_list)`, there are 2*2=4 degrees of freedom. However, when i=j, the binary interaction parameter is 0. Therefore, in this problem, we estimate the binary interaction parameter for the following variables only:\n", + "\n", + "* fs.properties.tau['benzene', 'toluene']\n", + "* fs.properties.tau['toluene', 'benzene']\n", + "\n", + "As shown below, these model components are used as our `unknown_parameters`.\n", + "\n", + "We define `measurement_error` as none so parmest calculates the value internally based on the experimental outputs. Refer to https://pyomo.readthedocs.io/en/stable/explanation/analysis/parmest/driver.html for more information. " + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "# Build an experiment class to take advantage of new parmest interface\n", + "from pyomo.contrib.parmest.experiment import Experiment\n", + "\n", + "\n", + "class NRTLExperiment(Experiment):\n", + " \"\"\"Experiment class for parameter estimation of NRTL model using parmest\"\"\"\n", + "\n", + " def __init__(self, data, meas_error=None):\n", + " \"\"\"Initialize the NRTLExperiment class\n", + "\n", + " Args:\n", + " data: DataFrame containing the experimental data\n", + " meas_error: Measurement error for the data (optional)\n", + " \"\"\"\n", + " self.model = None\n", + " self.data = data\n", + " self.meas_error = meas_error\n", + "\n", + " def create_model(self):\n", + " \"\"\"Create the Pyomo model for the NRTL parameter estimation problem\"\"\"\n", + " self.model = NRTL_model(self.data)\n", + "\n", + " def label_model(self):\n", + " m = self.model\n", + "\n", + " # Add experiment outputs to the model for easier access\n", + " m.experiment_outputs = Suffix(direction=Suffix.LOCAL)\n", + " m.experiment_outputs.update(\n", + " [\n", + " (\n", + " m.fs.flash.liq_outlet.mole_frac_comp[0, \"benzene\"],\n", + " self.data[\"liq_benzene\"],\n", + " ),\n", + " (\n", + " m.fs.flash.vap_outlet.mole_frac_comp[0, \"benzene\"],\n", + " self.data[\"vap_benzene\"],\n", + " ),\n", + " ]\n", + " )\n", + "\n", + " m.measurement_error = Suffix(direction=Suffix.LOCAL)\n", + " m.measurement_error.update(\n", + " [\n", + " (m.fs.flash.liq_outlet.mole_frac_comp[0, \"benzene\"], self.meas_error),\n", + " (m.fs.flash.vap_outlet.mole_frac_comp[0, \"benzene\"], self.meas_error),\n", + " ]\n", + " )\n", + "\n", + " # Add unknown parameters to the model for easier access\n", + " m.unknown_parameters = Suffix(direction=Suffix.LOCAL)\n", + " m.unknown_parameters.update(\n", + " (k, value(k))\n", + " for k in [\n", + " m.fs.properties.tau[\"benzene\", \"toluene\"],\n", + " m.fs.properties.tau[\"toluene\", \"benzene\"],\n", + " ]\n", + " )\n", + "\n", + " def get_labeled_model(self):\n", + " \"\"\"Return the labeled model\"\"\"\n", + " if self.model is None:\n", + " self.create_model()\n", + " self.label_model()\n", + " return self.model" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Pyomo's `parmest` tool supports the following data formats:\n", + "- pandas dataframe\n", + "- list of dictionaries\n", + "- list of json file names.\n", + "\n", + "Please see the documentation for more details. \n", + "\n", + "For this example, we load data from the csv file `BT_NRTL_dataset.csv`. The dataset consists of fifty data points which provide the mole fraction of benzene in the vapor and liquid phase as a function of temperature. " + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
temperatureliq_benzenevap_benzene
0365.5000000.4809530.692110
1365.6176470.4624440.667699
2365.7352940.4779840.692441
3365.8529410.4405470.640336
4365.9705880.4274210.623328
5366.0882350.4427250.647796
6366.2058820.4343740.637691
7366.3235290.4446420.654933
8366.4411760.4271320.631229
9366.5588240.4463010.661743
10366.6764710.4380040.651591
11366.7941180.4253200.634814
12366.9117650.4394350.658047
13367.0294120.4356550.654539
14367.1470590.4013500.604987
15367.2647060.3978620.601703
16367.3823530.4158210.630930
17367.5000000.4206670.640380
18367.6176470.3916830.598214
19367.7352940.4049030.620432
20367.8529410.4095630.629626
21367.9705880.3894880.600722
22368.0000000.3967890.612483
23368.0882350.3981620.616106
24368.2058820.3623400.562505
25368.3235290.3869580.602680
26368.4411760.3636430.568210
27368.5588240.3681180.577072
28368.6764710.3840980.604078
29368.7941180.3536050.557925
30368.9117650.3464740.548445
31369.0294120.3507410.556996
32369.1470590.3623470.577286
33369.2647060.3625780.579519
34369.3823530.3407650.546411
35369.5000000.3374620.542857
36369.6176470.3557290.574083
37369.7352940.3486790.564513
38369.8529410.3381870.549284
39369.9705880.3243600.528514
40370.0882350.3107530.507964
41370.2058820.3110370.510055
42370.3235290.3112630.512055
43370.4411760.3080810.508437
44370.5588240.3082240.510293
45370.6764710.3181480.528399
46370.7941180.3083340.513728
47370.9117650.3179370.531410
48371.0294120.2891490.484824
49371.1470590.2986370.502318
\n", + "
" + ], + "text/plain": [ + " temperature liq_benzene vap_benzene\n", + "0 365.500000 0.480953 0.692110\n", + "1 365.617647 0.462444 0.667699\n", + "2 365.735294 0.477984 0.692441\n", + "3 365.852941 0.440547 0.640336\n", + "4 365.970588 0.427421 0.623328\n", + "5 366.088235 0.442725 0.647796\n", + "6 366.205882 0.434374 0.637691\n", + "7 366.323529 0.444642 0.654933\n", + "8 366.441176 0.427132 0.631229\n", + "9 366.558824 0.446301 0.661743\n", + "10 366.676471 0.438004 0.651591\n", + "11 366.794118 0.425320 0.634814\n", + "12 366.911765 0.439435 0.658047\n", + "13 367.029412 0.435655 0.654539\n", + "14 367.147059 0.401350 0.604987\n", + "15 367.264706 0.397862 0.601703\n", + "16 367.382353 0.415821 0.630930\n", + "17 367.500000 0.420667 0.640380\n", + "18 367.617647 0.391683 0.598214\n", + "19 367.735294 0.404903 0.620432\n", + "20 367.852941 0.409563 0.629626\n", + "21 367.970588 0.389488 0.600722\n", + "22 368.000000 0.396789 0.612483\n", + "23 368.088235 0.398162 0.616106\n", + "24 368.205882 0.362340 0.562505\n", + "25 368.323529 0.386958 0.602680\n", + "26 368.441176 0.363643 0.568210\n", + "27 368.558824 0.368118 0.577072\n", + "28 368.676471 0.384098 0.604078\n", + "29 368.794118 0.353605 0.557925\n", + "30 368.911765 0.346474 0.548445\n", + "31 369.029412 0.350741 0.556996\n", + "32 369.147059 0.362347 0.577286\n", + "33 369.264706 0.362578 0.579519\n", + "34 369.382353 0.340765 0.546411\n", + "35 369.500000 0.337462 0.542857\n", + "36 369.617647 0.355729 0.574083\n", + "37 369.735294 0.348679 0.564513\n", + "38 369.852941 0.338187 0.549284\n", + "39 369.970588 0.324360 0.528514\n", + "40 370.088235 0.310753 0.507964\n", + "41 370.205882 0.311037 0.510055\n", + "42 370.323529 0.311263 0.512055\n", + "43 370.441176 0.308081 0.508437\n", + "44 370.558824 0.308224 0.510293\n", + "45 370.676471 0.318148 0.528399\n", + "46 370.794118 0.308334 0.513728\n", + "47 370.911765 0.317937 0.531410\n", + "48 371.029412 0.289149 0.484824\n", + "49 371.147059 0.298637 0.502318" + ] + }, + "metadata": {}, + "output_type": "display_data" + } ], - "text/plain": [ - " temperature liq_benzene vap_benzene\n", - "0 365.500000 0.480953 0.692110\n", - "1 365.617647 0.462444 0.667699\n", - "2 365.735294 0.477984 0.692441\n", - "3 365.852941 0.440547 0.640336\n", - "4 365.970588 0.427421 0.623328\n", - "5 366.088235 0.442725 0.647796\n", - "6 366.205882 0.434374 0.637691\n", - "7 366.323529 0.444642 0.654933\n", - "8 366.441176 0.427132 0.631229\n", - "9 366.558824 0.446301 0.661743\n", - "10 366.676471 0.438004 0.651591\n", - "11 366.794118 0.425320 0.634814\n", - "12 366.911765 0.439435 0.658047\n", - "13 367.029412 0.435655 0.654539\n", - "14 367.147059 0.401350 0.604987\n", - "15 367.264706 0.397862 0.601703\n", - "16 367.382353 0.415821 0.630930\n", - "17 367.500000 0.420667 0.640380\n", - "18 367.617647 0.391683 0.598214\n", - "19 367.735294 0.404903 0.620432\n", - "20 367.852941 0.409563 0.629626\n", - "21 367.970588 0.389488 0.600722\n", - "22 368.000000 0.396789 0.612483\n", - "23 368.088235 0.398162 0.616106\n", - "24 368.205882 0.362340 0.562505\n", - "25 368.323529 0.386958 0.602680\n", - "26 368.441176 0.363643 0.568210\n", - "27 368.558824 0.368118 0.577072\n", - "28 368.676471 0.384098 0.604078\n", - "29 368.794118 0.353605 0.557925\n", - "30 368.911765 0.346474 0.548445\n", - "31 369.029412 0.350741 0.556996\n", - "32 369.147059 0.362347 0.577286\n", - "33 369.264706 0.362578 0.579519\n", - "34 369.382353 0.340765 0.546411\n", - "35 369.500000 0.337462 0.542857\n", - "36 369.617647 0.355729 0.574083\n", - "37 369.735294 0.348679 0.564513\n", - "38 369.852941 0.338187 0.549284\n", - "39 369.970588 0.324360 0.528514\n", - "40 370.088235 0.310753 0.507964\n", - "41 370.205882 0.311037 0.510055\n", - "42 370.323529 0.311263 0.512055\n", - "43 370.441176 0.308081 0.508437\n", - "44 370.558824 0.308224 0.510293\n", - "45 370.676471 0.318148 0.528399\n", - "46 370.794118 0.308334 0.513728\n", - "47 370.911765 0.317937 0.531410\n", - "48 371.029412 0.289149 0.484824\n", - "49 371.147059 0.298637 0.502318" + "source": [ + "# Load data from csv\n", + "data = pd.read_csv(\"BT_NRTL_dataset.csv\")\n", + "\n", + "# Display the dataset\n", + "display(data)" ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# Load data from csv\n", - "data = pd.read_csv(\"BT_NRTL_dataset.csv\")\n", - "\n", - "# Display the dataset\n", - "display(data)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "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 mole fraction of benzene in the vapor and liquid phase between the model prediction and data. \n", - "\n", - "
\n", - "Inline Exercise:\n", - "Complete the following cell by adding an expression to compute the sum of square errors. \n", - "
" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": { - "tags": [ - "solution" - ] - }, - "outputs": [], - "source": [ - "# Create method to return an expression that computes the sum of squared error\n", - "def SSE(m, data):\n", - " # Todo: Add expression for computing the sum of squared errors in mole fraction of benzene in the liquid\n", - " # and vapor phase. For example, the squared error for the vapor phase is:\n", - " # (float(data[\"vap_benzene\"]) - m.fs.flash.vap_outlet.mole_frac_comp[0, \"benzene\"])**2\n", - " expr = (\n", - " float(data[\"vap_benzene\"]) - m.fs.flash.vap_outlet.mole_frac_comp[0, \"benzene\"]\n", - " ) ** 2 + (\n", - " float(data[\"liq_benzene\"]) - m.fs.flash.liq_outlet.mole_frac_comp[0, \"benzene\"]\n", - " ) ** 2\n", - " return expr * 1e4" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
\n", - "Note:\n", - "Notice that we have scaled the expression up by a factor of 10000 as the SSE computed here will be an extremely small number given that we are using the difference in mole fraction in our expression. A well-scaled objective will help improve solve robustness when using IPOPT. \n", - "
\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "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, dataset, list of variable names to estimate, and the SSE expression to the Estimator object. `tee=True` will print the solver output after solving the parameter estimation problem." - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ + }, { - "name": "stderr", - "output_type": "stream", - "text": [ - "C:\\Users\\dkgun\\AppData\\Local\\Temp\\ipykernel_36352\\1862275024.py:45: FutureWarning: Calling float on a single element Series is deprecated and will raise a TypeError in the future. Use float(ser.iloc[0]) instead\n", - " m.fs.flash.inlet.temperature.fix(float(data[\"temperature\"]))\n", - "C:\\Users\\dkgun\\AppData\\Local\\Temp\\ipykernel_36352\\2860104238.py:7: FutureWarning: Calling float on a single element Series is deprecated and will raise a TypeError in the future. Use float(ser.iloc[0]) instead\n", - " float(data[\"vap_benzene\"]) - m.fs.flash.vap_outlet.mole_frac_comp[0, \"benzene\"]\n", - "C:\\Users\\dkgun\\AppData\\Local\\Temp\\ipykernel_36352\\2860104238.py:9: FutureWarning: Calling float on a single element Series is deprecated and will raise a TypeError in the future. Use float(ser.iloc[0]) instead\n", - " float(data[\"liq_benzene\"]) - m.fs.flash.liq_outlet.mole_frac_comp[0, \"benzene\"]\n" - ] + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We define the `exp_list` by spliting the data into individual experiments, or data points." + ] }, { - "name": "stdout", - "output_type": "stream", - "text": [ - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 10946\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 6600\n", - "\n", - "Total number of variables............................: 2950\n", - " variables with only lower bounds: 150\n", - " variables with lower and upper bounds: 600\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 2948\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 6.0671019e+01 5.63e+02 1.08e-04 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 5.0339335e+00 1.57e+03 7.47e+01 -1.0 1.37e+04 - 9.45e-01 1.00e+00h 1\n", - " 2 5.1535704e+00 1.93e+02 4.59e+02 -1.0 5.54e+02 -4.0 9.90e-01 1.00e+00h 1\n", - " 3 5.1392848e+00 1.07e+00 3.40e+01 -1.0 6.17e+01 -4.5 9.92e-01 1.00e+00h 1\n", - " 4 5.1359488e+00 3.65e+02 2.24e+01 -1.0 8.41e+02 - 1.00e+00 1.00e+00h 1\n", - " 5 5.1198699e+00 1.64e+00 1.32e-01 -1.0 3.65e+02 - 1.00e+00 1.00e+00h 1\n", - " 6 5.0735545e+00 1.54e+02 1.83e-01 -2.5 3.80e+02 - 9.96e-01 1.00e+00h 1\n", - " 7 5.0752210e+00 1.03e+01 5.00e-02 -2.5 9.51e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 5.0750012e+00 5.57e-03 2.07e-05 -2.5 2.09e-01 - 1.00e+00 1.00e+00h 1\n", - " 9 5.0749679e+00 5.85e-02 7.21e-04 -3.8 8.43e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 5.0749686e+00 5.59e-04 1.05e-05 -5.7 9.63e-01 - 1.00e+00 1.00e+00h 1\n", - " 11 5.0749686e+00 3.98e-08 1.56e-09 -8.6 7.56e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 11\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 5.0749685783045084e+00 5.0749685783045084e+00\n", - "Dual infeasibility......: 1.5648775501801708e-09 1.5648775501801708e-09\n", - "Constraint violation....: 1.3843631310512158e-10 3.9843143895268440e-08\n", - "Complementarity.........: 2.5074825419922871e-09 2.5074825419922871e-09\n", - "Overall NLP error.......: 2.5074825419922871e-09 3.9843143895268440e-08\n", - "\n", - "\n", - "Number of objective function evaluations = 12\n", - "Number of objective gradient evaluations = 12\n", - "Number of equality constraint evaluations = 12\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 12\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 11\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.053\n", - "Total CPU secs in NLP function evaluations = 0.010\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "\b\b\b\b\b\b\b\b\b\b\b\b\b\b" - ] - } - ], - "source": [ - "# Initialize a parameter estimation object\n", - "pest = parmest.Estimator(NRTL_model, data, variable_name, SSE, tee=True)\n", - "\n", - "# Run parameter estimation using all data\n", - "obj_value, parameters = pest.theta_est()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You will notice that the resulting parameter estimation problem, when using the flash unit model, will have 2952 variables and 2950 constraints. This is because the unit models in IDAES use control volume blocks which have two state blocks attached; one at the inlet and one at the outlet. Even though there are two state blocks, they still use the same parameter block i.e. `m.fs.properties` in our example which is where our parameters that need to be estimated exist. \n", - "\n", - "Let us display the results by running the next cell. " - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "# Loop through the dataset and create an experiment for each row of data\n", + "exp_list = []\n", + "for i in range(data.shape[0]):\n", + " exp_list.append(NRTLExperiment(data.iloc[i]))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "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." + ] + }, { - "name": "stdout", - "output_type": "stream", - "text": [ - "The SSE at the optimal solution is 0.000507\n", - "\n", - "The values for the parameters are as follows:\n", - "fs.properties.tau[benzene,toluene] = -0.8987624039723903\n", - "fs.properties.tau[toluene,benzene] = 1.410486110660486\n" - ] + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 10950\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 6600\n", + "\n", + "Total number of variables............................: 2952\n", + " variables with only lower bounds: 150\n", + " variables with lower and upper bounds: 600\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 2950\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 6.0671019e-03 5.63e+02 1.20e-08 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 9.0714942e-04 1.37e+03 1.61e+01 -1.0 1.37e+04 - 9.82e-01 1.00e+00h 1\n", + " 2 1.3219937e-03 1.17e+04 1.62e+01 -1.0 5.23e+03 - 3.41e-01 1.65e-01h 3\n", + " 3 1.3161671e-03 1.11e+04 4.02e+01 -1.0 3.96e+02 -4.0 8.19e-01 1.25e-01h 4\n", + " 4 1.3154170e-03 1.11e+04 4.32e+01 -1.0 3.47e+02 -4.5 9.90e-01 4.43e-02h 5\n", + " 5 9.4424343e-04 1.04e+04 4.05e+01 -1.0 1.16e+04 - 9.33e-01 5.61e-02h 5\n", + " 6 9.4571258e-04 1.11e+04 4.85e+01 -1.0 3.13e+02 -5.0 8.74e-01 1.25e-01h 4\n", + " 7 9.4862862e-04 1.11e+04 4.84e+01 -1.0 2.41e+03 -5.4 1.72e-01 1.50e-03h 8\n", + " 8 9.5448936e-04 1.10e+04 4.81e+01 -1.0 4.11e+02 -5.0 1.00e+00 1.97e-02h 6\n", + " 9 9.5650047e-04 1.10e+04 4.81e+01 -1.0 5.14e+02 -4.6 3.46e-01 5.24e-03h 7\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 9.5730419e-04 1.10e+04 4.81e+01 -1.0 9.78e+02 -4.2 4.40e-01 1.08e-03h 8\n", + " 11 9.5774182e-04 1.10e+04 4.84e+01 -1.0 2.76e+02 -3.7 2.91e-01 2.99e-03h 7\n", + " 12 9.4292855e-04 7.77e+04 4.09e+04 -1.0 5.38e+02 -2.4 5.48e-02 6.44e-02w 1\n", + " 13 2.4318219e-01 2.38e+07 4.22e+14 -1.0 1.28e+06 - 2.55e-02 3.49e-02w 1\n", + " 14 2.8902019e-01 1.64e+07 2.92e+14 -1.0 1.11e+05 -2.9 9.54e-01 3.01e-01w 1\n", + " 15 9.5768293e-04 1.10e+04 4.85e+01 -1.0 2.80e+05 -3.4 5.48e-02 2.52e-04h 8\n", + " 16 9.5769345e-04 1.10e+04 4.85e+01 -1.0 4.33e+02 -2.9 7.95e-02 1.91e-04h 9\n", + " 17 9.5763809e-04 1.10e+04 4.85e+01 -1.0 6.35e+02 -2.5 4.94e-02 2.08e-04h 9\n", + " 18 9.5734836e-04 1.10e+04 4.87e+01 -1.0 3.22e+02 -3.0 1.00e+00 1.22e-03h 8\n", + " 19 9.3628114e-04 1.09e+04 4.62e+01 -1.0 4.22e+02 -3.5 5.16e-01 5.87e-02h 5\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 7.1894543e-04 4.02e+03 4.95e+02 -1.0 3.49e+02 -3.9 1.00e+00 1.00e+00h 1\n", + " 21 6.7062834e-04 1.58e+02 2.21e+02 -1.0 1.78e+02 -4.4 1.00e+00 1.00e+00h 1\n", + " 22 6.6635123e-04 4.17e+01 1.12e+01 -1.0 2.44e+02 -4.9 1.00e+00 1.00e+00h 1\n", + " 23 6.6729070e-04 1.43e+00 9.69e-01 -1.0 1.08e+01 -5.4 1.00e+00 1.00e+00h 1\n", + " 24 6.6785681e-04 3.58e-01 5.25e-03 -1.7 6.65e+00 -5.8 1.00e+00 1.00e+00h 1\n", + " 25 6.2552355e-04 9.80e+02 6.48e-02 -3.8 7.92e+02 - 9.22e-01 1.00e+00h 1\n", + " 26 5.9105707e-04 8.13e+00 6.13e-04 -3.8 5.66e+02 - 1.00e+00 1.00e+00h 1\n", + " 27 6.1313801e-04 6.24e+01 8.08e-06 -3.8 1.70e+02 - 1.00e+00 1.00e+00h 1\n", + " 28 6.1208051e-04 3.58e-01 1.18e-08 -3.8 1.88e+00 - 1.00e+00 1.00e+00h 1\n", + " 29 5.9010560e-04 1.58e+01 1.00e-05 -5.7 1.08e+02 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30 5.9008319e-04 2.74e-02 7.90e-07 -5.7 7.54e-02 -6.3 1.00e+00 1.00e+00h 1\n", + " 31 5.3570104e-04 1.48e+04 8.70e-04 -5.7 1.81e+02 - 1.00e+00 1.00e+00h 1\n", + " 32 5.1618763e-04 6.29e+02 8.06e-05 -5.7 2.55e+02 - 1.00e+00 1.00e+00h 1\n", + " 33 5.5250565e-04 2.88e+01 2.58e-04 -5.7 1.81e+04 - 6.26e-01 6.25e-02h 5\n", + " 34 5.2209909e-04 2.88e+02 2.02e-04 -5.7 1.89e+03 - 1.00e+00 1.00e+00h 1\n", + " 35 5.0707798e-04 5.60e+01 2.02e-04 -5.7 2.93e+03 - 1.00e+00 1.00e+00h 1\n", + " 36 5.0765648e-04 7.87e+00 1.91e-05 -5.7 1.02e+02 - 1.00e+00 1.00e+00h 1\n", + " 37 5.0740606e-04 2.57e+00 1.88e-05 -5.7 6.96e+01 - 1.00e+00 1.00e+00h 1\n", + " 38 5.0764164e-04 2.55e+00 1.76e-05 -5.7 6.81e+01 - 1.00e+00 1.00e+00h 1\n", + " 39 5.0740672e-04 2.55e+00 1.88e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 40 5.0764162e-04 2.54e+00 1.76e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", + " 41 5.0740672e-04 2.55e+00 1.88e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", + " 42 5.0782847e-04 1.43e-01 1.83e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00H 1\n", + " 43 5.0751252e-04 1.58e-02 1.93e-05 -5.7 6.88e+01 - 1.00e+00 1.00e+00H 1\n", + " 44 5.0783218e-04 4.79e-03 1.85e-05 -5.7 6.92e+01 - 1.00e+00 1.00e+00H 1\n", + " 45 5.0751252e-04 1.60e-02 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", + " 46 5.0783222e-04 1.23e-04 1.85e-05 -5.7 6.92e+01 - 1.00e+00 1.00e+00H 1\n", + " 47 5.0751252e-04 1.60e-02 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", + " 48 5.0783216e-04 1.24e-04 1.85e-05 -5.7 6.92e+01 - 1.00e+00 1.00e+00H 1\n", + " 49 5.0751765e-04 3.20e-03 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 50 5.0764151e-04 2.56e+00 1.77e-05 -5.7 6.93e+01 - 1.00e+00 1.00e+00h 1\n", + " 51 5.0740671e-04 2.55e+00 1.88e-05 -5.7 6.81e+01 - 1.00e+00 1.00e+00h 1\n", + " 52 5.0764162e-04 2.54e+00 1.76e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", + " 53 5.0740672e-04 2.55e+00 1.88e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", + " 54 5.0764162e-04 2.54e+00 1.76e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", + " 55 5.0748886e-04 1.91e+00 8.64e-06 -5.7 6.80e+01 - 1.00e+00 5.00e-01h 2\n", + " 56 5.0744550e-04 3.37e-01 1.64e-05 -5.7 2.54e+01 - 1.00e+00 1.00e+00h 1\n", + " 57 5.0763613e-04 1.82e+00 1.43e-05 -5.7 5.79e+01 - 1.00e+00 1.00e+00h 1\n", + " 58 5.0751252e-04 2.25e-02 1.93e-05 -5.7 6.65e+01 - 1.00e+00 1.00e+00H 1\n", + " 59 5.0783220e-04 1.23e-04 1.85e-05 -5.7 6.92e+01 - 1.00e+00 1.00e+00H 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 60 5.0751252e-04 1.60e-02 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", + " 61 5.0783207e-04 3.26e-04 1.85e-05 -5.7 6.92e+01 - 1.00e+00 1.00e+00H 1\n", + " 62 5.0751786e-04 7.95e-05 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", + " 63 5.0754291e-04 6.40e-01 8.69e-06 -5.7 6.93e+01 - 1.00e+00 5.00e-01h 2\n", + " 64 5.0745167e-04 3.00e-01 1.61e-05 -5.7 2.35e+01 - 1.00e+00 1.00e+00h 1\n", + " 65 5.0763437e-04 1.71e+00 1.33e-05 -5.7 5.61e+01 - 1.00e+00 1.00e+00h 1\n", + " 66 5.0751762e-04 2.91e-03 1.93e-05 -5.7 6.60e+01 - 1.00e+00 1.00e+00H 1\n", + " 67 5.0752104e-04 1.62e-01 1.43e-05 -5.7 6.92e+01 - 1.00e+00 2.50e-01h 3\n", + " 68 5.0761295e-04 1.03e+00 2.18e-05 -5.7 4.35e+01 - 1.00e+00 1.00e+00h 1\n", + " 69 5.0751251e-04 2.38e-02 1.92e-05 -5.7 5.95e+01 - 1.00e+00 1.00e+00H 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 70 5.0783210e-04 3.29e-06 1.85e-05 -5.7 6.90e+01 - 1.00e+00 1.00e+00H 1\n", + " 71 5.0751786e-04 7.94e-05 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", + " 72 5.0754292e-04 6.40e-01 8.69e-06 -5.7 6.93e+01 - 1.00e+00 5.00e-01h 2\n", + " 73 5.0749299e-04 3.95e-01 1.21e-05 -5.7 2.35e+01 - 1.00e+00 5.00e-01h 2\n", + " 74 5.0755524e-04 1.36e-01 3.09e-05 -5.7 1.57e+01 - 1.00e+00 1.00e+00h 1\n", + " 75 5.0751308e-04 1.96e-02 1.80e-05 -5.7 3.30e+01 - 1.00e+00 1.00e+00H 1\n", + " 76 5.0754492e-04 5.62e-01 8.19e-06 -5.7 6.42e+01 - 1.00e+00 5.00e-01h 2\n", + " 77 5.0748301e-04 3.98e-01 1.25e-05 -5.7 2.93e+01 - 1.00e+00 5.00e-01h 2\n", + " 78 5.0756455e-04 2.42e-01 3.07e-05 -5.7 2.09e+01 - 1.00e+00 1.00e+00h 1\n", + " 79 5.0751710e-04 1.38e-03 1.87e-05 -5.7 3.98e+01 - 1.00e+00 1.00e+00H 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 80 5.0783077e-04 3.26e-06 1.84e-05 -5.7 6.70e+01 - 1.00e+00 1.00e+00H 1\n", + " 81 5.0726420e-04 1.24e+01 1.85e-05 -8.6 1.34e+02 - 9.93e-01 1.00e+00h 1\n", + " 82 5.0749897e-04 2.75e+00 2.53e-06 -8.6 6.93e+01 - 1.00e+00 1.00e+00h 1\n", + " 83 5.0749686e-04 3.64e-04 6.40e-10 -8.6 4.69e-02 - 1.00e+00 1.00e+00h 1\n", + " 84 5.0749686e-04 7.28e-11 2.51e-14 -8.6 6.86e-05 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 84\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 5.0749685809243843e-04 5.0749685809243843e-04\n", + "Dual infeasibility......: 2.5059195074646584e-14 2.5059195074646584e-14\n", + "Constraint violation....: 1.4104644499482425e-11 7.2759576141834259e-11\n", + "Complementarity.........: 2.5059035596800647e-09 2.5059035596800647e-09\n", + "Overall NLP error.......: 2.5059035596800647e-09 2.5059035596800647e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 260\n", + "Number of objective gradient evaluations = 85\n", + "Number of equality constraint evaluations = 260\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 85\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 84\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.338\n", + "Total CPU secs in NLP function evaluations = 0.092\n", + "\n", + "EXIT: Optimal Solution Found.\n" + ] + } + ], + "source": [ + "import logging\n", + "\n", + "idaeslog.getIdaesLogger(\"core.property_meta\").setLevel(logging.ERROR)\n", + "\n", + "pest = parmest.Estimator(exp_list, obj_function=\"SSE\", tee=True)\n", + "obj_value, parameters = pest.theta_est()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You will notice that the resulting parameter estimation problem, when using the flash unit model, will have 2952 variables and 2950 constraints. This is because the unit models in IDAES use control volume blocks which have two state blocks attached; one at the inlet and one at the outlet. Even though there are two state blocks, they still use the same parameter block i.e. `m.fs.properties` in our example which is where our parameters that need to be estimated exist. \n", + "\n", + "Let us display the results by running the next cell. " + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The SSE at the optimal solution is 0.000507\n", + "\n", + "The values for the parameters are as follows:\n", + "fs.properties.tau[benzene,toluene] = -0.8987454466579063\n", + "fs.properties.tau[toluene,benzene] = 1.410449514796474\n" + ] + } + ], + "source": [ + "print(\"The SSE at the optimal solution is %0.6f\" % (obj_value))\n", + "print()\n", + "print(\"The values for the parameters are as follows:\")\n", + "for k, v in parameters.items():\n", + " print(k, \"=\", v)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Using the data that was provided, we have estimated the binary interaction parameters in the NRTL model for a benzene-toluene mixture. Although the dataset that was provided was temperature dependent, in this example we have estimated a single value that fits best for all temperatures." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Advanced options for parmest: bootstrapping\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Pyomo's `parmest` tool allows for bootstrapping where the parameter estimation is repeated over `n` samples with resampling from the original data set. Parameter estimation with bootstrap resampling can be used to identify confidence regions around each parameter estimate. This analysis can be slow given the increased number of model instances that need to be solved. Please refer to https://pyomo.readthedocs.io/en/stable/explanation/analysis/parmest/covariance.html#bootstrapping for more details. \n", + "\n", + "For the example above, the bootstrapping can be run by uncommenting the code in the following cell:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "# Run parameter estimation using bootstrap resample of the data (10 samples),\n", + "# plot results along with confidence regions\n", + "\n", + "# Uncomment the following lines\n", + "# bootstrap_theta = pest.theta_est_bootstrap(4, seed=542)\n", + "# display(bootstrap_theta)" + ] + } + ], + "metadata": { + "celltoolbar": "Tags", + "kernelspec": { + "display_name": "idaes-pse-and-examples-dev-py313-macmini", + "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.13.13" } - ], - "source": [ - "print(\"The SSE at the optimal solution is %0.6f\" % (obj_value * 1e-4))\n", - "print()\n", - "print(\"The values for the parameters are as follows:\")\n", - "for k, v in parameters.items():\n", - " print(k, \"=\", v)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Using the data that was provided, we have estimated the binary interaction parameters in the NRTL model for a benzene-toluene mixture. Although the dataset that was provided was temperature dependent, in this example we have estimated a single value that fits best for all temperatures." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Advanced options for parmest: bootstrapping\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Pyomo's `parmest` tool allows for bootstrapping where the parameter estimation is repeated over `n` samples with resampling from the original data set. Parameter estimation with bootstrap resampling can be used to identify confidence regions around each parameter estimate. This analysis can be slow given the increased number of model instances that need to be solved. Please refer to https://pyomo.readthedocs.io/en/stable/contributed_packages/parmest/driver.html for more details. \n", - "\n", - "For the example above, the bootstrapping can be run by uncommenting the code in the following cell:" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [], - "source": [ - "# Run parameter estimation using bootstrap resample of the data (10 samples),\n", - "# plot results along with confidence regions\n", - "\n", - "# Uncomment the following lines\n", - "\n", - "# bootstrap_theta = pest.theta_est_bootstrap(4)\n", - "# display(bootstrap_theta)" - ] - } - ], - "metadata": { - "celltoolbar": "Tags", - "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.11.5" - } - }, - "nbformat": 4, - "nbformat_minor": 3 -} + "nbformat": 4, + "nbformat_minor": 3 +} \ No newline at end of file diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_exercise.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_exercise.ipynb index 9ebb2bbd..9bc7f5e6 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_exercise.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_exercise.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": { "tags": [ "header", @@ -16,7 +16,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", @@ -32,8 +32,8 @@ "# Parameter Estimation Using Flash Unit Model\n", "\n", "Author: Jaffer Ghouse \n", - "Maintainer: Andrew Lee \n", - "Updated: 2023-06-01 \n", + "Maintainer: Stephen Cini \n", + "Updated: 2026-06-11 \n", "\n", "In this module, we will be using Pyomo's `parmest` tool in conjunction with IDAES models for parameter estimation. We demonstrate these tools by estimating the parameters associated with the NRTL property model for a benzene-toluene mixture. The NRTL model has 2 sets of parameters: the non-randomness parameter (`alpha_ij`) and the binary interaction parameter (`tau_ij`), where `i` and `j` is the pure component species. In this example, we will be only estimate the binary interaction parameter (`tau_ij`) for a given dataset. 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 the NRTL property package. \n", "\n", @@ -45,7 +45,7 @@ "\n", "## Key links to documentation:\n", "* NRTL Model - https://idaes-pse.readthedocs.io/en/stable/reference_guides/model_libraries/generic/property_models/activity_coefficient.html\n", - "* parmest - https://pyomo.readthedocs.io/en/stable/contributed_packages/parmest/index.html\n" + "* parmest - https://pyomo.readthedocs.io/en/stable/explanation/analysis/parmest/index.html" ] }, { @@ -54,13 +54,13 @@ "source": [ "
\n", "Inline Exercise:\n", - "import `ConcreteModel` from Pyomo, `FlowsheetBlock` and `Flash` from IDAES. \n", + "import `ConcreteModel`, `value`, and `Suffix` from Pyomo, `FlowsheetBlock` and `Flash` from IDAES. \n", "
" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": { "tags": [ "exercise" @@ -68,7 +68,7 @@ }, "outputs": [], "source": [ - "# Todo: import ConcreteModel from pyomo.environ\n", + "# Todo: import ConcreteModel, value, and Suffix from pyomo.environ\n", "\n", "# Todo: import FlowsheetBlock from idaes.core\n", "\n", @@ -84,7 +84,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -103,7 +103,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -132,7 +132,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "metadata": { "tags": [ "exercise" @@ -180,7 +180,12 @@ " m.fs.flash.initialize(outlvl=idaeslog.INFO_LOW)\n", "\n", " # Fix at actual temperature\n", - " m.fs.flash.inlet.temperature.fix(float(data[\"temperature\"]))\n", + " if isinstance(data, dict) or isinstance(data, pd.Series):\n", + " m.fs.state_block.temperature.fix(float(data[\"temperature\"]))\n", + " elif isinstance(data, pd.DataFrame):\n", + " m.fs.state_block.temperature.fix(float(data.iloc[0][\"temperature\"]))\n", + " else:\n", + " raise ValueError(\"Unrecognized data type.\")\n", "\n", " # Set bounds on variables to be estimated\n", " m.fs.properties.tau[\"benzene\", \"toluene\"].setlb(-5)\n", @@ -206,38 +211,98 @@ "source": [ "In addition to providing a method to return an initialized model, the `parmest` tool needs the following:\n", "\n", - "* List of variable names to be estimated\n", - "* Dataset with multiple scenarios\n", - "* Expression to compute the sum of squared errors\n", - "\n" + "* Experiment class to set up and label model with suffixes\n", + "* Dataset with multiple scenarios - organized into an experiment list" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ + "Here we build an experiment class to label our model problem for parameter estimation. The labels are defined as a `Suffix`, and the main labels for our model are `experiment_outputs`, `unknown_parameters`. and `measurement_error`.\n", + "\n", + "For this problem, the error will be computed for the mole fraction of benzene in the vapor and liquid phase between the model prediction and data. The `experimental_outputs` will therefore be the mole fraction of benzene in the two phases.\n", + "\n", "In this example, we only estimate the binary interaction parameter (`tau_ij`). Given that this variable is usually indexed as `tau_ij = Var(component_list, component_list)`, there are 2*2=4 degrees of freedom. However, when i=j, the binary interaction parameter is 0. Therefore, in this problem, we estimate the binary interaction parameter for the following variables only:\n", "\n", "* fs.properties.tau['benzene', 'toluene']\n", "* fs.properties.tau['toluene', 'benzene']\n", "\n", - "
\n", - "Inline Exercise:\n", - "Create a list called `variable_name` with the above-mentioned variables declared as strings.\n", - "
" + "As shown below, these model components are used as our `unknown_parameters`.\n", + "\n", + "We define `measurement_error` as none so parmest calculates the value internally based on the experimental outputs. Refer to https://pyomo.readthedocs.io/en/stable/explanation/analysis/parmest/driver.html for more information. " ] }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "exercise" - ] - }, + "execution_count": 9, + "metadata": {}, "outputs": [], "source": [ - "# Todo: Create a list of vars to estimate" + "# Build an experiment class to take advantage of new parmest interface\n", + "from pyomo.contrib.parmest.experiment import Experiment\n", + "\n", + "\n", + "class NRTLExperiment(Experiment):\n", + " \"\"\"Experiment class for parameter estimation of NRTL model using parmest\"\"\"\n", + "\n", + " def __init__(self, data, meas_error=None):\n", + " \"\"\"Initialize the NRTLExperiment class\n", + "\n", + " Args:\n", + " data: DataFrame containing the experimental data\n", + " meas_error: Measurement error for the data (optional)\n", + " \"\"\"\n", + " self.model = None\n", + " self.data = data\n", + " self.meas_error = meas_error\n", + "\n", + " def create_model(self):\n", + " \"\"\"Create the Pyomo model for the NRTL parameter estimation problem\"\"\"\n", + " self.model = NRTL_model(self.data)\n", + "\n", + " def label_model(self):\n", + " m = self.model\n", + "\n", + " # Add experiment outputs to the model for easier access\n", + " m.experiment_outputs = Suffix(direction=Suffix.LOCAL)\n", + " m.experiment_outputs.update(\n", + " [\n", + " (\n", + " m.fs.flash.liq_outlet.mole_frac_comp[0, \"benzene\"],\n", + " self.data[\"liq_benzene\"],\n", + " ),\n", + " (\n", + " m.fs.flash.vap_outlet.mole_frac_comp[0, \"benzene\"],\n", + " self.data[\"vap_benzene\"],\n", + " ),\n", + " ]\n", + " )\n", + "\n", + " m.measurement_error = Suffix(direction=Suffix.LOCAL)\n", + " m.measurement_error.update(\n", + " [\n", + " (m.fs.flash.liq_outlet.mole_frac_comp[0, \"benzene\"], self.meas_error),\n", + " (m.fs.flash.vap_outlet.mole_frac_comp[0, \"benzene\"], self.meas_error),\n", + " ]\n", + " )\n", + "\n", + " # Add unknown parameters to the model for easier access\n", + " m.unknown_parameters = Suffix(direction=Suffix.LOCAL)\n", + " m.unknown_parameters.update(\n", + " (k, value(k))\n", + " for k in [\n", + " m.fs.properties.tau[\"benzene\", \"toluene\"],\n", + " m.fs.properties.tau[\"toluene\", \"benzene\"],\n", + " ]\n", + " )\n", + "\n", + " def get_labeled_model(self):\n", + " \"\"\"Return the labeled model\"\"\"\n", + " if self.model is None:\n", + " self.create_model()\n", + " self.label_model()\n", + " return self.model" ] }, { @@ -256,9 +321,398 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
temperatureliq_benzenevap_benzene
0365.5000000.4809530.692110
1365.6176470.4624440.667699
2365.7352940.4779840.692441
3365.8529410.4405470.640336
4365.9705880.4274210.623328
5366.0882350.4427250.647796
6366.2058820.4343740.637691
7366.3235290.4446420.654933
8366.4411760.4271320.631229
9366.5588240.4463010.661743
10366.6764710.4380040.651591
11366.7941180.4253200.634814
12366.9117650.4394350.658047
13367.0294120.4356550.654539
14367.1470590.4013500.604987
15367.2647060.3978620.601703
16367.3823530.4158210.630930
17367.5000000.4206670.640380
18367.6176470.3916830.598214
19367.7352940.4049030.620432
20367.8529410.4095630.629626
21367.9705880.3894880.600722
22368.0000000.3967890.612483
23368.0882350.3981620.616106
24368.2058820.3623400.562505
25368.3235290.3869580.602680
26368.4411760.3636430.568210
27368.5588240.3681180.577072
28368.6764710.3840980.604078
29368.7941180.3536050.557925
30368.9117650.3464740.548445
31369.0294120.3507410.556996
32369.1470590.3623470.577286
33369.2647060.3625780.579519
34369.3823530.3407650.546411
35369.5000000.3374620.542857
36369.6176470.3557290.574083
37369.7352940.3486790.564513
38369.8529410.3381870.549284
39369.9705880.3243600.528514
40370.0882350.3107530.507964
41370.2058820.3110370.510055
42370.3235290.3112630.512055
43370.4411760.3080810.508437
44370.5588240.3082240.510293
45370.6764710.3181480.528399
46370.7941180.3083340.513728
47370.9117650.3179370.531410
48371.0294120.2891490.484824
49371.1470590.2986370.502318
\n", + "
" + ], + "text/plain": [ + " temperature liq_benzene vap_benzene\n", + "0 365.500000 0.480953 0.692110\n", + "1 365.617647 0.462444 0.667699\n", + "2 365.735294 0.477984 0.692441\n", + "3 365.852941 0.440547 0.640336\n", + "4 365.970588 0.427421 0.623328\n", + "5 366.088235 0.442725 0.647796\n", + "6 366.205882 0.434374 0.637691\n", + "7 366.323529 0.444642 0.654933\n", + "8 366.441176 0.427132 0.631229\n", + "9 366.558824 0.446301 0.661743\n", + "10 366.676471 0.438004 0.651591\n", + "11 366.794118 0.425320 0.634814\n", + "12 366.911765 0.439435 0.658047\n", + "13 367.029412 0.435655 0.654539\n", + "14 367.147059 0.401350 0.604987\n", + "15 367.264706 0.397862 0.601703\n", + "16 367.382353 0.415821 0.630930\n", + "17 367.500000 0.420667 0.640380\n", + "18 367.617647 0.391683 0.598214\n", + "19 367.735294 0.404903 0.620432\n", + "20 367.852941 0.409563 0.629626\n", + "21 367.970588 0.389488 0.600722\n", + "22 368.000000 0.396789 0.612483\n", + "23 368.088235 0.398162 0.616106\n", + "24 368.205882 0.362340 0.562505\n", + "25 368.323529 0.386958 0.602680\n", + "26 368.441176 0.363643 0.568210\n", + "27 368.558824 0.368118 0.577072\n", + "28 368.676471 0.384098 0.604078\n", + "29 368.794118 0.353605 0.557925\n", + "30 368.911765 0.346474 0.548445\n", + "31 369.029412 0.350741 0.556996\n", + "32 369.147059 0.362347 0.577286\n", + "33 369.264706 0.362578 0.579519\n", + "34 369.382353 0.340765 0.546411\n", + "35 369.500000 0.337462 0.542857\n", + "36 369.617647 0.355729 0.574083\n", + "37 369.735294 0.348679 0.564513\n", + "38 369.852941 0.338187 0.549284\n", + "39 369.970588 0.324360 0.528514\n", + "40 370.088235 0.310753 0.507964\n", + "41 370.205882 0.311037 0.510055\n", + "42 370.323529 0.311263 0.512055\n", + "43 370.441176 0.308081 0.508437\n", + "44 370.558824 0.308224 0.510293\n", + "45 370.676471 0.318148 0.528399\n", + "46 370.794118 0.308334 0.513728\n", + "47 370.911765 0.317937 0.531410\n", + "48 371.029412 0.289149 0.484824\n", + "49 371.147059 0.298637 0.502318" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "# Load data from csv\n", "data = pd.read_csv(\"BT_NRTL_dataset.csv\")\n", @@ -271,60 +725,198 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "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 mole fraction of benzene in the vapor and liquid phase between the model prediction and data. \n", - "\n", - "
\n", - "Inline Exercise:\n", - "Complete the following cell by adding an expression to compute the sum of square errors. \n", - "
" + "We define the `exp_list` by spliting the data into individual experiments, or data points." ] }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "exercise" - ] - }, - "outputs": [], - "source": [ - "# Create method to return an expression that computes the sum of squared error\n", - "def SSE(m, data):\n", - " # Todo: Add expression for computing the sum of squared errors in mole fraction of benzene in the liquid\n", - " # and vapor phase. For example, the squared error for the vapor phase is:\n", - " # (float(data[\"vap_benzene\"]) - m.fs.flash.vap_outlet.mole_frac_comp[0, \"benzene\"])**2\n", - "\n", - " return expr * 1e4" - ] - }, - { - "cell_type": "markdown", + "execution_count": 11, "metadata": {}, + "outputs": [], "source": [ - "
\n", - "Note:\n", - "Notice that we have scaled the expression up by a factor of 10000 as the SSE computed here will be an extremely small number given that we are using the difference in mole fraction in our expression. A well-scaled objective will help improve solve robustness when using IPOPT. \n", - "
\n" + "# Loop through the dataset and create an experiment for each row of data\n", + "exp_list = []\n", + "for i in range(data.shape[0]):\n", + " exp_list.append(NRTLExperiment(data.iloc[i]))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "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, dataset, list of variable names to estimate, and the SSE expression to the Estimator object. `tee=True` will print the solver output after solving the parameter estimation problem." + "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." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 10950\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 6600\n", + "\n", + "Total number of variables............................: 2952\n", + " variables with only lower bounds: 150\n", + " variables with lower and upper bounds: 600\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 2950\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 6.0671019e-03 5.63e+02 1.20e-08 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 9.0714942e-04 1.37e+03 1.61e+01 -1.0 1.37e+04 - 9.82e-01 1.00e+00h 1\n", + " 2 1.3219937e-03 1.17e+04 1.62e+01 -1.0 5.23e+03 - 3.41e-01 1.65e-01h 3\n", + " 3 1.3161671e-03 1.11e+04 4.02e+01 -1.0 3.96e+02 -4.0 8.19e-01 1.25e-01h 4\n", + " 4 1.3154170e-03 1.11e+04 4.32e+01 -1.0 3.47e+02 -4.5 9.90e-01 4.43e-02h 5\n", + " 5 9.4424343e-04 1.04e+04 4.05e+01 -1.0 1.16e+04 - 9.33e-01 5.61e-02h 5\n", + " 6 9.4571258e-04 1.11e+04 4.85e+01 -1.0 3.13e+02 -5.0 8.74e-01 1.25e-01h 4\n", + " 7 9.4862862e-04 1.11e+04 4.84e+01 -1.0 2.41e+03 -5.4 1.72e-01 1.50e-03h 8\n", + " 8 9.5448936e-04 1.10e+04 4.81e+01 -1.0 4.11e+02 -5.0 1.00e+00 1.97e-02h 6\n", + " 9 9.5650047e-04 1.10e+04 4.81e+01 -1.0 5.14e+02 -4.6 3.46e-01 5.24e-03h 7\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 9.5730419e-04 1.10e+04 4.81e+01 -1.0 9.78e+02 -4.2 4.40e-01 1.08e-03h 8\n", + " 11 9.5774182e-04 1.10e+04 4.84e+01 -1.0 2.76e+02 -3.7 2.91e-01 2.99e-03h 7\n", + " 12 9.4292855e-04 7.77e+04 4.09e+04 -1.0 5.38e+02 -2.4 5.48e-02 6.44e-02w 1\n", + " 13 2.4318219e-01 2.38e+07 4.22e+14 -1.0 1.28e+06 - 2.55e-02 3.49e-02w 1\n", + " 14 2.8902019e-01 1.64e+07 2.92e+14 -1.0 1.11e+05 -2.9 9.54e-01 3.01e-01w 1\n", + " 15 9.5768293e-04 1.10e+04 4.85e+01 -1.0 2.80e+05 -3.4 5.48e-02 2.52e-04h 8\n", + " 16 9.5769345e-04 1.10e+04 4.85e+01 -1.0 4.33e+02 -2.9 7.95e-02 1.91e-04h 9\n", + " 17 9.5763809e-04 1.10e+04 4.85e+01 -1.0 6.35e+02 -2.5 4.94e-02 2.08e-04h 9\n", + " 18 9.5734836e-04 1.10e+04 4.87e+01 -1.0 3.22e+02 -3.0 1.00e+00 1.22e-03h 8\n", + " 19 9.3628114e-04 1.09e+04 4.62e+01 -1.0 4.22e+02 -3.5 5.16e-01 5.87e-02h 5\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 7.1894543e-04 4.02e+03 4.95e+02 -1.0 3.49e+02 -3.9 1.00e+00 1.00e+00h 1\n", + " 21 6.7062834e-04 1.58e+02 2.21e+02 -1.0 1.78e+02 -4.4 1.00e+00 1.00e+00h 1\n", + " 22 6.6635123e-04 4.17e+01 1.12e+01 -1.0 2.44e+02 -4.9 1.00e+00 1.00e+00h 1\n", + " 23 6.6729070e-04 1.43e+00 9.69e-01 -1.0 1.08e+01 -5.4 1.00e+00 1.00e+00h 1\n", + " 24 6.6785681e-04 3.58e-01 5.25e-03 -1.7 6.65e+00 -5.8 1.00e+00 1.00e+00h 1\n", + " 25 6.2552355e-04 9.80e+02 6.48e-02 -3.8 7.92e+02 - 9.22e-01 1.00e+00h 1\n", + " 26 5.9105707e-04 8.13e+00 6.13e-04 -3.8 5.66e+02 - 1.00e+00 1.00e+00h 1\n", + " 27 6.1313801e-04 6.24e+01 8.08e-06 -3.8 1.70e+02 - 1.00e+00 1.00e+00h 1\n", + " 28 6.1208051e-04 3.58e-01 1.18e-08 -3.8 1.88e+00 - 1.00e+00 1.00e+00h 1\n", + " 29 5.9010560e-04 1.58e+01 1.00e-05 -5.7 1.08e+02 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30 5.9008319e-04 2.74e-02 7.90e-07 -5.7 7.54e-02 -6.3 1.00e+00 1.00e+00h 1\n", + " 31 5.3570104e-04 1.48e+04 8.70e-04 -5.7 1.81e+02 - 1.00e+00 1.00e+00h 1\n", + " 32 5.1618763e-04 6.29e+02 8.06e-05 -5.7 2.55e+02 - 1.00e+00 1.00e+00h 1\n", + " 33 5.5250565e-04 2.88e+01 2.58e-04 -5.7 1.81e+04 - 6.26e-01 6.25e-02h 5\n", + " 34 5.2209909e-04 2.88e+02 2.02e-04 -5.7 1.89e+03 - 1.00e+00 1.00e+00h 1\n", + " 35 5.0707798e-04 5.60e+01 2.02e-04 -5.7 2.93e+03 - 1.00e+00 1.00e+00h 1\n", + " 36 5.0765648e-04 7.87e+00 1.91e-05 -5.7 1.02e+02 - 1.00e+00 1.00e+00h 1\n", + " 37 5.0740606e-04 2.57e+00 1.88e-05 -5.7 6.96e+01 - 1.00e+00 1.00e+00h 1\n", + " 38 5.0764164e-04 2.55e+00 1.76e-05 -5.7 6.81e+01 - 1.00e+00 1.00e+00h 1\n", + " 39 5.0740672e-04 2.55e+00 1.88e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 40 5.0764162e-04 2.54e+00 1.76e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", + " 41 5.0740672e-04 2.55e+00 1.88e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", + " 42 5.0782847e-04 1.43e-01 1.83e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00H 1\n", + " 43 5.0751252e-04 1.58e-02 1.93e-05 -5.7 6.88e+01 - 1.00e+00 1.00e+00H 1\n", + " 44 5.0783218e-04 4.79e-03 1.85e-05 -5.7 6.92e+01 - 1.00e+00 1.00e+00H 1\n", + " 45 5.0751252e-04 1.60e-02 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", + " 46 5.0783222e-04 1.23e-04 1.85e-05 -5.7 6.92e+01 - 1.00e+00 1.00e+00H 1\n", + " 47 5.0751252e-04 1.60e-02 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", + " 48 5.0783216e-04 1.24e-04 1.85e-05 -5.7 6.92e+01 - 1.00e+00 1.00e+00H 1\n", + " 49 5.0751765e-04 3.20e-03 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 50 5.0764151e-04 2.56e+00 1.77e-05 -5.7 6.93e+01 - 1.00e+00 1.00e+00h 1\n", + " 51 5.0740671e-04 2.55e+00 1.88e-05 -5.7 6.81e+01 - 1.00e+00 1.00e+00h 1\n", + " 52 5.0764162e-04 2.54e+00 1.76e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", + " 53 5.0740672e-04 2.55e+00 1.88e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", + " 54 5.0764162e-04 2.54e+00 1.76e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", + " 55 5.0748886e-04 1.91e+00 8.64e-06 -5.7 6.80e+01 - 1.00e+00 5.00e-01h 2\n", + " 56 5.0744550e-04 3.37e-01 1.64e-05 -5.7 2.54e+01 - 1.00e+00 1.00e+00h 1\n", + " 57 5.0763613e-04 1.82e+00 1.43e-05 -5.7 5.79e+01 - 1.00e+00 1.00e+00h 1\n", + " 58 5.0751252e-04 2.25e-02 1.93e-05 -5.7 6.65e+01 - 1.00e+00 1.00e+00H 1\n", + " 59 5.0783220e-04 1.23e-04 1.85e-05 -5.7 6.92e+01 - 1.00e+00 1.00e+00H 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 60 5.0751252e-04 1.60e-02 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", + " 61 5.0783207e-04 3.26e-04 1.85e-05 -5.7 6.92e+01 - 1.00e+00 1.00e+00H 1\n", + " 62 5.0751786e-04 7.95e-05 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", + " 63 5.0754291e-04 6.40e-01 8.69e-06 -5.7 6.93e+01 - 1.00e+00 5.00e-01h 2\n", + " 64 5.0745167e-04 3.00e-01 1.61e-05 -5.7 2.35e+01 - 1.00e+00 1.00e+00h 1\n", + " 65 5.0763437e-04 1.71e+00 1.33e-05 -5.7 5.61e+01 - 1.00e+00 1.00e+00h 1\n", + " 66 5.0751762e-04 2.91e-03 1.93e-05 -5.7 6.60e+01 - 1.00e+00 1.00e+00H 1\n", + " 67 5.0752104e-04 1.62e-01 1.43e-05 -5.7 6.92e+01 - 1.00e+00 2.50e-01h 3\n", + " 68 5.0761295e-04 1.03e+00 2.18e-05 -5.7 4.35e+01 - 1.00e+00 1.00e+00h 1\n", + " 69 5.0751251e-04 2.38e-02 1.92e-05 -5.7 5.95e+01 - 1.00e+00 1.00e+00H 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 70 5.0783210e-04 3.29e-06 1.85e-05 -5.7 6.90e+01 - 1.00e+00 1.00e+00H 1\n", + " 71 5.0751786e-04 7.94e-05 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", + " 72 5.0754292e-04 6.40e-01 8.69e-06 -5.7 6.93e+01 - 1.00e+00 5.00e-01h 2\n", + " 73 5.0749299e-04 3.95e-01 1.21e-05 -5.7 2.35e+01 - 1.00e+00 5.00e-01h 2\n", + " 74 5.0755524e-04 1.36e-01 3.09e-05 -5.7 1.57e+01 - 1.00e+00 1.00e+00h 1\n", + " 75 5.0751308e-04 1.96e-02 1.80e-05 -5.7 3.30e+01 - 1.00e+00 1.00e+00H 1\n", + " 76 5.0754492e-04 5.62e-01 8.19e-06 -5.7 6.42e+01 - 1.00e+00 5.00e-01h 2\n", + " 77 5.0748301e-04 3.98e-01 1.25e-05 -5.7 2.93e+01 - 1.00e+00 5.00e-01h 2\n", + " 78 5.0756455e-04 2.42e-01 3.07e-05 -5.7 2.09e+01 - 1.00e+00 1.00e+00h 1\n", + " 79 5.0751710e-04 1.38e-03 1.87e-05 -5.7 3.98e+01 - 1.00e+00 1.00e+00H 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 80 5.0783077e-04 3.26e-06 1.84e-05 -5.7 6.70e+01 - 1.00e+00 1.00e+00H 1\n", + " 81 5.0726420e-04 1.24e+01 1.85e-05 -8.6 1.34e+02 - 9.93e-01 1.00e+00h 1\n", + " 82 5.0749897e-04 2.75e+00 2.53e-06 -8.6 6.93e+01 - 1.00e+00 1.00e+00h 1\n", + " 83 5.0749686e-04 3.64e-04 6.40e-10 -8.6 4.69e-02 - 1.00e+00 1.00e+00h 1\n", + " 84 5.0749686e-04 7.28e-11 2.51e-14 -8.6 6.86e-05 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 84\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 5.0749685809243843e-04 5.0749685809243843e-04\n", + "Dual infeasibility......: 2.5059195074646584e-14 2.5059195074646584e-14\n", + "Constraint violation....: 1.4104644499482425e-11 7.2759576141834259e-11\n", + "Complementarity.........: 2.5059035596800647e-09 2.5059035596800647e-09\n", + "Overall NLP error.......: 2.5059035596800647e-09 2.5059035596800647e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 260\n", + "Number of objective gradient evaluations = 85\n", + "Number of equality constraint evaluations = 260\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 85\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 84\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.338\n", + "Total CPU secs in NLP function evaluations = 0.092\n", + "\n", + "EXIT: Optimal Solution Found.\n" + ] + } + ], "source": [ - "# Initialize a parameter estimation object\n", - "pest = parmest.Estimator(NRTL_model, data, variable_name, SSE, tee=True)\n", + "import logging\n", + "\n", + "idaeslog.getIdaesLogger(\"core.property_meta\").setLevel(logging.ERROR)\n", "\n", - "# Run parameter estimation using all data\n", + "pest = parmest.Estimator(exp_list, obj_function=\"SSE\", tee=True)\n", "obj_value, parameters = pest.theta_est()" ] }, @@ -339,11 +931,23 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The SSE at the optimal solution is 0.000507\n", + "\n", + "The values for the parameters are as follows:\n", + "fs.properties.tau[benzene,toluene] = -0.8987454466579063\n", + "fs.properties.tau[toluene,benzene] = 1.410449514796474\n" + ] + } + ], "source": [ - "print(\"The SSE at the optimal solution is %0.6f\" % (obj_value * 1e-4))\n", + "print(\"The SSE at the optimal solution is %0.6f\" % (obj_value))\n", "print()\n", "print(\"The values for the parameters are as follows:\")\n", "for k, v in parameters.items():\n", @@ -369,14 +973,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Pyomo's `parmest` tool allows for bootstrapping where the parameter estimation is repeated over `n` samples with resampling from the original data set. Parameter estimation with bootstrap resampling can be used to identify confidence regions around each parameter estimate. This analysis can be slow given the increased number of model instances that need to be solved. Please refer to https://pyomo.readthedocs.io/en/stable/contributed_packages/parmest/driver.html for more details. \n", + "Pyomo's `parmest` tool allows for bootstrapping where the parameter estimation is repeated over `n` samples with resampling from the original data set. Parameter estimation with bootstrap resampling can be used to identify confidence regions around each parameter estimate. This analysis can be slow given the increased number of model instances that need to be solved. Please refer to https://pyomo.readthedocs.io/en/stable/explanation/analysis/parmest/covariance.html#bootstrapping for more details. \n", "\n", "For the example above, the bootstrapping can be run by uncommenting the code in the following cell:" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "metadata": {}, "outputs": [], "source": [ @@ -384,8 +988,7 @@ "# plot results along with confidence regions\n", "\n", "# Uncomment the following lines\n", - "\n", - "# bootstrap_theta = pest.theta_est_bootstrap(4)\n", + "# bootstrap_theta = pest.theta_est_bootstrap(4, seed=542)\n", "# display(bootstrap_theta)" ] } @@ -393,7 +996,7 @@ "metadata": { "celltoolbar": "Tags", "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "idaes-pse-and-examples-dev-py313-macmini", "language": "python", "name": "python3" }, @@ -407,9 +1010,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.12" + "version": "3.13.13" } }, "nbformat": 4, "nbformat_minor": 3 -} +} \ No newline at end of file diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_solution.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_solution.ipynb index d70ff27d..c1d70da8 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_solution.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_solution.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": { "tags": [ "header", @@ -16,7 +16,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", @@ -32,8 +32,8 @@ "# Parameter Estimation Using Flash Unit Model\n", "\n", "Author: Jaffer Ghouse \n", - "Maintainer: Andrew Lee \n", - "Updated: 2023-06-01 \n", + "Maintainer: Stephen Cini \n", + "Updated: 2026-06-11 \n", "\n", "In this module, we will be using Pyomo's `parmest` tool in conjunction with IDAES models for parameter estimation. We demonstrate these tools by estimating the parameters associated with the NRTL property model for a benzene-toluene mixture. The NRTL model has 2 sets of parameters: the non-randomness parameter (`alpha_ij`) and the binary interaction parameter (`tau_ij`), where `i` and `j` is the pure component species. In this example, we will be only estimate the binary interaction parameter (`tau_ij`) for a given dataset. 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 the NRTL property package. \n", "\n", @@ -45,7 +45,7 @@ "\n", "## Key links to documentation:\n", "* NRTL Model - https://idaes-pse.readthedocs.io/en/stable/reference_guides/model_libraries/generic/property_models/activity_coefficient.html\n", - "* parmest - https://pyomo.readthedocs.io/en/stable/contributed_packages/parmest/index.html\n" + "* parmest - https://pyomo.readthedocs.io/en/stable/explanation/analysis/parmest/index.html" ] }, { @@ -54,13 +54,13 @@ "source": [ "
\n", "Inline Exercise:\n", - "import `ConcreteModel` from Pyomo, `FlowsheetBlock` and `Flash` from IDAES. \n", + "import `ConcreteModel`, `value`, and `Suffix` from Pyomo, `FlowsheetBlock` and `Flash` from IDAES. \n", "
" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": { "tags": [ "exercise" @@ -68,7 +68,7 @@ }, "outputs": [], "source": [ - "# Todo: import ConcreteModel from pyomo.environ\n", + "# Todo: import ConcreteModel, value, and Suffix from pyomo.environ\n", "\n", "# Todo: import FlowsheetBlock from idaes.core\n", "\n", @@ -77,7 +77,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": { "tags": [ "solution" @@ -85,8 +85,8 @@ }, "outputs": [], "source": [ - "# Todo: import ConcreteModel from pyomo.environ\n", - "from pyomo.environ import ConcreteModel, value\n", + "# Todo: import ConcreteModel, value, and Suffix from pyomo.environ\n", + "from pyomo.environ import ConcreteModel, value, Suffix\n", "\n", "# Todo: import FlowsheetBlock from idaes.core\n", "from idaes.core import FlowsheetBlock\n", @@ -104,7 +104,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -123,7 +123,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -152,7 +152,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "metadata": { "tags": [ "exercise" @@ -200,7 +200,12 @@ " m.fs.flash.initialize(outlvl=idaeslog.INFO_LOW)\n", "\n", " # Fix at actual temperature\n", - " m.fs.flash.inlet.temperature.fix(float(data[\"temperature\"]))\n", + " if isinstance(data, dict) or isinstance(data, pd.Series):\n", + " m.fs.state_block.temperature.fix(float(data[\"temperature\"]))\n", + " elif isinstance(data, pd.DataFrame):\n", + " m.fs.state_block.temperature.fix(float(data.iloc[0][\"temperature\"]))\n", + " else:\n", + " raise ValueError(\"Unrecognized data type.\")\n", "\n", " # Set bounds on variables to be estimated\n", " m.fs.properties.tau[\"benzene\", \"toluene\"].setlb(-5)\n", @@ -215,7 +220,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "metadata": { "tags": [ "solution" @@ -267,7 +272,12 @@ " m.fs.flash.initialize(outlvl=idaeslog.INFO_LOW)\n", "\n", " # Fix at actual temperature\n", - " m.fs.flash.inlet.temperature.fix(float(data[\"temperature\"]))\n", + " if isinstance(data, dict) or isinstance(data, pd.Series):\n", + " m.fs.flash.inlet.temperature.fix(float(data[\"temperature\"]))\n", + " elif isinstance(data, pd.DataFrame):\n", + " m.fs.flash.inlet.temperature.fix(float(data.iloc[0][\"temperature\"]))\n", + " else:\n", + " raise ValueError(\"Unrecognized data type.\")\n", "\n", " # Set bounds on variables to be estimated\n", " m.fs.properties.tau[\"benzene\", \"toluene\"].setlb(-5)\n", @@ -293,55 +303,98 @@ "source": [ "In addition to providing a method to return an initialized model, the `parmest` tool needs the following:\n", "\n", - "* List of variable names to be estimated\n", - "* Dataset with multiple scenarios\n", - "* Expression to compute the sum of squared errors\n", - "\n" + "* Experiment class to set up and label model with suffixes\n", + "* Dataset with multiple scenarios - organized into an experiment list" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ + "Here we build an experiment class to label our model problem for parameter estimation. The labels are defined as a `Suffix`, and the main labels for our model are `experiment_outputs`, `unknown_parameters`. and `measurement_error`.\n", + "\n", + "For this problem, the error will be computed for the mole fraction of benzene in the vapor and liquid phase between the model prediction and data. The `experimental_outputs` will therefore be the mole fraction of benzene in the two phases.\n", + "\n", "In this example, we only estimate the binary interaction parameter (`tau_ij`). Given that this variable is usually indexed as `tau_ij = Var(component_list, component_list)`, there are 2*2=4 degrees of freedom. However, when i=j, the binary interaction parameter is 0. Therefore, in this problem, we estimate the binary interaction parameter for the following variables only:\n", "\n", "* fs.properties.tau['benzene', 'toluene']\n", "* fs.properties.tau['toluene', 'benzene']\n", "\n", - "
\n", - "Inline Exercise:\n", - "Create a list called `variable_name` with the above-mentioned variables declared as strings.\n", - "
" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "exercise" - ] - }, - "outputs": [], - "source": [ - "# Todo: Create a list of vars to estimate" + "As shown below, these model components are used as our `unknown_parameters`.\n", + "\n", + "We define `measurement_error` as none so parmest calculates the value internally based on the experimental outputs. Refer to https://pyomo.readthedocs.io/en/stable/explanation/analysis/parmest/driver.html for more information. " ] }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "solution" - ] - }, + "execution_count": 9, + "metadata": {}, "outputs": [], "source": [ - "# Todo: Create a list of vars to estimate\n", - "variable_name = [\n", - " \"fs.properties.tau['benzene', 'toluene']\",\n", - " \"fs.properties.tau['toluene', 'benzene']\",\n", - "]" + "# Build an experiment class to take advantage of new parmest interface\n", + "from pyomo.contrib.parmest.experiment import Experiment\n", + "\n", + "\n", + "class NRTLExperiment(Experiment):\n", + " \"\"\"Experiment class for parameter estimation of NRTL model using parmest\"\"\"\n", + "\n", + " def __init__(self, data, meas_error=None):\n", + " \"\"\"Initialize the NRTLExperiment class\n", + "\n", + " Args:\n", + " data: DataFrame containing the experimental data\n", + " meas_error: Measurement error for the data (optional)\n", + " \"\"\"\n", + " self.model = None\n", + " self.data = data\n", + " self.meas_error = meas_error\n", + "\n", + " def create_model(self):\n", + " \"\"\"Create the Pyomo model for the NRTL parameter estimation problem\"\"\"\n", + " self.model = NRTL_model(self.data)\n", + "\n", + " def label_model(self):\n", + " m = self.model\n", + "\n", + " # Add experiment outputs to the model for easier access\n", + " m.experiment_outputs = Suffix(direction=Suffix.LOCAL)\n", + " m.experiment_outputs.update(\n", + " [\n", + " (\n", + " m.fs.flash.liq_outlet.mole_frac_comp[0, \"benzene\"],\n", + " self.data[\"liq_benzene\"],\n", + " ),\n", + " (\n", + " m.fs.flash.vap_outlet.mole_frac_comp[0, \"benzene\"],\n", + " self.data[\"vap_benzene\"],\n", + " ),\n", + " ]\n", + " )\n", + "\n", + " m.measurement_error = Suffix(direction=Suffix.LOCAL)\n", + " m.measurement_error.update(\n", + " [\n", + " (m.fs.flash.liq_outlet.mole_frac_comp[0, \"benzene\"], self.meas_error),\n", + " (m.fs.flash.vap_outlet.mole_frac_comp[0, \"benzene\"], self.meas_error),\n", + " ]\n", + " )\n", + "\n", + " # Add unknown parameters to the model for easier access\n", + " m.unknown_parameters = Suffix(direction=Suffix.LOCAL)\n", + " m.unknown_parameters.update(\n", + " (k, value(k))\n", + " for k in [\n", + " m.fs.properties.tau[\"benzene\", \"toluene\"],\n", + " m.fs.properties.tau[\"toluene\", \"benzene\"],\n", + " ]\n", + " )\n", + "\n", + " def get_labeled_model(self):\n", + " \"\"\"Return the labeled model\"\"\"\n", + " if self.model is None:\n", + " self.create_model()\n", + " self.label_model()\n", + " return self.model" ] }, { @@ -360,9 +413,398 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
temperatureliq_benzenevap_benzene
0365.5000000.4809530.692110
1365.6176470.4624440.667699
2365.7352940.4779840.692441
3365.8529410.4405470.640336
4365.9705880.4274210.623328
5366.0882350.4427250.647796
6366.2058820.4343740.637691
7366.3235290.4446420.654933
8366.4411760.4271320.631229
9366.5588240.4463010.661743
10366.6764710.4380040.651591
11366.7941180.4253200.634814
12366.9117650.4394350.658047
13367.0294120.4356550.654539
14367.1470590.4013500.604987
15367.2647060.3978620.601703
16367.3823530.4158210.630930
17367.5000000.4206670.640380
18367.6176470.3916830.598214
19367.7352940.4049030.620432
20367.8529410.4095630.629626
21367.9705880.3894880.600722
22368.0000000.3967890.612483
23368.0882350.3981620.616106
24368.2058820.3623400.562505
25368.3235290.3869580.602680
26368.4411760.3636430.568210
27368.5588240.3681180.577072
28368.6764710.3840980.604078
29368.7941180.3536050.557925
30368.9117650.3464740.548445
31369.0294120.3507410.556996
32369.1470590.3623470.577286
33369.2647060.3625780.579519
34369.3823530.3407650.546411
35369.5000000.3374620.542857
36369.6176470.3557290.574083
37369.7352940.3486790.564513
38369.8529410.3381870.549284
39369.9705880.3243600.528514
40370.0882350.3107530.507964
41370.2058820.3110370.510055
42370.3235290.3112630.512055
43370.4411760.3080810.508437
44370.5588240.3082240.510293
45370.6764710.3181480.528399
46370.7941180.3083340.513728
47370.9117650.3179370.531410
48371.0294120.2891490.484824
49371.1470590.2986370.502318
\n", + "
" + ], + "text/plain": [ + " temperature liq_benzene vap_benzene\n", + "0 365.500000 0.480953 0.692110\n", + "1 365.617647 0.462444 0.667699\n", + "2 365.735294 0.477984 0.692441\n", + "3 365.852941 0.440547 0.640336\n", + "4 365.970588 0.427421 0.623328\n", + "5 366.088235 0.442725 0.647796\n", + "6 366.205882 0.434374 0.637691\n", + "7 366.323529 0.444642 0.654933\n", + "8 366.441176 0.427132 0.631229\n", + "9 366.558824 0.446301 0.661743\n", + "10 366.676471 0.438004 0.651591\n", + "11 366.794118 0.425320 0.634814\n", + "12 366.911765 0.439435 0.658047\n", + "13 367.029412 0.435655 0.654539\n", + "14 367.147059 0.401350 0.604987\n", + "15 367.264706 0.397862 0.601703\n", + "16 367.382353 0.415821 0.630930\n", + "17 367.500000 0.420667 0.640380\n", + "18 367.617647 0.391683 0.598214\n", + "19 367.735294 0.404903 0.620432\n", + "20 367.852941 0.409563 0.629626\n", + "21 367.970588 0.389488 0.600722\n", + "22 368.000000 0.396789 0.612483\n", + "23 368.088235 0.398162 0.616106\n", + "24 368.205882 0.362340 0.562505\n", + "25 368.323529 0.386958 0.602680\n", + "26 368.441176 0.363643 0.568210\n", + "27 368.558824 0.368118 0.577072\n", + "28 368.676471 0.384098 0.604078\n", + "29 368.794118 0.353605 0.557925\n", + "30 368.911765 0.346474 0.548445\n", + "31 369.029412 0.350741 0.556996\n", + "32 369.147059 0.362347 0.577286\n", + "33 369.264706 0.362578 0.579519\n", + "34 369.382353 0.340765 0.546411\n", + "35 369.500000 0.337462 0.542857\n", + "36 369.617647 0.355729 0.574083\n", + "37 369.735294 0.348679 0.564513\n", + "38 369.852941 0.338187 0.549284\n", + "39 369.970588 0.324360 0.528514\n", + "40 370.088235 0.310753 0.507964\n", + "41 370.205882 0.311037 0.510055\n", + "42 370.323529 0.311263 0.512055\n", + "43 370.441176 0.308081 0.508437\n", + "44 370.558824 0.308224 0.510293\n", + "45 370.676471 0.318148 0.528399\n", + "46 370.794118 0.308334 0.513728\n", + "47 370.911765 0.317937 0.531410\n", + "48 371.029412 0.289149 0.484824\n", + "49 371.147059 0.298637 0.502318" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "# Load data from csv\n", "data = pd.read_csv(\"BT_NRTL_dataset.csv\")\n", @@ -375,83 +817,198 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "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 mole fraction of benzene in the vapor and liquid phase between the model prediction and data. \n", - "\n", - "
\n", - "Inline Exercise:\n", - "Complete the following cell by adding an expression to compute the sum of square errors. \n", - "
" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "exercise" - ] - }, - "outputs": [], - "source": [ - "# Create method to return an expression that computes the sum of squared error\n", - "def SSE(m, data):\n", - " # Todo: Add expression for computing the sum of squared errors in mole fraction of benzene in the liquid\n", - " # and vapor phase. For example, the squared error for the vapor phase is:\n", - " # (float(data[\"vap_benzene\"]) - m.fs.flash.vap_outlet.mole_frac_comp[0, \"benzene\"])**2\n", - "\n", - " return expr * 1e4" + "We define the `exp_list` by spliting the data into individual experiments, or data points." ] }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "solution" - ] - }, - "outputs": [], - "source": [ - "# Create method to return an expression that computes the sum of squared error\n", - "def SSE(m, data):\n", - " # Todo: Add expression for computing the sum of squared errors in mole fraction of benzene in the liquid\n", - " # and vapor phase. For example, the squared error for the vapor phase is:\n", - " # (float(data[\"vap_benzene\"]) - m.fs.flash.vap_outlet.mole_frac_comp[0, \"benzene\"])**2\n", - " expr = (\n", - " float(data[\"vap_benzene\"]) - m.fs.flash.vap_outlet.mole_frac_comp[0, \"benzene\"]\n", - " ) ** 2 + (\n", - " float(data[\"liq_benzene\"]) - m.fs.flash.liq_outlet.mole_frac_comp[0, \"benzene\"]\n", - " ) ** 2\n", - " return expr * 1e4" - ] - }, - { - "cell_type": "markdown", + "execution_count": 11, "metadata": {}, + "outputs": [], "source": [ - "
\n", - "Note:\n", - "Notice that we have scaled the expression up by a factor of 10000 as the SSE computed here will be an extremely small number given that we are using the difference in mole fraction in our expression. A well-scaled objective will help improve solve robustness when using IPOPT. \n", - "
\n" + "# Loop through the dataset and create an experiment for each row of data\n", + "exp_list = []\n", + "for i in range(data.shape[0]):\n", + " exp_list.append(NRTLExperiment(data.iloc[i]))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "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, dataset, list of variable names to estimate, and the SSE expression to the Estimator object. `tee=True` will print the solver output after solving the parameter estimation problem." + "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." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 10950\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 6600\n", + "\n", + "Total number of variables............................: 2952\n", + " variables with only lower bounds: 150\n", + " variables with lower and upper bounds: 600\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 2950\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 6.0671019e-03 5.63e+02 1.20e-08 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 9.0714942e-04 1.37e+03 1.61e+01 -1.0 1.37e+04 - 9.82e-01 1.00e+00h 1\n", + " 2 1.3219937e-03 1.17e+04 1.62e+01 -1.0 5.23e+03 - 3.41e-01 1.65e-01h 3\n", + " 3 1.3161671e-03 1.11e+04 4.02e+01 -1.0 3.96e+02 -4.0 8.19e-01 1.25e-01h 4\n", + " 4 1.3154170e-03 1.11e+04 4.32e+01 -1.0 3.47e+02 -4.5 9.90e-01 4.43e-02h 5\n", + " 5 9.4424343e-04 1.04e+04 4.05e+01 -1.0 1.16e+04 - 9.33e-01 5.61e-02h 5\n", + " 6 9.4571258e-04 1.11e+04 4.85e+01 -1.0 3.13e+02 -5.0 8.74e-01 1.25e-01h 4\n", + " 7 9.4862862e-04 1.11e+04 4.84e+01 -1.0 2.41e+03 -5.4 1.72e-01 1.50e-03h 8\n", + " 8 9.5448936e-04 1.10e+04 4.81e+01 -1.0 4.11e+02 -5.0 1.00e+00 1.97e-02h 6\n", + " 9 9.5650047e-04 1.10e+04 4.81e+01 -1.0 5.14e+02 -4.6 3.46e-01 5.24e-03h 7\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 9.5730419e-04 1.10e+04 4.81e+01 -1.0 9.78e+02 -4.2 4.40e-01 1.08e-03h 8\n", + " 11 9.5774182e-04 1.10e+04 4.84e+01 -1.0 2.76e+02 -3.7 2.91e-01 2.99e-03h 7\n", + " 12 9.4292855e-04 7.77e+04 4.09e+04 -1.0 5.38e+02 -2.4 5.48e-02 6.44e-02w 1\n", + " 13 2.4318219e-01 2.38e+07 4.22e+14 -1.0 1.28e+06 - 2.55e-02 3.49e-02w 1\n", + " 14 2.8902019e-01 1.64e+07 2.92e+14 -1.0 1.11e+05 -2.9 9.54e-01 3.01e-01w 1\n", + " 15 9.5768293e-04 1.10e+04 4.85e+01 -1.0 2.80e+05 -3.4 5.48e-02 2.52e-04h 8\n", + " 16 9.5769345e-04 1.10e+04 4.85e+01 -1.0 4.33e+02 -2.9 7.95e-02 1.91e-04h 9\n", + " 17 9.5763809e-04 1.10e+04 4.85e+01 -1.0 6.35e+02 -2.5 4.94e-02 2.08e-04h 9\n", + " 18 9.5734836e-04 1.10e+04 4.87e+01 -1.0 3.22e+02 -3.0 1.00e+00 1.22e-03h 8\n", + " 19 9.3628114e-04 1.09e+04 4.62e+01 -1.0 4.22e+02 -3.5 5.16e-01 5.87e-02h 5\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 7.1894543e-04 4.02e+03 4.95e+02 -1.0 3.49e+02 -3.9 1.00e+00 1.00e+00h 1\n", + " 21 6.7062834e-04 1.58e+02 2.21e+02 -1.0 1.78e+02 -4.4 1.00e+00 1.00e+00h 1\n", + " 22 6.6635123e-04 4.17e+01 1.12e+01 -1.0 2.44e+02 -4.9 1.00e+00 1.00e+00h 1\n", + " 23 6.6729070e-04 1.43e+00 9.69e-01 -1.0 1.08e+01 -5.4 1.00e+00 1.00e+00h 1\n", + " 24 6.6785681e-04 3.58e-01 5.25e-03 -1.7 6.65e+00 -5.8 1.00e+00 1.00e+00h 1\n", + " 25 6.2552355e-04 9.80e+02 6.48e-02 -3.8 7.92e+02 - 9.22e-01 1.00e+00h 1\n", + " 26 5.9105707e-04 8.13e+00 6.13e-04 -3.8 5.66e+02 - 1.00e+00 1.00e+00h 1\n", + " 27 6.1313801e-04 6.24e+01 8.08e-06 -3.8 1.70e+02 - 1.00e+00 1.00e+00h 1\n", + " 28 6.1208051e-04 3.58e-01 1.18e-08 -3.8 1.88e+00 - 1.00e+00 1.00e+00h 1\n", + " 29 5.9010560e-04 1.58e+01 1.00e-05 -5.7 1.08e+02 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30 5.9008319e-04 2.74e-02 7.90e-07 -5.7 7.54e-02 -6.3 1.00e+00 1.00e+00h 1\n", + " 31 5.3570104e-04 1.48e+04 8.70e-04 -5.7 1.81e+02 - 1.00e+00 1.00e+00h 1\n", + " 32 5.1618763e-04 6.29e+02 8.06e-05 -5.7 2.55e+02 - 1.00e+00 1.00e+00h 1\n", + " 33 5.5250565e-04 2.88e+01 2.58e-04 -5.7 1.81e+04 - 6.26e-01 6.25e-02h 5\n", + " 34 5.2209909e-04 2.88e+02 2.02e-04 -5.7 1.89e+03 - 1.00e+00 1.00e+00h 1\n", + " 35 5.0707798e-04 5.60e+01 2.02e-04 -5.7 2.93e+03 - 1.00e+00 1.00e+00h 1\n", + " 36 5.0765648e-04 7.87e+00 1.91e-05 -5.7 1.02e+02 - 1.00e+00 1.00e+00h 1\n", + " 37 5.0740606e-04 2.57e+00 1.88e-05 -5.7 6.96e+01 - 1.00e+00 1.00e+00h 1\n", + " 38 5.0764164e-04 2.55e+00 1.76e-05 -5.7 6.81e+01 - 1.00e+00 1.00e+00h 1\n", + " 39 5.0740672e-04 2.55e+00 1.88e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 40 5.0764162e-04 2.54e+00 1.76e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", + " 41 5.0740672e-04 2.55e+00 1.88e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", + " 42 5.0782847e-04 1.43e-01 1.83e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00H 1\n", + " 43 5.0751252e-04 1.58e-02 1.93e-05 -5.7 6.88e+01 - 1.00e+00 1.00e+00H 1\n", + " 44 5.0783218e-04 4.79e-03 1.85e-05 -5.7 6.92e+01 - 1.00e+00 1.00e+00H 1\n", + " 45 5.0751252e-04 1.60e-02 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", + " 46 5.0783222e-04 1.23e-04 1.85e-05 -5.7 6.92e+01 - 1.00e+00 1.00e+00H 1\n", + " 47 5.0751252e-04 1.60e-02 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", + " 48 5.0783216e-04 1.24e-04 1.85e-05 -5.7 6.92e+01 - 1.00e+00 1.00e+00H 1\n", + " 49 5.0751765e-04 3.20e-03 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 50 5.0764151e-04 2.56e+00 1.77e-05 -5.7 6.93e+01 - 1.00e+00 1.00e+00h 1\n", + " 51 5.0740671e-04 2.55e+00 1.88e-05 -5.7 6.81e+01 - 1.00e+00 1.00e+00h 1\n", + " 52 5.0764162e-04 2.54e+00 1.76e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", + " 53 5.0740672e-04 2.55e+00 1.88e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", + " 54 5.0764162e-04 2.54e+00 1.76e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", + " 55 5.0748886e-04 1.91e+00 8.64e-06 -5.7 6.80e+01 - 1.00e+00 5.00e-01h 2\n", + " 56 5.0744550e-04 3.37e-01 1.64e-05 -5.7 2.54e+01 - 1.00e+00 1.00e+00h 1\n", + " 57 5.0763613e-04 1.82e+00 1.43e-05 -5.7 5.79e+01 - 1.00e+00 1.00e+00h 1\n", + " 58 5.0751252e-04 2.25e-02 1.93e-05 -5.7 6.65e+01 - 1.00e+00 1.00e+00H 1\n", + " 59 5.0783220e-04 1.23e-04 1.85e-05 -5.7 6.92e+01 - 1.00e+00 1.00e+00H 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 60 5.0751252e-04 1.60e-02 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", + " 61 5.0783207e-04 3.26e-04 1.85e-05 -5.7 6.92e+01 - 1.00e+00 1.00e+00H 1\n", + " 62 5.0751786e-04 7.95e-05 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", + " 63 5.0754291e-04 6.40e-01 8.69e-06 -5.7 6.93e+01 - 1.00e+00 5.00e-01h 2\n", + " 64 5.0745167e-04 3.00e-01 1.61e-05 -5.7 2.35e+01 - 1.00e+00 1.00e+00h 1\n", + " 65 5.0763437e-04 1.71e+00 1.33e-05 -5.7 5.61e+01 - 1.00e+00 1.00e+00h 1\n", + " 66 5.0751762e-04 2.91e-03 1.93e-05 -5.7 6.60e+01 - 1.00e+00 1.00e+00H 1\n", + " 67 5.0752104e-04 1.62e-01 1.43e-05 -5.7 6.92e+01 - 1.00e+00 2.50e-01h 3\n", + " 68 5.0761295e-04 1.03e+00 2.18e-05 -5.7 4.35e+01 - 1.00e+00 1.00e+00h 1\n", + " 69 5.0751251e-04 2.38e-02 1.92e-05 -5.7 5.95e+01 - 1.00e+00 1.00e+00H 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 70 5.0783210e-04 3.29e-06 1.85e-05 -5.7 6.90e+01 - 1.00e+00 1.00e+00H 1\n", + " 71 5.0751786e-04 7.94e-05 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", + " 72 5.0754292e-04 6.40e-01 8.69e-06 -5.7 6.93e+01 - 1.00e+00 5.00e-01h 2\n", + " 73 5.0749299e-04 3.95e-01 1.21e-05 -5.7 2.35e+01 - 1.00e+00 5.00e-01h 2\n", + " 74 5.0755524e-04 1.36e-01 3.09e-05 -5.7 1.57e+01 - 1.00e+00 1.00e+00h 1\n", + " 75 5.0751308e-04 1.96e-02 1.80e-05 -5.7 3.30e+01 - 1.00e+00 1.00e+00H 1\n", + " 76 5.0754492e-04 5.62e-01 8.19e-06 -5.7 6.42e+01 - 1.00e+00 5.00e-01h 2\n", + " 77 5.0748301e-04 3.98e-01 1.25e-05 -5.7 2.93e+01 - 1.00e+00 5.00e-01h 2\n", + " 78 5.0756455e-04 2.42e-01 3.07e-05 -5.7 2.09e+01 - 1.00e+00 1.00e+00h 1\n", + " 79 5.0751710e-04 1.38e-03 1.87e-05 -5.7 3.98e+01 - 1.00e+00 1.00e+00H 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 80 5.0783077e-04 3.26e-06 1.84e-05 -5.7 6.70e+01 - 1.00e+00 1.00e+00H 1\n", + " 81 5.0726420e-04 1.24e+01 1.85e-05 -8.6 1.34e+02 - 9.93e-01 1.00e+00h 1\n", + " 82 5.0749897e-04 2.75e+00 2.53e-06 -8.6 6.93e+01 - 1.00e+00 1.00e+00h 1\n", + " 83 5.0749686e-04 3.64e-04 6.40e-10 -8.6 4.69e-02 - 1.00e+00 1.00e+00h 1\n", + " 84 5.0749686e-04 7.28e-11 2.51e-14 -8.6 6.86e-05 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 84\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 5.0749685809243843e-04 5.0749685809243843e-04\n", + "Dual infeasibility......: 2.5059195074646584e-14 2.5059195074646584e-14\n", + "Constraint violation....: 1.4104644499482425e-11 7.2759576141834259e-11\n", + "Complementarity.........: 2.5059035596800647e-09 2.5059035596800647e-09\n", + "Overall NLP error.......: 2.5059035596800647e-09 2.5059035596800647e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 260\n", + "Number of objective gradient evaluations = 85\n", + "Number of equality constraint evaluations = 260\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 85\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 84\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.338\n", + "Total CPU secs in NLP function evaluations = 0.092\n", + "\n", + "EXIT: Optimal Solution Found.\n" + ] + } + ], "source": [ - "# Initialize a parameter estimation object\n", - "pest = parmest.Estimator(NRTL_model, data, variable_name, SSE, tee=True)\n", + "import logging\n", + "\n", + "idaeslog.getIdaesLogger(\"core.property_meta\").setLevel(logging.ERROR)\n", "\n", - "# Run parameter estimation using all data\n", + "pest = parmest.Estimator(exp_list, obj_function=\"SSE\", tee=True)\n", "obj_value, parameters = pest.theta_est()" ] }, @@ -466,11 +1023,23 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The SSE at the optimal solution is 0.000507\n", + "\n", + "The values for the parameters are as follows:\n", + "fs.properties.tau[benzene,toluene] = -0.8987454466579063\n", + "fs.properties.tau[toluene,benzene] = 1.410449514796474\n" + ] + } + ], "source": [ - "print(\"The SSE at the optimal solution is %0.6f\" % (obj_value * 1e-4))\n", + "print(\"The SSE at the optimal solution is %0.6f\" % (obj_value))\n", "print()\n", "print(\"The values for the parameters are as follows:\")\n", "for k, v in parameters.items():\n", @@ -496,14 +1065,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Pyomo's `parmest` tool allows for bootstrapping where the parameter estimation is repeated over `n` samples with resampling from the original data set. Parameter estimation with bootstrap resampling can be used to identify confidence regions around each parameter estimate. This analysis can be slow given the increased number of model instances that need to be solved. Please refer to https://pyomo.readthedocs.io/en/stable/contributed_packages/parmest/driver.html for more details. \n", + "Pyomo's `parmest` tool allows for bootstrapping where the parameter estimation is repeated over `n` samples with resampling from the original data set. Parameter estimation with bootstrap resampling can be used to identify confidence regions around each parameter estimate. This analysis can be slow given the increased number of model instances that need to be solved. Please refer to https://pyomo.readthedocs.io/en/stable/explanation/analysis/parmest/covariance.html#bootstrapping for more details. \n", "\n", "For the example above, the bootstrapping can be run by uncommenting the code in the following cell:" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "metadata": {}, "outputs": [], "source": [ @@ -511,8 +1080,7 @@ "# plot results along with confidence regions\n", "\n", "# Uncomment the following lines\n", - "\n", - "# bootstrap_theta = pest.theta_est_bootstrap(4)\n", + "# bootstrap_theta = pest.theta_est_bootstrap(4, seed=542)\n", "# display(bootstrap_theta)" ] } @@ -520,7 +1088,7 @@ "metadata": { "celltoolbar": "Tags", "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "idaes-pse-and-examples-dev-py313-macmini", "language": "python", "name": "python3" }, @@ -534,9 +1102,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.12" + "version": "3.13.13" } }, "nbformat": 4, "nbformat_minor": 3 -} +} \ No newline at end of file diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_test.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_test.ipynb index 7add77ff..c5243ffb 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_test.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_test.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": { "tags": [ "header", @@ -16,7 +16,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", @@ -32,8 +32,8 @@ "# Parameter Estimation Using Flash Unit Model\n", "\n", "Author: Jaffer Ghouse \n", - "Maintainer: Andrew Lee \n", - "Updated: 2023-06-01 \n", + "Maintainer: Stephen Cini \n", + "Updated: 2026-06-11 \n", "\n", "In this module, we will be using Pyomo's `parmest` tool in conjunction with IDAES models for parameter estimation. We demonstrate these tools by estimating the parameters associated with the NRTL property model for a benzene-toluene mixture. The NRTL model has 2 sets of parameters: the non-randomness parameter (`alpha_ij`) and the binary interaction parameter (`tau_ij`), where `i` and `j` is the pure component species. In this example, we will be only estimate the binary interaction parameter (`tau_ij`) for a given dataset. 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 the NRTL property package. \n", "\n", @@ -45,7 +45,7 @@ "\n", "## Key links to documentation:\n", "* NRTL Model - https://idaes-pse.readthedocs.io/en/stable/reference_guides/model_libraries/generic/property_models/activity_coefficient.html\n", - "* parmest - https://pyomo.readthedocs.io/en/stable/contributed_packages/parmest/index.html\n" + "* parmest - https://pyomo.readthedocs.io/en/stable/explanation/analysis/parmest/index.html" ] }, { @@ -54,13 +54,13 @@ "source": [ "
\n", "Inline Exercise:\n", - "import `ConcreteModel` from Pyomo, `FlowsheetBlock` and `Flash` from IDAES. \n", + "import `ConcreteModel`, `value`, and `Suffix` from Pyomo, `FlowsheetBlock` and `Flash` from IDAES. \n", "
" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": { "tags": [ "solution" @@ -68,8 +68,8 @@ }, "outputs": [], "source": [ - "# Todo: import ConcreteModel from pyomo.environ\n", - "from pyomo.environ import ConcreteModel, value\n", + "# Todo: import ConcreteModel, value, and Suffix from pyomo.environ\n", + "from pyomo.environ import ConcreteModel, value, Suffix\n", "\n", "# Todo: import FlowsheetBlock from idaes.core\n", "from idaes.core import FlowsheetBlock\n", @@ -87,7 +87,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -106,7 +106,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -135,7 +135,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "metadata": { "tags": [ "solution" @@ -187,7 +187,12 @@ " m.fs.flash.initialize(outlvl=idaeslog.INFO_LOW)\n", "\n", " # Fix at actual temperature\n", - " m.fs.flash.inlet.temperature.fix(float(data[\"temperature\"]))\n", + " if isinstance(data, dict) or isinstance(data, pd.Series):\n", + " m.fs.flash.inlet.temperature.fix(float(data[\"temperature\"]))\n", + " elif isinstance(data, pd.DataFrame):\n", + " m.fs.flash.inlet.temperature.fix(float(data.iloc[0][\"temperature\"]))\n", + " else:\n", + " raise ValueError(\"Unrecognized data type.\")\n", "\n", " # Set bounds on variables to be estimated\n", " m.fs.properties.tau[\"benzene\", \"toluene\"].setlb(-5)\n", @@ -202,7 +207,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": { "tags": [ "testing" @@ -250,42 +255,98 @@ "source": [ "In addition to providing a method to return an initialized model, the `parmest` tool needs the following:\n", "\n", - "* List of variable names to be estimated\n", - "* Dataset with multiple scenarios\n", - "* Expression to compute the sum of squared errors\n", - "\n" + "* Experiment class to set up and label model with suffixes\n", + "* Dataset with multiple scenarios - organized into an experiment list" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ + "Here we build an experiment class to label our model problem for parameter estimation. The labels are defined as a `Suffix`, and the main labels for our model are `experiment_outputs`, `unknown_parameters`. and `measurement_error`.\n", + "\n", + "For this problem, the error will be computed for the mole fraction of benzene in the vapor and liquid phase between the model prediction and data. The `experimental_outputs` will therefore be the mole fraction of benzene in the two phases.\n", + "\n", "In this example, we only estimate the binary interaction parameter (`tau_ij`). Given that this variable is usually indexed as `tau_ij = Var(component_list, component_list)`, there are 2*2=4 degrees of freedom. However, when i=j, the binary interaction parameter is 0. Therefore, in this problem, we estimate the binary interaction parameter for the following variables only:\n", "\n", "* fs.properties.tau['benzene', 'toluene']\n", "* fs.properties.tau['toluene', 'benzene']\n", "\n", - "
\n", - "Inline Exercise:\n", - "Create a list called `variable_name` with the above-mentioned variables declared as strings.\n", - "
" + "As shown below, these model components are used as our `unknown_parameters`.\n", + "\n", + "We define `measurement_error` as none so parmest calculates the value internally based on the experimental outputs. Refer to https://pyomo.readthedocs.io/en/stable/explanation/analysis/parmest/driver.html for more information. " ] }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "solution" - ] - }, + "execution_count": 9, + "metadata": {}, "outputs": [], "source": [ - "# Todo: Create a list of vars to estimate\n", - "variable_name = [\n", - " \"fs.properties.tau['benzene', 'toluene']\",\n", - " \"fs.properties.tau['toluene', 'benzene']\",\n", - "]" + "# Build an experiment class to take advantage of new parmest interface\n", + "from pyomo.contrib.parmest.experiment import Experiment\n", + "\n", + "\n", + "class NRTLExperiment(Experiment):\n", + " \"\"\"Experiment class for parameter estimation of NRTL model using parmest\"\"\"\n", + "\n", + " def __init__(self, data, meas_error=None):\n", + " \"\"\"Initialize the NRTLExperiment class\n", + "\n", + " Args:\n", + " data: DataFrame containing the experimental data\n", + " meas_error: Measurement error for the data (optional)\n", + " \"\"\"\n", + " self.model = None\n", + " self.data = data\n", + " self.meas_error = meas_error\n", + "\n", + " def create_model(self):\n", + " \"\"\"Create the Pyomo model for the NRTL parameter estimation problem\"\"\"\n", + " self.model = NRTL_model(self.data)\n", + "\n", + " def label_model(self):\n", + " m = self.model\n", + "\n", + " # Add experiment outputs to the model for easier access\n", + " m.experiment_outputs = Suffix(direction=Suffix.LOCAL)\n", + " m.experiment_outputs.update(\n", + " [\n", + " (\n", + " m.fs.flash.liq_outlet.mole_frac_comp[0, \"benzene\"],\n", + " self.data[\"liq_benzene\"],\n", + " ),\n", + " (\n", + " m.fs.flash.vap_outlet.mole_frac_comp[0, \"benzene\"],\n", + " self.data[\"vap_benzene\"],\n", + " ),\n", + " ]\n", + " )\n", + "\n", + " m.measurement_error = Suffix(direction=Suffix.LOCAL)\n", + " m.measurement_error.update(\n", + " [\n", + " (m.fs.flash.liq_outlet.mole_frac_comp[0, \"benzene\"], self.meas_error),\n", + " (m.fs.flash.vap_outlet.mole_frac_comp[0, \"benzene\"], self.meas_error),\n", + " ]\n", + " )\n", + "\n", + " # Add unknown parameters to the model for easier access\n", + " m.unknown_parameters = Suffix(direction=Suffix.LOCAL)\n", + " m.unknown_parameters.update(\n", + " (k, value(k))\n", + " for k in [\n", + " m.fs.properties.tau[\"benzene\", \"toluene\"],\n", + " m.fs.properties.tau[\"toluene\", \"benzene\"],\n", + " ]\n", + " )\n", + "\n", + " def get_labeled_model(self):\n", + " \"\"\"Return the labeled model\"\"\"\n", + " if self.model is None:\n", + " self.create_model()\n", + " self.label_model()\n", + " return self.model" ] }, { @@ -304,9 +365,398 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
temperatureliq_benzenevap_benzene
0365.5000000.4809530.692110
1365.6176470.4624440.667699
2365.7352940.4779840.692441
3365.8529410.4405470.640336
4365.9705880.4274210.623328
5366.0882350.4427250.647796
6366.2058820.4343740.637691
7366.3235290.4446420.654933
8366.4411760.4271320.631229
9366.5588240.4463010.661743
10366.6764710.4380040.651591
11366.7941180.4253200.634814
12366.9117650.4394350.658047
13367.0294120.4356550.654539
14367.1470590.4013500.604987
15367.2647060.3978620.601703
16367.3823530.4158210.630930
17367.5000000.4206670.640380
18367.6176470.3916830.598214
19367.7352940.4049030.620432
20367.8529410.4095630.629626
21367.9705880.3894880.600722
22368.0000000.3967890.612483
23368.0882350.3981620.616106
24368.2058820.3623400.562505
25368.3235290.3869580.602680
26368.4411760.3636430.568210
27368.5588240.3681180.577072
28368.6764710.3840980.604078
29368.7941180.3536050.557925
30368.9117650.3464740.548445
31369.0294120.3507410.556996
32369.1470590.3623470.577286
33369.2647060.3625780.579519
34369.3823530.3407650.546411
35369.5000000.3374620.542857
36369.6176470.3557290.574083
37369.7352940.3486790.564513
38369.8529410.3381870.549284
39369.9705880.3243600.528514
40370.0882350.3107530.507964
41370.2058820.3110370.510055
42370.3235290.3112630.512055
43370.4411760.3080810.508437
44370.5588240.3082240.510293
45370.6764710.3181480.528399
46370.7941180.3083340.513728
47370.9117650.3179370.531410
48371.0294120.2891490.484824
49371.1470590.2986370.502318
\n", + "
" + ], + "text/plain": [ + " temperature liq_benzene vap_benzene\n", + "0 365.500000 0.480953 0.692110\n", + "1 365.617647 0.462444 0.667699\n", + "2 365.735294 0.477984 0.692441\n", + "3 365.852941 0.440547 0.640336\n", + "4 365.970588 0.427421 0.623328\n", + "5 366.088235 0.442725 0.647796\n", + "6 366.205882 0.434374 0.637691\n", + "7 366.323529 0.444642 0.654933\n", + "8 366.441176 0.427132 0.631229\n", + "9 366.558824 0.446301 0.661743\n", + "10 366.676471 0.438004 0.651591\n", + "11 366.794118 0.425320 0.634814\n", + "12 366.911765 0.439435 0.658047\n", + "13 367.029412 0.435655 0.654539\n", + "14 367.147059 0.401350 0.604987\n", + "15 367.264706 0.397862 0.601703\n", + "16 367.382353 0.415821 0.630930\n", + "17 367.500000 0.420667 0.640380\n", + "18 367.617647 0.391683 0.598214\n", + "19 367.735294 0.404903 0.620432\n", + "20 367.852941 0.409563 0.629626\n", + "21 367.970588 0.389488 0.600722\n", + "22 368.000000 0.396789 0.612483\n", + "23 368.088235 0.398162 0.616106\n", + "24 368.205882 0.362340 0.562505\n", + "25 368.323529 0.386958 0.602680\n", + "26 368.441176 0.363643 0.568210\n", + "27 368.558824 0.368118 0.577072\n", + "28 368.676471 0.384098 0.604078\n", + "29 368.794118 0.353605 0.557925\n", + "30 368.911765 0.346474 0.548445\n", + "31 369.029412 0.350741 0.556996\n", + "32 369.147059 0.362347 0.577286\n", + "33 369.264706 0.362578 0.579519\n", + "34 369.382353 0.340765 0.546411\n", + "35 369.500000 0.337462 0.542857\n", + "36 369.617647 0.355729 0.574083\n", + "37 369.735294 0.348679 0.564513\n", + "38 369.852941 0.338187 0.549284\n", + "39 369.970588 0.324360 0.528514\n", + "40 370.088235 0.310753 0.507964\n", + "41 370.205882 0.311037 0.510055\n", + "42 370.323529 0.311263 0.512055\n", + "43 370.441176 0.308081 0.508437\n", + "44 370.558824 0.308224 0.510293\n", + "45 370.676471 0.318148 0.528399\n", + "46 370.794118 0.308334 0.513728\n", + "47 370.911765 0.317937 0.531410\n", + "48 371.029412 0.289149 0.484824\n", + "49 371.147059 0.298637 0.502318" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "# Load data from csv\n", "data = pd.read_csv(\"BT_NRTL_dataset.csv\")\n", @@ -319,70 +769,204 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "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 mole fraction of benzene in the vapor and liquid phase between the model prediction and data. \n", - "\n", - "
\n", - "Inline Exercise:\n", - "Complete the following cell by adding an expression to compute the sum of square errors. \n", - "
" + "We define the `exp_list` by spliting the data into individual experiments, or data points." ] }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "solution" - ] - }, - "outputs": [], - "source": [ - "# Create method to return an expression that computes the sum of squared error\n", - "def SSE(m, data):\n", - " # Todo: Add expression for computing the sum of squared errors in mole fraction of benzene in the liquid\n", - " # and vapor phase. For example, the squared error for the vapor phase is:\n", - " # (float(data[\"vap_benzene\"]) - m.fs.flash.vap_outlet.mole_frac_comp[0, \"benzene\"])**2\n", - " expr = (\n", - " float(data[\"vap_benzene\"]) - m.fs.flash.vap_outlet.mole_frac_comp[0, \"benzene\"]\n", - " ) ** 2 + (\n", - " float(data[\"liq_benzene\"]) - m.fs.flash.liq_outlet.mole_frac_comp[0, \"benzene\"]\n", - " ) ** 2\n", - " return expr * 1e4" - ] - }, - { - "cell_type": "markdown", + "execution_count": 11, "metadata": {}, + "outputs": [], "source": [ - "
\n", - "Note:\n", - "Notice that we have scaled the expression up by a factor of 10000 as the SSE computed here will be an extremely small number given that we are using the difference in mole fraction in our expression. A well-scaled objective will help improve solve robustness when using IPOPT. \n", - "
\n" + "# Loop through the dataset and create an experiment for each row of data\n", + "exp_list = []\n", + "for i in range(data.shape[0]):\n", + " exp_list.append(NRTLExperiment(data.iloc[i]))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "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, dataset, list of variable names to estimate, and the SSE expression to the Estimator object. `tee=True` will print the solver output after solving the parameter estimation problem." + "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." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 10950\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 6600\n", + "\n", + "Total number of variables............................: 2952\n", + " variables with only lower bounds: 150\n", + " variables with lower and upper bounds: 600\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 2950\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 6.0671019e-03 5.63e+02 1.20e-08 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 9.0714942e-04 1.37e+03 1.61e+01 -1.0 1.37e+04 - 9.82e-01 1.00e+00h 1\n", + " 2 1.3219937e-03 1.17e+04 1.62e+01 -1.0 5.23e+03 - 3.41e-01 1.65e-01h 3\n", + " 3 1.3161671e-03 1.11e+04 4.02e+01 -1.0 3.96e+02 -4.0 8.19e-01 1.25e-01h 4\n", + " 4 1.3154170e-03 1.11e+04 4.32e+01 -1.0 3.47e+02 -4.5 9.90e-01 4.43e-02h 5\n", + " 5 9.4424343e-04 1.04e+04 4.05e+01 -1.0 1.16e+04 - 9.33e-01 5.61e-02h 5\n", + " 6 9.4571258e-04 1.11e+04 4.85e+01 -1.0 3.13e+02 -5.0 8.74e-01 1.25e-01h 4\n", + " 7 9.4862862e-04 1.11e+04 4.84e+01 -1.0 2.41e+03 -5.4 1.72e-01 1.50e-03h 8\n", + " 8 9.5448936e-04 1.10e+04 4.81e+01 -1.0 4.11e+02 -5.0 1.00e+00 1.97e-02h 6\n", + " 9 9.5650047e-04 1.10e+04 4.81e+01 -1.0 5.14e+02 -4.6 3.46e-01 5.24e-03h 7\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 9.5730419e-04 1.10e+04 4.81e+01 -1.0 9.78e+02 -4.2 4.40e-01 1.08e-03h 8\n", + " 11 9.5774182e-04 1.10e+04 4.84e+01 -1.0 2.76e+02 -3.7 2.91e-01 2.99e-03h 7\n", + " 12 9.4292855e-04 7.77e+04 4.09e+04 -1.0 5.38e+02 -2.4 5.48e-02 6.44e-02w 1\n", + " 13 2.4318219e-01 2.38e+07 4.22e+14 -1.0 1.28e+06 - 2.55e-02 3.49e-02w 1\n", + " 14 2.8902019e-01 1.64e+07 2.92e+14 -1.0 1.11e+05 -2.9 9.54e-01 3.01e-01w 1\n", + " 15 9.5768293e-04 1.10e+04 4.85e+01 -1.0 2.80e+05 -3.4 5.48e-02 2.52e-04h 8\n", + " 16 9.5769345e-04 1.10e+04 4.85e+01 -1.0 4.33e+02 -2.9 7.95e-02 1.91e-04h 9\n", + " 17 9.5763809e-04 1.10e+04 4.85e+01 -1.0 6.35e+02 -2.5 4.94e-02 2.08e-04h 9\n", + " 18 9.5734836e-04 1.10e+04 4.87e+01 -1.0 3.22e+02 -3.0 1.00e+00 1.22e-03h 8\n", + " 19 9.3628114e-04 1.09e+04 4.62e+01 -1.0 4.22e+02 -3.5 5.16e-01 5.87e-02h 5\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 7.1894543e-04 4.02e+03 4.95e+02 -1.0 3.49e+02 -3.9 1.00e+00 1.00e+00h 1\n", + " 21 6.7062834e-04 1.58e+02 2.21e+02 -1.0 1.78e+02 -4.4 1.00e+00 1.00e+00h 1\n", + " 22 6.6635123e-04 4.17e+01 1.12e+01 -1.0 2.44e+02 -4.9 1.00e+00 1.00e+00h 1\n", + " 23 6.6729070e-04 1.43e+00 9.69e-01 -1.0 1.08e+01 -5.4 1.00e+00 1.00e+00h 1\n", + " 24 6.6785681e-04 3.58e-01 5.25e-03 -1.7 6.65e+00 -5.8 1.00e+00 1.00e+00h 1\n", + " 25 6.2552355e-04 9.80e+02 6.48e-02 -3.8 7.92e+02 - 9.22e-01 1.00e+00h 1\n", + " 26 5.9105707e-04 8.13e+00 6.13e-04 -3.8 5.66e+02 - 1.00e+00 1.00e+00h 1\n", + " 27 6.1313801e-04 6.24e+01 8.08e-06 -3.8 1.70e+02 - 1.00e+00 1.00e+00h 1\n", + " 28 6.1208051e-04 3.58e-01 1.18e-08 -3.8 1.88e+00 - 1.00e+00 1.00e+00h 1\n", + " 29 5.9010560e-04 1.58e+01 1.00e-05 -5.7 1.08e+02 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30 5.9008319e-04 2.74e-02 7.90e-07 -5.7 7.54e-02 -6.3 1.00e+00 1.00e+00h 1\n", + " 31 5.3570104e-04 1.48e+04 8.70e-04 -5.7 1.81e+02 - 1.00e+00 1.00e+00h 1\n", + " 32 5.1618763e-04 6.29e+02 8.06e-05 -5.7 2.55e+02 - 1.00e+00 1.00e+00h 1\n", + " 33 5.5250565e-04 2.88e+01 2.58e-04 -5.7 1.81e+04 - 6.26e-01 6.25e-02h 5\n", + " 34 5.2209909e-04 2.88e+02 2.02e-04 -5.7 1.89e+03 - 1.00e+00 1.00e+00h 1\n", + " 35 5.0707798e-04 5.60e+01 2.02e-04 -5.7 2.93e+03 - 1.00e+00 1.00e+00h 1\n", + " 36 5.0765648e-04 7.87e+00 1.91e-05 -5.7 1.02e+02 - 1.00e+00 1.00e+00h 1\n", + " 37 5.0740606e-04 2.57e+00 1.88e-05 -5.7 6.96e+01 - 1.00e+00 1.00e+00h 1\n", + " 38 5.0764164e-04 2.55e+00 1.76e-05 -5.7 6.81e+01 - 1.00e+00 1.00e+00h 1\n", + " 39 5.0740672e-04 2.55e+00 1.88e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 40 5.0764162e-04 2.54e+00 1.76e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", + " 41 5.0740672e-04 2.55e+00 1.88e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", + " 42 5.0782847e-04 1.43e-01 1.83e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00H 1\n", + " 43 5.0751252e-04 1.58e-02 1.93e-05 -5.7 6.88e+01 - 1.00e+00 1.00e+00H 1\n", + " 44 5.0783218e-04 4.79e-03 1.85e-05 -5.7 6.92e+01 - 1.00e+00 1.00e+00H 1\n", + " 45 5.0751252e-04 1.60e-02 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", + " 46 5.0783222e-04 1.23e-04 1.85e-05 -5.7 6.92e+01 - 1.00e+00 1.00e+00H 1\n", + " 47 5.0751252e-04 1.60e-02 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", + " 48 5.0783216e-04 1.24e-04 1.85e-05 -5.7 6.92e+01 - 1.00e+00 1.00e+00H 1\n", + " 49 5.0751765e-04 3.20e-03 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 50 5.0764151e-04 2.56e+00 1.77e-05 -5.7 6.93e+01 - 1.00e+00 1.00e+00h 1\n", + " 51 5.0740671e-04 2.55e+00 1.88e-05 -5.7 6.81e+01 - 1.00e+00 1.00e+00h 1\n", + " 52 5.0764162e-04 2.54e+00 1.76e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", + " 53 5.0740672e-04 2.55e+00 1.88e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", + " 54 5.0764162e-04 2.54e+00 1.76e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", + " 55 5.0748886e-04 1.91e+00 8.64e-06 -5.7 6.80e+01 - 1.00e+00 5.00e-01h 2\n", + " 56 5.0744550e-04 3.37e-01 1.64e-05 -5.7 2.54e+01 - 1.00e+00 1.00e+00h 1\n", + " 57 5.0763613e-04 1.82e+00 1.43e-05 -5.7 5.79e+01 - 1.00e+00 1.00e+00h 1\n", + " 58 5.0751252e-04 2.25e-02 1.93e-05 -5.7 6.65e+01 - 1.00e+00 1.00e+00H 1\n", + " 59 5.0783220e-04 1.23e-04 1.85e-05 -5.7 6.92e+01 - 1.00e+00 1.00e+00H 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 60 5.0751252e-04 1.60e-02 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", + " 61 5.0783207e-04 3.26e-04 1.85e-05 -5.7 6.92e+01 - 1.00e+00 1.00e+00H 1\n", + " 62 5.0751786e-04 7.95e-05 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", + " 63 5.0754291e-04 6.40e-01 8.69e-06 -5.7 6.93e+01 - 1.00e+00 5.00e-01h 2\n", + " 64 5.0745167e-04 3.00e-01 1.61e-05 -5.7 2.35e+01 - 1.00e+00 1.00e+00h 1\n", + " 65 5.0763437e-04 1.71e+00 1.33e-05 -5.7 5.61e+01 - 1.00e+00 1.00e+00h 1\n", + " 66 5.0751762e-04 2.91e-03 1.93e-05 -5.7 6.60e+01 - 1.00e+00 1.00e+00H 1\n", + " 67 5.0752104e-04 1.62e-01 1.43e-05 -5.7 6.92e+01 - 1.00e+00 2.50e-01h 3\n", + " 68 5.0761295e-04 1.03e+00 2.18e-05 -5.7 4.35e+01 - 1.00e+00 1.00e+00h 1\n", + " 69 5.0751251e-04 2.38e-02 1.92e-05 -5.7 5.95e+01 - 1.00e+00 1.00e+00H 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 70 5.0783210e-04 3.29e-06 1.85e-05 -5.7 6.90e+01 - 1.00e+00 1.00e+00H 1\n", + " 71 5.0751786e-04 7.94e-05 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", + " 72 5.0754292e-04 6.40e-01 8.69e-06 -5.7 6.93e+01 - 1.00e+00 5.00e-01h 2\n", + " 73 5.0749299e-04 3.95e-01 1.21e-05 -5.7 2.35e+01 - 1.00e+00 5.00e-01h 2\n", + " 74 5.0755524e-04 1.36e-01 3.09e-05 -5.7 1.57e+01 - 1.00e+00 1.00e+00h 1\n", + " 75 5.0751308e-04 1.96e-02 1.80e-05 -5.7 3.30e+01 - 1.00e+00 1.00e+00H 1\n", + " 76 5.0754492e-04 5.62e-01 8.19e-06 -5.7 6.42e+01 - 1.00e+00 5.00e-01h 2\n", + " 77 5.0748301e-04 3.98e-01 1.25e-05 -5.7 2.93e+01 - 1.00e+00 5.00e-01h 2\n", + " 78 5.0756455e-04 2.42e-01 3.07e-05 -5.7 2.09e+01 - 1.00e+00 1.00e+00h 1\n", + " 79 5.0751710e-04 1.38e-03 1.87e-05 -5.7 3.98e+01 - 1.00e+00 1.00e+00H 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 80 5.0783077e-04 3.26e-06 1.84e-05 -5.7 6.70e+01 - 1.00e+00 1.00e+00H 1\n", + " 81 5.0726420e-04 1.24e+01 1.85e-05 -8.6 1.34e+02 - 9.93e-01 1.00e+00h 1\n", + " 82 5.0749897e-04 2.75e+00 2.53e-06 -8.6 6.93e+01 - 1.00e+00 1.00e+00h 1\n", + " 83 5.0749686e-04 3.64e-04 6.40e-10 -8.6 4.69e-02 - 1.00e+00 1.00e+00h 1\n", + " 84 5.0749686e-04 7.28e-11 2.51e-14 -8.6 6.86e-05 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 84\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 5.0749685809243843e-04 5.0749685809243843e-04\n", + "Dual infeasibility......: 2.5059195074646584e-14 2.5059195074646584e-14\n", + "Constraint violation....: 1.4104644499482425e-11 7.2759576141834259e-11\n", + "Complementarity.........: 2.5059035596800647e-09 2.5059035596800647e-09\n", + "Overall NLP error.......: 2.5059035596800647e-09 2.5059035596800647e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 260\n", + "Number of objective gradient evaluations = 85\n", + "Number of equality constraint evaluations = 260\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 85\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 84\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.338\n", + "Total CPU secs in NLP function evaluations = 0.092\n", + "\n", + "EXIT: Optimal Solution Found.\n" + ] + } + ], "source": [ - "# Initialize a parameter estimation object\n", - "pest = parmest.Estimator(NRTL_model, data, variable_name, SSE, tee=True)\n", + "import logging\n", + "\n", + "idaeslog.getIdaesLogger(\"core.property_meta\").setLevel(logging.ERROR)\n", "\n", - "# Run parameter estimation using all data\n", + "pest = parmest.Estimator(exp_list, obj_function=\"SSE\", tee=True)\n", "obj_value, parameters = pest.theta_est()" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "metadata": { "tags": [ "testing" @@ -391,7 +975,7 @@ "outputs": [], "source": [ "# Check for values of the parameter estimation problem\n", - "assert obj_value == pytest.approx(5.07496, abs=1e-1)\n", + "assert obj_value == pytest.approx(5.07496e-4, abs=1e-1)\n", "assert parameters[\"fs.properties.tau[benzene,toluene]\"] == pytest.approx(-0.89876, 1e-3)\n", "assert parameters[\"fs.properties.tau[toluene,benzene]\"] == pytest.approx(1.410486, 1e-3)" ] @@ -407,11 +991,23 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The SSE at the optimal solution is 0.000507\n", + "\n", + "The values for the parameters are as follows:\n", + "fs.properties.tau[benzene,toluene] = -0.8987454466579063\n", + "fs.properties.tau[toluene,benzene] = 1.410449514796474\n" + ] + } + ], "source": [ - "print(\"The SSE at the optimal solution is %0.6f\" % (obj_value * 1e-4))\n", + "print(\"The SSE at the optimal solution is %0.6f\" % (obj_value))\n", "print()\n", "print(\"The values for the parameters are as follows:\")\n", "for k, v in parameters.items():\n", @@ -437,14 +1033,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Pyomo's `parmest` tool allows for bootstrapping where the parameter estimation is repeated over `n` samples with resampling from the original data set. Parameter estimation with bootstrap resampling can be used to identify confidence regions around each parameter estimate. This analysis can be slow given the increased number of model instances that need to be solved. Please refer to https://pyomo.readthedocs.io/en/stable/contributed_packages/parmest/driver.html for more details. \n", + "Pyomo's `parmest` tool allows for bootstrapping where the parameter estimation is repeated over `n` samples with resampling from the original data set. Parameter estimation with bootstrap resampling can be used to identify confidence regions around each parameter estimate. This analysis can be slow given the increased number of model instances that need to be solved. Please refer to https://pyomo.readthedocs.io/en/stable/explanation/analysis/parmest/covariance.html#bootstrapping for more details. \n", "\n", "For the example above, the bootstrapping can be run by uncommenting the code in the following cell:" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "metadata": {}, "outputs": [], "source": [ @@ -452,8 +1048,7 @@ "# plot results along with confidence regions\n", "\n", "# Uncomment the following lines\n", - "\n", - "# bootstrap_theta = pest.theta_est_bootstrap(4)\n", + "# bootstrap_theta = pest.theta_est_bootstrap(4, seed=542)\n", "# display(bootstrap_theta)" ] } @@ -461,7 +1056,7 @@ "metadata": { "celltoolbar": "Tags", "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "idaes-pse-and-examples-dev-py313-macmini", "language": "python", "name": "python3" }, @@ -475,9 +1070,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.12" + "version": "3.13.13" } }, "nbformat": 4, "nbformat_minor": 3 -} +} \ No newline at end of file diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_usr.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_usr.ipynb index d70ff27d..c1d70da8 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_usr.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_usr.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": { "tags": [ "header", @@ -16,7 +16,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", @@ -32,8 +32,8 @@ "# Parameter Estimation Using Flash Unit Model\n", "\n", "Author: Jaffer Ghouse \n", - "Maintainer: Andrew Lee \n", - "Updated: 2023-06-01 \n", + "Maintainer: Stephen Cini \n", + "Updated: 2026-06-11 \n", "\n", "In this module, we will be using Pyomo's `parmest` tool in conjunction with IDAES models for parameter estimation. We demonstrate these tools by estimating the parameters associated with the NRTL property model for a benzene-toluene mixture. The NRTL model has 2 sets of parameters: the non-randomness parameter (`alpha_ij`) and the binary interaction parameter (`tau_ij`), where `i` and `j` is the pure component species. In this example, we will be only estimate the binary interaction parameter (`tau_ij`) for a given dataset. 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 the NRTL property package. \n", "\n", @@ -45,7 +45,7 @@ "\n", "## Key links to documentation:\n", "* NRTL Model - https://idaes-pse.readthedocs.io/en/stable/reference_guides/model_libraries/generic/property_models/activity_coefficient.html\n", - "* parmest - https://pyomo.readthedocs.io/en/stable/contributed_packages/parmest/index.html\n" + "* parmest - https://pyomo.readthedocs.io/en/stable/explanation/analysis/parmest/index.html" ] }, { @@ -54,13 +54,13 @@ "source": [ "
\n", "Inline Exercise:\n", - "import `ConcreteModel` from Pyomo, `FlowsheetBlock` and `Flash` from IDAES. \n", + "import `ConcreteModel`, `value`, and `Suffix` from Pyomo, `FlowsheetBlock` and `Flash` from IDAES. \n", "
" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": { "tags": [ "exercise" @@ -68,7 +68,7 @@ }, "outputs": [], "source": [ - "# Todo: import ConcreteModel from pyomo.environ\n", + "# Todo: import ConcreteModel, value, and Suffix from pyomo.environ\n", "\n", "# Todo: import FlowsheetBlock from idaes.core\n", "\n", @@ -77,7 +77,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": { "tags": [ "solution" @@ -85,8 +85,8 @@ }, "outputs": [], "source": [ - "# Todo: import ConcreteModel from pyomo.environ\n", - "from pyomo.environ import ConcreteModel, value\n", + "# Todo: import ConcreteModel, value, and Suffix from pyomo.environ\n", + "from pyomo.environ import ConcreteModel, value, Suffix\n", "\n", "# Todo: import FlowsheetBlock from idaes.core\n", "from idaes.core import FlowsheetBlock\n", @@ -104,7 +104,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -123,7 +123,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -152,7 +152,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "metadata": { "tags": [ "exercise" @@ -200,7 +200,12 @@ " m.fs.flash.initialize(outlvl=idaeslog.INFO_LOW)\n", "\n", " # Fix at actual temperature\n", - " m.fs.flash.inlet.temperature.fix(float(data[\"temperature\"]))\n", + " if isinstance(data, dict) or isinstance(data, pd.Series):\n", + " m.fs.state_block.temperature.fix(float(data[\"temperature\"]))\n", + " elif isinstance(data, pd.DataFrame):\n", + " m.fs.state_block.temperature.fix(float(data.iloc[0][\"temperature\"]))\n", + " else:\n", + " raise ValueError(\"Unrecognized data type.\")\n", "\n", " # Set bounds on variables to be estimated\n", " m.fs.properties.tau[\"benzene\", \"toluene\"].setlb(-5)\n", @@ -215,7 +220,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "metadata": { "tags": [ "solution" @@ -267,7 +272,12 @@ " m.fs.flash.initialize(outlvl=idaeslog.INFO_LOW)\n", "\n", " # Fix at actual temperature\n", - " m.fs.flash.inlet.temperature.fix(float(data[\"temperature\"]))\n", + " if isinstance(data, dict) or isinstance(data, pd.Series):\n", + " m.fs.flash.inlet.temperature.fix(float(data[\"temperature\"]))\n", + " elif isinstance(data, pd.DataFrame):\n", + " m.fs.flash.inlet.temperature.fix(float(data.iloc[0][\"temperature\"]))\n", + " else:\n", + " raise ValueError(\"Unrecognized data type.\")\n", "\n", " # Set bounds on variables to be estimated\n", " m.fs.properties.tau[\"benzene\", \"toluene\"].setlb(-5)\n", @@ -293,55 +303,98 @@ "source": [ "In addition to providing a method to return an initialized model, the `parmest` tool needs the following:\n", "\n", - "* List of variable names to be estimated\n", - "* Dataset with multiple scenarios\n", - "* Expression to compute the sum of squared errors\n", - "\n" + "* Experiment class to set up and label model with suffixes\n", + "* Dataset with multiple scenarios - organized into an experiment list" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ + "Here we build an experiment class to label our model problem for parameter estimation. The labels are defined as a `Suffix`, and the main labels for our model are `experiment_outputs`, `unknown_parameters`. and `measurement_error`.\n", + "\n", + "For this problem, the error will be computed for the mole fraction of benzene in the vapor and liquid phase between the model prediction and data. The `experimental_outputs` will therefore be the mole fraction of benzene in the two phases.\n", + "\n", "In this example, we only estimate the binary interaction parameter (`tau_ij`). Given that this variable is usually indexed as `tau_ij = Var(component_list, component_list)`, there are 2*2=4 degrees of freedom. However, when i=j, the binary interaction parameter is 0. Therefore, in this problem, we estimate the binary interaction parameter for the following variables only:\n", "\n", "* fs.properties.tau['benzene', 'toluene']\n", "* fs.properties.tau['toluene', 'benzene']\n", "\n", - "
\n", - "Inline Exercise:\n", - "Create a list called `variable_name` with the above-mentioned variables declared as strings.\n", - "
" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "exercise" - ] - }, - "outputs": [], - "source": [ - "# Todo: Create a list of vars to estimate" + "As shown below, these model components are used as our `unknown_parameters`.\n", + "\n", + "We define `measurement_error` as none so parmest calculates the value internally based on the experimental outputs. Refer to https://pyomo.readthedocs.io/en/stable/explanation/analysis/parmest/driver.html for more information. " ] }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "solution" - ] - }, + "execution_count": 9, + "metadata": {}, "outputs": [], "source": [ - "# Todo: Create a list of vars to estimate\n", - "variable_name = [\n", - " \"fs.properties.tau['benzene', 'toluene']\",\n", - " \"fs.properties.tau['toluene', 'benzene']\",\n", - "]" + "# Build an experiment class to take advantage of new parmest interface\n", + "from pyomo.contrib.parmest.experiment import Experiment\n", + "\n", + "\n", + "class NRTLExperiment(Experiment):\n", + " \"\"\"Experiment class for parameter estimation of NRTL model using parmest\"\"\"\n", + "\n", + " def __init__(self, data, meas_error=None):\n", + " \"\"\"Initialize the NRTLExperiment class\n", + "\n", + " Args:\n", + " data: DataFrame containing the experimental data\n", + " meas_error: Measurement error for the data (optional)\n", + " \"\"\"\n", + " self.model = None\n", + " self.data = data\n", + " self.meas_error = meas_error\n", + "\n", + " def create_model(self):\n", + " \"\"\"Create the Pyomo model for the NRTL parameter estimation problem\"\"\"\n", + " self.model = NRTL_model(self.data)\n", + "\n", + " def label_model(self):\n", + " m = self.model\n", + "\n", + " # Add experiment outputs to the model for easier access\n", + " m.experiment_outputs = Suffix(direction=Suffix.LOCAL)\n", + " m.experiment_outputs.update(\n", + " [\n", + " (\n", + " m.fs.flash.liq_outlet.mole_frac_comp[0, \"benzene\"],\n", + " self.data[\"liq_benzene\"],\n", + " ),\n", + " (\n", + " m.fs.flash.vap_outlet.mole_frac_comp[0, \"benzene\"],\n", + " self.data[\"vap_benzene\"],\n", + " ),\n", + " ]\n", + " )\n", + "\n", + " m.measurement_error = Suffix(direction=Suffix.LOCAL)\n", + " m.measurement_error.update(\n", + " [\n", + " (m.fs.flash.liq_outlet.mole_frac_comp[0, \"benzene\"], self.meas_error),\n", + " (m.fs.flash.vap_outlet.mole_frac_comp[0, \"benzene\"], self.meas_error),\n", + " ]\n", + " )\n", + "\n", + " # Add unknown parameters to the model for easier access\n", + " m.unknown_parameters = Suffix(direction=Suffix.LOCAL)\n", + " m.unknown_parameters.update(\n", + " (k, value(k))\n", + " for k in [\n", + " m.fs.properties.tau[\"benzene\", \"toluene\"],\n", + " m.fs.properties.tau[\"toluene\", \"benzene\"],\n", + " ]\n", + " )\n", + "\n", + " def get_labeled_model(self):\n", + " \"\"\"Return the labeled model\"\"\"\n", + " if self.model is None:\n", + " self.create_model()\n", + " self.label_model()\n", + " return self.model" ] }, { @@ -360,9 +413,398 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
temperatureliq_benzenevap_benzene
0365.5000000.4809530.692110
1365.6176470.4624440.667699
2365.7352940.4779840.692441
3365.8529410.4405470.640336
4365.9705880.4274210.623328
5366.0882350.4427250.647796
6366.2058820.4343740.637691
7366.3235290.4446420.654933
8366.4411760.4271320.631229
9366.5588240.4463010.661743
10366.6764710.4380040.651591
11366.7941180.4253200.634814
12366.9117650.4394350.658047
13367.0294120.4356550.654539
14367.1470590.4013500.604987
15367.2647060.3978620.601703
16367.3823530.4158210.630930
17367.5000000.4206670.640380
18367.6176470.3916830.598214
19367.7352940.4049030.620432
20367.8529410.4095630.629626
21367.9705880.3894880.600722
22368.0000000.3967890.612483
23368.0882350.3981620.616106
24368.2058820.3623400.562505
25368.3235290.3869580.602680
26368.4411760.3636430.568210
27368.5588240.3681180.577072
28368.6764710.3840980.604078
29368.7941180.3536050.557925
30368.9117650.3464740.548445
31369.0294120.3507410.556996
32369.1470590.3623470.577286
33369.2647060.3625780.579519
34369.3823530.3407650.546411
35369.5000000.3374620.542857
36369.6176470.3557290.574083
37369.7352940.3486790.564513
38369.8529410.3381870.549284
39369.9705880.3243600.528514
40370.0882350.3107530.507964
41370.2058820.3110370.510055
42370.3235290.3112630.512055
43370.4411760.3080810.508437
44370.5588240.3082240.510293
45370.6764710.3181480.528399
46370.7941180.3083340.513728
47370.9117650.3179370.531410
48371.0294120.2891490.484824
49371.1470590.2986370.502318
\n", + "
" + ], + "text/plain": [ + " temperature liq_benzene vap_benzene\n", + "0 365.500000 0.480953 0.692110\n", + "1 365.617647 0.462444 0.667699\n", + "2 365.735294 0.477984 0.692441\n", + "3 365.852941 0.440547 0.640336\n", + "4 365.970588 0.427421 0.623328\n", + "5 366.088235 0.442725 0.647796\n", + "6 366.205882 0.434374 0.637691\n", + "7 366.323529 0.444642 0.654933\n", + "8 366.441176 0.427132 0.631229\n", + "9 366.558824 0.446301 0.661743\n", + "10 366.676471 0.438004 0.651591\n", + "11 366.794118 0.425320 0.634814\n", + "12 366.911765 0.439435 0.658047\n", + "13 367.029412 0.435655 0.654539\n", + "14 367.147059 0.401350 0.604987\n", + "15 367.264706 0.397862 0.601703\n", + "16 367.382353 0.415821 0.630930\n", + "17 367.500000 0.420667 0.640380\n", + "18 367.617647 0.391683 0.598214\n", + "19 367.735294 0.404903 0.620432\n", + "20 367.852941 0.409563 0.629626\n", + "21 367.970588 0.389488 0.600722\n", + "22 368.000000 0.396789 0.612483\n", + "23 368.088235 0.398162 0.616106\n", + "24 368.205882 0.362340 0.562505\n", + "25 368.323529 0.386958 0.602680\n", + "26 368.441176 0.363643 0.568210\n", + "27 368.558824 0.368118 0.577072\n", + "28 368.676471 0.384098 0.604078\n", + "29 368.794118 0.353605 0.557925\n", + "30 368.911765 0.346474 0.548445\n", + "31 369.029412 0.350741 0.556996\n", + "32 369.147059 0.362347 0.577286\n", + "33 369.264706 0.362578 0.579519\n", + "34 369.382353 0.340765 0.546411\n", + "35 369.500000 0.337462 0.542857\n", + "36 369.617647 0.355729 0.574083\n", + "37 369.735294 0.348679 0.564513\n", + "38 369.852941 0.338187 0.549284\n", + "39 369.970588 0.324360 0.528514\n", + "40 370.088235 0.310753 0.507964\n", + "41 370.205882 0.311037 0.510055\n", + "42 370.323529 0.311263 0.512055\n", + "43 370.441176 0.308081 0.508437\n", + "44 370.558824 0.308224 0.510293\n", + "45 370.676471 0.318148 0.528399\n", + "46 370.794118 0.308334 0.513728\n", + "47 370.911765 0.317937 0.531410\n", + "48 371.029412 0.289149 0.484824\n", + "49 371.147059 0.298637 0.502318" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "# Load data from csv\n", "data = pd.read_csv(\"BT_NRTL_dataset.csv\")\n", @@ -375,83 +817,198 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "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 mole fraction of benzene in the vapor and liquid phase between the model prediction and data. \n", - "\n", - "
\n", - "Inline Exercise:\n", - "Complete the following cell by adding an expression to compute the sum of square errors. \n", - "
" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "exercise" - ] - }, - "outputs": [], - "source": [ - "# Create method to return an expression that computes the sum of squared error\n", - "def SSE(m, data):\n", - " # Todo: Add expression for computing the sum of squared errors in mole fraction of benzene in the liquid\n", - " # and vapor phase. For example, the squared error for the vapor phase is:\n", - " # (float(data[\"vap_benzene\"]) - m.fs.flash.vap_outlet.mole_frac_comp[0, \"benzene\"])**2\n", - "\n", - " return expr * 1e4" + "We define the `exp_list` by spliting the data into individual experiments, or data points." ] }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "solution" - ] - }, - "outputs": [], - "source": [ - "# Create method to return an expression that computes the sum of squared error\n", - "def SSE(m, data):\n", - " # Todo: Add expression for computing the sum of squared errors in mole fraction of benzene in the liquid\n", - " # and vapor phase. For example, the squared error for the vapor phase is:\n", - " # (float(data[\"vap_benzene\"]) - m.fs.flash.vap_outlet.mole_frac_comp[0, \"benzene\"])**2\n", - " expr = (\n", - " float(data[\"vap_benzene\"]) - m.fs.flash.vap_outlet.mole_frac_comp[0, \"benzene\"]\n", - " ) ** 2 + (\n", - " float(data[\"liq_benzene\"]) - m.fs.flash.liq_outlet.mole_frac_comp[0, \"benzene\"]\n", - " ) ** 2\n", - " return expr * 1e4" - ] - }, - { - "cell_type": "markdown", + "execution_count": 11, "metadata": {}, + "outputs": [], "source": [ - "
\n", - "Note:\n", - "Notice that we have scaled the expression up by a factor of 10000 as the SSE computed here will be an extremely small number given that we are using the difference in mole fraction in our expression. A well-scaled objective will help improve solve robustness when using IPOPT. \n", - "
\n" + "# Loop through the dataset and create an experiment for each row of data\n", + "exp_list = []\n", + "for i in range(data.shape[0]):\n", + " exp_list.append(NRTLExperiment(data.iloc[i]))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "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, dataset, list of variable names to estimate, and the SSE expression to the Estimator object. `tee=True` will print the solver output after solving the parameter estimation problem." + "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." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 10950\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 6600\n", + "\n", + "Total number of variables............................: 2952\n", + " variables with only lower bounds: 150\n", + " variables with lower and upper bounds: 600\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 2950\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 6.0671019e-03 5.63e+02 1.20e-08 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 9.0714942e-04 1.37e+03 1.61e+01 -1.0 1.37e+04 - 9.82e-01 1.00e+00h 1\n", + " 2 1.3219937e-03 1.17e+04 1.62e+01 -1.0 5.23e+03 - 3.41e-01 1.65e-01h 3\n", + " 3 1.3161671e-03 1.11e+04 4.02e+01 -1.0 3.96e+02 -4.0 8.19e-01 1.25e-01h 4\n", + " 4 1.3154170e-03 1.11e+04 4.32e+01 -1.0 3.47e+02 -4.5 9.90e-01 4.43e-02h 5\n", + " 5 9.4424343e-04 1.04e+04 4.05e+01 -1.0 1.16e+04 - 9.33e-01 5.61e-02h 5\n", + " 6 9.4571258e-04 1.11e+04 4.85e+01 -1.0 3.13e+02 -5.0 8.74e-01 1.25e-01h 4\n", + " 7 9.4862862e-04 1.11e+04 4.84e+01 -1.0 2.41e+03 -5.4 1.72e-01 1.50e-03h 8\n", + " 8 9.5448936e-04 1.10e+04 4.81e+01 -1.0 4.11e+02 -5.0 1.00e+00 1.97e-02h 6\n", + " 9 9.5650047e-04 1.10e+04 4.81e+01 -1.0 5.14e+02 -4.6 3.46e-01 5.24e-03h 7\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 9.5730419e-04 1.10e+04 4.81e+01 -1.0 9.78e+02 -4.2 4.40e-01 1.08e-03h 8\n", + " 11 9.5774182e-04 1.10e+04 4.84e+01 -1.0 2.76e+02 -3.7 2.91e-01 2.99e-03h 7\n", + " 12 9.4292855e-04 7.77e+04 4.09e+04 -1.0 5.38e+02 -2.4 5.48e-02 6.44e-02w 1\n", + " 13 2.4318219e-01 2.38e+07 4.22e+14 -1.0 1.28e+06 - 2.55e-02 3.49e-02w 1\n", + " 14 2.8902019e-01 1.64e+07 2.92e+14 -1.0 1.11e+05 -2.9 9.54e-01 3.01e-01w 1\n", + " 15 9.5768293e-04 1.10e+04 4.85e+01 -1.0 2.80e+05 -3.4 5.48e-02 2.52e-04h 8\n", + " 16 9.5769345e-04 1.10e+04 4.85e+01 -1.0 4.33e+02 -2.9 7.95e-02 1.91e-04h 9\n", + " 17 9.5763809e-04 1.10e+04 4.85e+01 -1.0 6.35e+02 -2.5 4.94e-02 2.08e-04h 9\n", + " 18 9.5734836e-04 1.10e+04 4.87e+01 -1.0 3.22e+02 -3.0 1.00e+00 1.22e-03h 8\n", + " 19 9.3628114e-04 1.09e+04 4.62e+01 -1.0 4.22e+02 -3.5 5.16e-01 5.87e-02h 5\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 7.1894543e-04 4.02e+03 4.95e+02 -1.0 3.49e+02 -3.9 1.00e+00 1.00e+00h 1\n", + " 21 6.7062834e-04 1.58e+02 2.21e+02 -1.0 1.78e+02 -4.4 1.00e+00 1.00e+00h 1\n", + " 22 6.6635123e-04 4.17e+01 1.12e+01 -1.0 2.44e+02 -4.9 1.00e+00 1.00e+00h 1\n", + " 23 6.6729070e-04 1.43e+00 9.69e-01 -1.0 1.08e+01 -5.4 1.00e+00 1.00e+00h 1\n", + " 24 6.6785681e-04 3.58e-01 5.25e-03 -1.7 6.65e+00 -5.8 1.00e+00 1.00e+00h 1\n", + " 25 6.2552355e-04 9.80e+02 6.48e-02 -3.8 7.92e+02 - 9.22e-01 1.00e+00h 1\n", + " 26 5.9105707e-04 8.13e+00 6.13e-04 -3.8 5.66e+02 - 1.00e+00 1.00e+00h 1\n", + " 27 6.1313801e-04 6.24e+01 8.08e-06 -3.8 1.70e+02 - 1.00e+00 1.00e+00h 1\n", + " 28 6.1208051e-04 3.58e-01 1.18e-08 -3.8 1.88e+00 - 1.00e+00 1.00e+00h 1\n", + " 29 5.9010560e-04 1.58e+01 1.00e-05 -5.7 1.08e+02 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30 5.9008319e-04 2.74e-02 7.90e-07 -5.7 7.54e-02 -6.3 1.00e+00 1.00e+00h 1\n", + " 31 5.3570104e-04 1.48e+04 8.70e-04 -5.7 1.81e+02 - 1.00e+00 1.00e+00h 1\n", + " 32 5.1618763e-04 6.29e+02 8.06e-05 -5.7 2.55e+02 - 1.00e+00 1.00e+00h 1\n", + " 33 5.5250565e-04 2.88e+01 2.58e-04 -5.7 1.81e+04 - 6.26e-01 6.25e-02h 5\n", + " 34 5.2209909e-04 2.88e+02 2.02e-04 -5.7 1.89e+03 - 1.00e+00 1.00e+00h 1\n", + " 35 5.0707798e-04 5.60e+01 2.02e-04 -5.7 2.93e+03 - 1.00e+00 1.00e+00h 1\n", + " 36 5.0765648e-04 7.87e+00 1.91e-05 -5.7 1.02e+02 - 1.00e+00 1.00e+00h 1\n", + " 37 5.0740606e-04 2.57e+00 1.88e-05 -5.7 6.96e+01 - 1.00e+00 1.00e+00h 1\n", + " 38 5.0764164e-04 2.55e+00 1.76e-05 -5.7 6.81e+01 - 1.00e+00 1.00e+00h 1\n", + " 39 5.0740672e-04 2.55e+00 1.88e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 40 5.0764162e-04 2.54e+00 1.76e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", + " 41 5.0740672e-04 2.55e+00 1.88e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", + " 42 5.0782847e-04 1.43e-01 1.83e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00H 1\n", + " 43 5.0751252e-04 1.58e-02 1.93e-05 -5.7 6.88e+01 - 1.00e+00 1.00e+00H 1\n", + " 44 5.0783218e-04 4.79e-03 1.85e-05 -5.7 6.92e+01 - 1.00e+00 1.00e+00H 1\n", + " 45 5.0751252e-04 1.60e-02 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", + " 46 5.0783222e-04 1.23e-04 1.85e-05 -5.7 6.92e+01 - 1.00e+00 1.00e+00H 1\n", + " 47 5.0751252e-04 1.60e-02 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", + " 48 5.0783216e-04 1.24e-04 1.85e-05 -5.7 6.92e+01 - 1.00e+00 1.00e+00H 1\n", + " 49 5.0751765e-04 3.20e-03 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 50 5.0764151e-04 2.56e+00 1.77e-05 -5.7 6.93e+01 - 1.00e+00 1.00e+00h 1\n", + " 51 5.0740671e-04 2.55e+00 1.88e-05 -5.7 6.81e+01 - 1.00e+00 1.00e+00h 1\n", + " 52 5.0764162e-04 2.54e+00 1.76e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", + " 53 5.0740672e-04 2.55e+00 1.88e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", + " 54 5.0764162e-04 2.54e+00 1.76e-05 -5.7 6.80e+01 - 1.00e+00 1.00e+00h 1\n", + " 55 5.0748886e-04 1.91e+00 8.64e-06 -5.7 6.80e+01 - 1.00e+00 5.00e-01h 2\n", + " 56 5.0744550e-04 3.37e-01 1.64e-05 -5.7 2.54e+01 - 1.00e+00 1.00e+00h 1\n", + " 57 5.0763613e-04 1.82e+00 1.43e-05 -5.7 5.79e+01 - 1.00e+00 1.00e+00h 1\n", + " 58 5.0751252e-04 2.25e-02 1.93e-05 -5.7 6.65e+01 - 1.00e+00 1.00e+00H 1\n", + " 59 5.0783220e-04 1.23e-04 1.85e-05 -5.7 6.92e+01 - 1.00e+00 1.00e+00H 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 60 5.0751252e-04 1.60e-02 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", + " 61 5.0783207e-04 3.26e-04 1.85e-05 -5.7 6.92e+01 - 1.00e+00 1.00e+00H 1\n", + " 62 5.0751786e-04 7.95e-05 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", + " 63 5.0754291e-04 6.40e-01 8.69e-06 -5.7 6.93e+01 - 1.00e+00 5.00e-01h 2\n", + " 64 5.0745167e-04 3.00e-01 1.61e-05 -5.7 2.35e+01 - 1.00e+00 1.00e+00h 1\n", + " 65 5.0763437e-04 1.71e+00 1.33e-05 -5.7 5.61e+01 - 1.00e+00 1.00e+00h 1\n", + " 66 5.0751762e-04 2.91e-03 1.93e-05 -5.7 6.60e+01 - 1.00e+00 1.00e+00H 1\n", + " 67 5.0752104e-04 1.62e-01 1.43e-05 -5.7 6.92e+01 - 1.00e+00 2.50e-01h 3\n", + " 68 5.0761295e-04 1.03e+00 2.18e-05 -5.7 4.35e+01 - 1.00e+00 1.00e+00h 1\n", + " 69 5.0751251e-04 2.38e-02 1.92e-05 -5.7 5.95e+01 - 1.00e+00 1.00e+00H 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 70 5.0783210e-04 3.29e-06 1.85e-05 -5.7 6.90e+01 - 1.00e+00 1.00e+00H 1\n", + " 71 5.0751786e-04 7.94e-05 1.93e-05 -5.7 6.89e+01 - 1.00e+00 1.00e+00H 1\n", + " 72 5.0754292e-04 6.40e-01 8.69e-06 -5.7 6.93e+01 - 1.00e+00 5.00e-01h 2\n", + " 73 5.0749299e-04 3.95e-01 1.21e-05 -5.7 2.35e+01 - 1.00e+00 5.00e-01h 2\n", + " 74 5.0755524e-04 1.36e-01 3.09e-05 -5.7 1.57e+01 - 1.00e+00 1.00e+00h 1\n", + " 75 5.0751308e-04 1.96e-02 1.80e-05 -5.7 3.30e+01 - 1.00e+00 1.00e+00H 1\n", + " 76 5.0754492e-04 5.62e-01 8.19e-06 -5.7 6.42e+01 - 1.00e+00 5.00e-01h 2\n", + " 77 5.0748301e-04 3.98e-01 1.25e-05 -5.7 2.93e+01 - 1.00e+00 5.00e-01h 2\n", + " 78 5.0756455e-04 2.42e-01 3.07e-05 -5.7 2.09e+01 - 1.00e+00 1.00e+00h 1\n", + " 79 5.0751710e-04 1.38e-03 1.87e-05 -5.7 3.98e+01 - 1.00e+00 1.00e+00H 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 80 5.0783077e-04 3.26e-06 1.84e-05 -5.7 6.70e+01 - 1.00e+00 1.00e+00H 1\n", + " 81 5.0726420e-04 1.24e+01 1.85e-05 -8.6 1.34e+02 - 9.93e-01 1.00e+00h 1\n", + " 82 5.0749897e-04 2.75e+00 2.53e-06 -8.6 6.93e+01 - 1.00e+00 1.00e+00h 1\n", + " 83 5.0749686e-04 3.64e-04 6.40e-10 -8.6 4.69e-02 - 1.00e+00 1.00e+00h 1\n", + " 84 5.0749686e-04 7.28e-11 2.51e-14 -8.6 6.86e-05 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 84\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 5.0749685809243843e-04 5.0749685809243843e-04\n", + "Dual infeasibility......: 2.5059195074646584e-14 2.5059195074646584e-14\n", + "Constraint violation....: 1.4104644499482425e-11 7.2759576141834259e-11\n", + "Complementarity.........: 2.5059035596800647e-09 2.5059035596800647e-09\n", + "Overall NLP error.......: 2.5059035596800647e-09 2.5059035596800647e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 260\n", + "Number of objective gradient evaluations = 85\n", + "Number of equality constraint evaluations = 260\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 85\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 84\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.338\n", + "Total CPU secs in NLP function evaluations = 0.092\n", + "\n", + "EXIT: Optimal Solution Found.\n" + ] + } + ], "source": [ - "# Initialize a parameter estimation object\n", - "pest = parmest.Estimator(NRTL_model, data, variable_name, SSE, tee=True)\n", + "import logging\n", + "\n", + "idaeslog.getIdaesLogger(\"core.property_meta\").setLevel(logging.ERROR)\n", "\n", - "# Run parameter estimation using all data\n", + "pest = parmest.Estimator(exp_list, obj_function=\"SSE\", tee=True)\n", "obj_value, parameters = pest.theta_est()" ] }, @@ -466,11 +1023,23 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The SSE at the optimal solution is 0.000507\n", + "\n", + "The values for the parameters are as follows:\n", + "fs.properties.tau[benzene,toluene] = -0.8987454466579063\n", + "fs.properties.tau[toluene,benzene] = 1.410449514796474\n" + ] + } + ], "source": [ - "print(\"The SSE at the optimal solution is %0.6f\" % (obj_value * 1e-4))\n", + "print(\"The SSE at the optimal solution is %0.6f\" % (obj_value))\n", "print()\n", "print(\"The values for the parameters are as follows:\")\n", "for k, v in parameters.items():\n", @@ -496,14 +1065,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Pyomo's `parmest` tool allows for bootstrapping where the parameter estimation is repeated over `n` samples with resampling from the original data set. Parameter estimation with bootstrap resampling can be used to identify confidence regions around each parameter estimate. This analysis can be slow given the increased number of model instances that need to be solved. Please refer to https://pyomo.readthedocs.io/en/stable/contributed_packages/parmest/driver.html for more details. \n", + "Pyomo's `parmest` tool allows for bootstrapping where the parameter estimation is repeated over `n` samples with resampling from the original data set. Parameter estimation with bootstrap resampling can be used to identify confidence regions around each parameter estimate. This analysis can be slow given the increased number of model instances that need to be solved. Please refer to https://pyomo.readthedocs.io/en/stable/explanation/analysis/parmest/covariance.html#bootstrapping for more details. \n", "\n", "For the example above, the bootstrapping can be run by uncommenting the code in the following cell:" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "metadata": {}, "outputs": [], "source": [ @@ -511,8 +1080,7 @@ "# plot results along with confidence regions\n", "\n", "# Uncomment the following lines\n", - "\n", - "# bootstrap_theta = pest.theta_est_bootstrap(4)\n", + "# bootstrap_theta = pest.theta_est_bootstrap(4, seed=542)\n", "# display(bootstrap_theta)" ] } @@ -520,7 +1088,7 @@ "metadata": { "celltoolbar": "Tags", "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "idaes-pse-and-examples-dev-py313-macmini", "language": "python", "name": "python3" }, @@ -534,9 +1102,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.12" + "version": "3.13.13" } }, "nbformat": 4, "nbformat_minor": 3 -} +} \ No newline at end of file diff --git a/idaes_examples/notebooks/docs/properties/parameter_estimation_pr_doc.ipynb b/idaes_examples/notebooks/docs/properties/parameter_estimation_pr_doc.ipynb index ea87d247..e42c5b93 100644 --- a/idaes_examples/notebooks/docs/properties/parameter_estimation_pr_doc.ipynb +++ b/idaes_examples/notebooks/docs/properties/parameter_estimation_pr_doc.ipynb @@ -1,1597 +1,774 @@ { - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "tags": [ - "header", - "hide-cell" - ] - }, - "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", - "metadata": {}, - "source": [ - "# Using Parameter Estimation with Modular Property Packages\n", - "Author: Alejandro Garciadego \n", - "Maintainer: Andrew Lee \n", - "Updated: 2023-06-01 \n", - "## 1. Introduction\n", - "\n", - "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.\n", - "\n", - "### 1.1 Tutorial objectives\n", - "\n", - "* 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.\n", - "* Set up a method to return an initialized model\n", - "* Set up the parameter estimation problem using `parmest`" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 2. Problem Statement\n", - "\n", - "### 2.1 Importing Pyomo and IDAES model and flowsheet components.\n", - "\n", - "In the next cell, we will be importing the necessary components from Pyomo and IDAES." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "# Import objects from pyomo package\n", - "from pyomo.environ import ConcreteModel, SolverFactory, units as pyunits\n", - "\n", - "# Import the main FlowsheetBlock from IDAES. The flowsheet block will contain the unit model\n", - "from idaes.core import FlowsheetBlock\n", - "\n", - "# Import idaes logger to set output levels\n", - "import idaes.logger as idaeslog\n", - "\n", - "# Import Flash unit model from idaes.models.unit_models\n", - "from idaes.models.unit_models import Flash" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 2.2 Import parmest " - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "import pyomo.contrib.parmest.parmest as parmest" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 2.3 Import the Modular Property framework" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [], - "source": [ - "from idaes.models.properties.modular_properties.examples.CO2_bmimPF6_PR import (\n", - " configuration,\n", - ")\n", - "\n", - "from idaes.models.properties.modular_properties import GenericParameterBlock" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 2.4 Import data\n", - "\n", - "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." - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "\n", - "# Load data from csv\n", - "data = pd.read_csv(\"CO2_IL_298.csv\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.0 Setting up an initialized model\n", - "\n", - "We need to provide a method that returns an initialized model to the `parmest` tool in Pyomo.\n", - "\n", - "How we build the model will depend on the data we provided in the data dataframe from pir .csv file.\n", - "\n", - "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. " - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [], - "source": [ - "def PR_model(data):\n", - "\n", - " m = ConcreteModel()\n", - "\n", - " m.fs = FlowsheetBlock(dynamic=False)\n", - "\n", - " m.fs.properties = GenericParameterBlock(**configuration)\n", - "\n", - " m.fs.state_block = m.fs.properties.build_state_block([1], defined_state=True)\n", - "\n", - " m.fs.state_block[1].flow_mol.fix(1)\n", - " x = float(data[\"x_carbon_dioxide\"]) + 0.5\n", - " m.fs.state_block[1].temperature.fix(float(data[\"temperature\"]))\n", - " m.fs.state_block[1].pressure.fix(float(data[\"pressure\"]))\n", - " m.fs.state_block[1].mole_frac_comp[\"bmimPF6\"].fix(1 - x)\n", - " m.fs.state_block[1].mole_frac_comp[\"carbon_dioxide\"].fix(x)\n", - "\n", - " # parameter - kappa_ij (set at 0.3, 0 if i=j)\n", - " m.fs.properties.PR_kappa[\"bmimPF6\", \"bmimPF6\"].fix(0)\n", - " m.fs.properties.PR_kappa[\"bmimPF6\", \"carbon_dioxide\"].fix(-0.047)\n", - " m.fs.properties.PR_kappa[\"carbon_dioxide\", \"carbon_dioxide\"].fix(0)\n", - " m.fs.properties.PR_kappa[\"carbon_dioxide\", \"bmimPF6\"].fix(0.002)\n", - "\n", - " # Initialize the flash unit\n", - " m.fs.state_block.initialize(outlvl=idaeslog.INFO)\n", - "\n", - " # Fix the state variables on the state block\n", - " m.fs.state_block[1].pressure.unfix()\n", - " m.fs.state_block[1].temperature.fix(float(data[\"temperature\"]))\n", - " m.fs.state_block[1].mole_frac_phase_comp[\"Liq\", \"bmimPF6\"].fix(\n", - " float(data[\"x_bmimPF6\"])\n", - " )\n", - " m.fs.state_block[1].mole_frac_phase_comp[\"Liq\", \"carbon_dioxide\"].fix(\n", - " float(data[\"x_carbon_dioxide\"])\n", - " )\n", - " m.fs.state_block[1].mole_frac_comp[\"bmimPF6\"].fix(float(data[\"x_bmimPF6\"]))\n", - " m.fs.state_block[1].mole_frac_comp[\"carbon_dioxide\"].unfix()\n", - " # Set bounds on variables to be estimated\n", - " m.fs.properties.PR_kappa[\"bmimPF6\", \"carbon_dioxide\"].setlb(-5)\n", - " m.fs.properties.PR_kappa[\"bmimPF6\", \"carbon_dioxide\"].setub(5)\n", - "\n", - " m.fs.properties.PR_kappa[\"carbon_dioxide\", \"bmimPF6\"].setlb(-5)\n", - " m.fs.properties.PR_kappa[\"carbon_dioxide\", \"bmimPF6\"].setub(5)\n", - "\n", - " # Return initialized flash model\n", - " return m" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.1 Solving square problem" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": { - "scrolled": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:29:59 [INFO] idaes.init.fs.state_block: Starting initialization\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "WARNING (W1002): Setting Var\n", - "'fs.state_block[1].log_mole_frac_tbub[Vap,Liq,carbon_dioxide]' to a numeric\n", - "value `1.3789905650578088e-06` outside the bounds (None, 0).\n", - " See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:29:59 [INFO] idaes.init.fs.state_block: Dew and bubble point initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:29:59 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:29:59 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:00 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:00 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:00 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n" - ] + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "tags": [ + "header", + "hide-cell" + ] + }, + "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": [ + "# Using Parameter Estimation with Modular Property Packages\n", + "Author: Alejandro Garciadego \n", + "Maintainer: Stephen Cini \n", + "Updated: 2026-06-11 \n", + "## 1. Introduction\n", + "\n", + "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.\n", + "\n", + "### 1.1 Tutorial objectives\n", + "\n", + "* 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.\n", + "* Set up a method to return an initialized model\n", + "* Set up the parameter estimation problem using `parmest`" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 2. Problem Statement\n", + "\n", + "### 2.1 Importing Pyomo and IDAES model and flowsheet components.\n", + "\n", + "In the next cell, we will be importing the necessary components from Pyomo and IDAES." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# Import objects from pyomo package\n", + "from pyomo.environ import ConcreteModel, SolverFactory, value, Suffix\n", + "\n", + "# Import the main FlowsheetBlock from IDAES. The flowsheet block will contain the unit model\n", + "from idaes.core import FlowsheetBlock\n", + "\n", + "# Import idaes logger to set output levels\n", + "import idaes.logger as idaeslog\n", + "\n", + "# Import Flash unit model from idaes.models.unit_models\n", + "from idaes.models.unit_models import Flash" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 2.2 Import parmest " + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "import pyomo.contrib.parmest.parmest as parmest" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 2.3 Import the Modular Property framework" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "from idaes.models.properties.modular_properties.examples.CO2_bmimPF6_PR import (\n", + " configuration,\n", + ")\n", + "\n", + "from idaes.models.properties.modular_properties import GenericParameterBlock" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 2.4 Import data\n", + "\n", + "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." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "\n", + "# Load data from csv\n", + "data = pd.read_csv(\"CO2_IL_298.csv\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 3.0 Setting up an initialized model\n", + "\n", + "We need to provide a method that returns an initialized model to the `parmest` tool in Pyomo.\n", + "\n", + "How we build the model will depend on the data we provided in the data dataframe from pir .csv file.\n", + "\n", + "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. " + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "def PR_model(data):\n", + "\n", + " m = ConcreteModel()\n", + "\n", + " m.fs = FlowsheetBlock(dynamic=False)\n", + "\n", + " m.fs.properties = GenericParameterBlock(**configuration)\n", + "\n", + " m.fs.state_block = m.fs.properties.build_state_block([1], defined_state=True)\n", + "\n", + " m.fs.state_block[1].flow_mol.fix(1)\n", + " if isinstance(data, dict) or isinstance(data, pd.Series):\n", + " x = float(data[\"x_carbon_dioxide\"]) + 0.5\n", + " m.fs.state_block[1].temperature.fix(float(data[\"temperature\"]))\n", + " m.fs.state_block[1].pressure.fix(float(data[\"pressure\"]))\n", + " elif isinstance(data, pd.DataFrame):\n", + " x = float(data.iloc[0][\"x_carbon_dioxide\"]) + 0.5\n", + " m.fs.state_block[1].temperature.fix(float(data.iloc[0][\"temperature\"]))\n", + " m.fs.state_block[1].pressure.fix(float(data.iloc[0][\"pressure\"]))\n", + " else:\n", + " raise ValueError(\"Unrecognized data type.\")\n", + " m.fs.state_block[1].mole_frac_comp[\"bmimPF6\"].fix(1 - x)\n", + " m.fs.state_block[1].mole_frac_comp[\"carbon_dioxide\"].fix(x)\n", + "\n", + " # parameter - kappa_ij (set at 0.3, 0 if i=j)\n", + " m.fs.properties.PR_kappa[\"bmimPF6\", \"bmimPF6\"].fix(0)\n", + " m.fs.properties.PR_kappa[\"bmimPF6\", \"carbon_dioxide\"].fix(-0.047)\n", + " m.fs.properties.PR_kappa[\"carbon_dioxide\", \"carbon_dioxide\"].fix(0)\n", + " m.fs.properties.PR_kappa[\"carbon_dioxide\", \"bmimPF6\"].fix(0.002)\n", + "\n", + " # Initialize the flash unit\n", + " m.fs.state_block.initialize(outlvl=idaeslog.INFO)\n", + "\n", + " # Fix the state variables on the state block\n", + " if isinstance(data, dict) or isinstance(data, pd.Series):\n", + " m.fs.state_block[1].temperature.fix(float(data[\"temperature\"]))\n", + " m.fs.state_block[1].mole_frac_phase_comp[\"Liq\", \"bmimPF6\"].fix(\n", + " float(data[\"x_bmimPF6\"])\n", + " )\n", + " m.fs.state_block[1].mole_frac_phase_comp[\"Liq\", \"carbon_dioxide\"].fix(\n", + " float(data[\"x_carbon_dioxide\"])\n", + " )\n", + " m.fs.state_block[1].mole_frac_comp[\"bmimPF6\"].fix(float(data[\"x_bmimPF6\"]))\n", + " elif isinstance(data, pd.DataFrame):\n", + " m.fs.state_block[1].temperature.fix(float(data.iloc[0][\"temperature\"]))\n", + " m.fs.state_block[1].mole_frac_phase_comp[\"Liq\", \"bmimPF6\"].fix(\n", + " float(data.iloc[0][\"x_bmimPF6\"])\n", + " )\n", + " m.fs.state_block[1].mole_frac_phase_comp[\"Liq\", \"carbon_dioxide\"].fix(\n", + " float(data.iloc[0][\"x_carbon_dioxide\"])\n", + " )\n", + " m.fs.state_block[1].mole_frac_comp[\"bmimPF6\"].fix(\n", + " float(data.iloc[0][\"x_bmimPF6\"])\n", + " )\n", + " else:\n", + " raise ValueError(\"Unrecognized data type.\")\n", + "\n", + " m.fs.state_block[1].pressure.unfix()\n", + " m.fs.state_block[1].mole_frac_comp[\"carbon_dioxide\"].unfix()\n", + " # Set bounds on variables to be estimated\n", + " m.fs.properties.PR_kappa[\"bmimPF6\", \"carbon_dioxide\"].setlb(-5)\n", + " m.fs.properties.PR_kappa[\"bmimPF6\", \"carbon_dioxide\"].setub(5)\n", + "\n", + " m.fs.properties.PR_kappa[\"carbon_dioxide\", \"bmimPF6\"].setlb(-5)\n", + " m.fs.properties.PR_kappa[\"carbon_dioxide\", \"bmimPF6\"].setub(5)\n", + "\n", + " # Return initialized flash model\n", + " return m" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3.1 Solving square problem" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2026-06-11 12:42:22 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 39\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 25\n", + "\n", + "Total number of variables............................: 18\n", + " variables with only lower bounds: 4\n", + " variables with lower and upper bounds: 13\n", + " variables with only upper bounds: 1\n", + "Total number of equality constraints.................: 18\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 5.00e-01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 0.0000000e+00 1.76e-01 6.65e+03 -1.0 7.51e+04 - 2.67e-01 9.90e-01H 1\n", + " 2 0.0000000e+00 4.81e-02 1.40e+02 -1.0 6.76e+02 - 9.46e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 8.65e-03 1.76e+01 -1.0 9.79e+00 - 9.90e-01 9.90e-01h 1\n", + " 4 0.0000000e+00 1.81e-03 4.99e+04 -1.0 1.20e+00 - 9.90e-01 1.00e+00h 1\n", + " 5 0.0000000e+00 3.48e-03 9.81e+04 -1.0 5.29e+01 - 9.90e-01 1.00e+00h 1\n", + " 6 0.0000000e+00 1.57e-03 8.00e+02 -1.0 1.54e+02 - 9.92e-01 1.00e+00h 1\n", + " 7 0.0000000e+00 7.66e-04 2.93e-04 -2.5 2.52e+02 - 1.00e+00 1.00e+00h 1\n", + " 8 0.0000000e+00 3.81e-04 1.61e-04 -5.7 4.82e+02 - 1.00e+00 1.00e+00h 1\n", + " 9 0.0000000e+00 1.90e-04 6.49e-05 -5.7 9.53e+02 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 0.0000000e+00 9.50e-05 8.68e-05 -5.7 1.90e+03 - 1.00e+00 1.00e+00h 1\n", + " 11 0.0000000e+00 4.75e-05 3.47e-04 -5.7 3.81e+03 - 1.00e+00 1.00e+00h 1\n", + " 12 0.0000000e+00 2.72e-05 1.39e-03 -5.7 7.64e+03 - 1.00e+00 1.00e+00h 1\n", + " 13 0.0000000e+00 1.07e-04 5.57e-03 -5.7 1.54e+04 - 1.00e+00 1.00e+00h 1\n", + " 14 0.0000000e+00 4.09e-04 2.23e-02 -5.7 3.11e+04 - 1.00e+00 1.00e+00h 1\n", + " 15 0.0000000e+00 1.51e-03 8.91e-02 -5.7 6.38e+04 - 1.00e+00 1.00e+00h 1\n", + " 16 0.0000000e+00 5.12e-03 3.53e-01 -5.7 1.33e+05 - 1.00e+00 1.00e+00h 1\n", + " 17 0.0000000e+00 1.49e-02 1.34e+00 -5.7 2.89e+05 - 1.00e+00 1.00e+00h 1\n", + " 18 0.0000000e+00 3.14e-02 4.58e+00 -5.7 6.55e+05 - 1.00e+00 1.00e+00h 1\n", + " 19 0.0000000e+00 2.86e-02 4.32e+00 -5.7 1.51e+06 - 1.00e+00 1.25e-01h 4\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 0.0000000e+00 2.82e-02 4.26e+00 -5.7 1.73e+06 - 1.00e+00 1.56e-02h 7\n", + " 21 0.0000000e+00 2.79e-02 4.23e+00 -5.7 1.76e+06 - 1.00e+00 7.81e-03h 8\n", + " 22 0.0000000e+00 2.79e-02 4.22e+00 -5.7 1.77e+06 - 1.00e+00 4.88e-04h 12\n", + " 23 0.0000000e+00 2.79e-02 4.22e+00 -5.7 1.77e+06 - 1.00e+00 1.22e-04h 14\n", + " 24 0.0000000e+00 7.05e-03 1.51e+01 -5.7 1.77e+06 - 1.00e+00 1.00e+00h 1\n", + " 25 0.0000000e+00 9.63e-04 4.01e+00 -5.7 3.18e+06 - 1.00e+00 1.50e-01h 2\n", + " 26 0.0000000e+00 5.53e-04 8.54e+01 -5.7 3.24e+06 - 1.00e+00 6.53e-02h 2\n", + " 27 0.0000000e+00 5.53e-04 8.57e+01 -5.7 3.20e+06 - 1.00e+00 9.58e-04h 7\n", + " 28 0.0000000e+00 5.53e-04 9.27e+01 -5.7 3.19e+06 - 1.00e+00 9.42e-04h 7\n", + " 29 0.0000000e+00 5.53e-04 2.08e+02 -5.7 3.19e+06 - 1.00e+00 9.27e-04h 7\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30 0.0000000e+00 5.52e-04 7.91e+03 -5.7 1.83e+06 - 1.00e+00 3.17e-03h 6\n", + " 31 0.0000000e+00 3.77e-05 2.11e+06 -5.7 2.63e+04 - 1.00e+00 1.00e+00h 1\n", + " 32 0.0000000e+00 3.77e-05 2.10e+06 -5.7 1.03e+06 - 1.00e+00 5.67e-04h 9\n", + " 33 0.0000000e+00 3.77e-05 2.10e+06 -5.7 1.03e+06 - 1.00e+00 5.65e-04h 9\n", + " 34 0.0000000e+00 3.77e-05 2.10e+06 -5.7 1.02e+06 - 1.00e+00 5.63e-04h 9\n", + " 35 0.0000000e+00 3.77e-05 2.12e+06 -5.7 9.14e+05 - 1.00e+00 6.29e-04h 9\n", + " 36 0.0000000e+00 3.77e-05 2.23e+06 -5.7 9.36e+05 - 1.00e+00 6.11e-04h 9\n", + " 37 0.0000000e+00 3.76e-05 4.98e+06 -5.7 4.23e+05 - 1.00e+00 2.69e-03h 8\n", + " 38 0.0000000e+00 3.76e-05 6.97e+06 -5.7 8.98e+05 - 1.00e+00 6.29e-04h 9\n", + " 39 0.0000000e+00 3.76e-05 5.17e+07 -5.7 6.09e+05 - 1.00e+00 1.85e-03h 8\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 40 0.0000000e+00 3.76e-05 6.29e+07 -5.7 1.03e+06 - 1.00e+00 5.42e-04h 9\n", + " 41 0.0000000e+00 3.76e-05 7.41e+07 -5.7 1.02e+06 - 1.00e+00 5.43e-04h 9\n", + " 42 0.0000000e+00 8.59e-04 7.30e+11 -5.7 1.02e+06 - 1.00e+00 1.39e-01w 1\n", + " 43 0.0000000e+00 8.58e-04 7.30e+11 -5.7 7.14e+03 - 1.00e+00 2.07e-05w 1\n", + "In iteration 43, 2 Slacks too small, adjusting variable bounds\n", + " 44 0.0000000e+00 7.90e-04 5.95e+14 -5.7 4.69e+03 - 1.00e+00 8.02e-02w 1\n", + " 45 0.0000000e+00 3.76e-05 8.53e+07 -5.7 4.31e+03 - 1.00e+00 5.41e-04h 8\n", + " 46 0.0000000e+00 3.75e-05 9.64e+07 -5.7 1.02e+06 - 1.00e+00 5.39e-04h 9\n", + " 47 0.0000000e+00 3.75e-05 1.08e+08 -5.7 1.02e+06 - 1.00e+00 5.37e-04h 9\n", + " 48 0.0000000e+00 3.75e-05 1.19e+08 -5.7 1.02e+06 - 1.00e+00 5.35e-04h 9\n", + " 49 0.0000000e+00 3.75e-05 1.30e+08 -5.7 1.02e+06 - 1.00e+00 5.33e-04h 9\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 50 0.0000000e+00 3.75e-05 1.41e+08 -5.7 1.02e+06 - 1.00e+00 5.31e-04h 9\n", + " 51 0.0000000e+00 3.75e-05 1.52e+08 -5.7 1.02e+06 - 1.00e+00 5.29e-04h 9\n", + " 52 0.0000000e+00 3.75e-05 1.64e+08 -5.7 1.02e+06 - 1.00e+00 5.27e-04h 9\n", + " 53 0.0000000e+00 3.75e-05 1.75e+08 -5.7 1.02e+06 - 1.00e+00 5.25e-04h 9\n", + " 54 0.0000000e+00 3.75e-05 1.86e+08 -5.7 1.02e+06 - 1.00e+00 5.23e-04h 9\n", + " 55 0.0000000e+00 7.97e-04 7.34e+11 -5.7 1.02e+06 - 1.00e+00 1.33e-01w 1\n", + " 56 0.0000000e+00 7.97e-04 6.89e+11 -5.7 6.89e-05 16.0 2.81e-04 5.39e-01w 1\n", + " 57 0.0000000e+00 4.04e-07 2.66e+15 -5.7 4.36e+03 - 2.29e-07 1.00e+00h 1\n", + "Cannot recompute multipliers for feasibility problem. Error in eq_mult_calculator\n", + "\n", + "Number of Iterations....: 57\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 2.6563801083485440e+15 2.6563801083485440e+15\n", + "Constraint violation....: 4.0441652946975677e-07 4.0441652946975677e-07\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 4.0441652946975677e-07 2.6563801083485440e+15\n", + "\n", + "\n", + "Number of objective function evaluations = 337\n", + "Number of objective gradient evaluations = 59\n", + "Number of equality constraint evaluations = 337\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 59\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 58\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", + "Total CPU secs in NLP function evaluations = 0.008\n", + "\n", + "EXIT: Solved To Acceptable Level.\n" + ] + } + ], + "source": [ + "from idaes.core.util.model_statistics import degrees_of_freedom\n", + "import pytest\n", + "\n", + "test_data = {\n", + " \"temperature\": 298,\n", + " \"pressure\": 812323,\n", + " \"x_bmimPF6\": 0.86,\n", + " \"x_carbon_dioxide\": 0.14,\n", + "}\n", + "\n", + "m = PR_model(test_data)\n", + "\n", + "# Check that degrees of freedom is 0\n", + "assert degrees_of_freedom(m) == 0\n", + "\n", + "# Solve the model with the default solver and display results\n", + "solver = SolverFactory(\"ipopt\")\n", + "results = solver.solve(m, tee=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4.0 Parameter estimation using parmest \n", + "\n", + "### 4.1 Define the Experiment class\n", + "\n", + "Define the Experiment class to label model for parameter estimation." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "from pyomo.contrib.parmest.experiment import Experiment\n", + "\n", + "\n", + "# Create experiment class for parameter estimation\n", + "class PRExperiment(Experiment):\n", + "\n", + " def __init__(self, data, meas_error=None):\n", + " \"\"\"Initialize the PR Experiment class\n", + "\n", + " Args:\n", + " data: DataFrame containing the experimental data\n", + " meas_error: Measurement error for the data (optional)\n", + " \"\"\"\n", + " self.model = None\n", + " self.data = data\n", + " self.meas_error = meas_error\n", + "\n", + " def create_model(self):\n", + " \"\"\"Create the Pyomo model for the PR parameter estimation problem\"\"\"\n", + " self.model = PR_model(self.data)\n", + "\n", + " def label_model(self):\n", + " m = self.model\n", + "\n", + " # Add Suffixes to label the outputs, parameters, and measurement error in the model\n", + " m.experiment_outputs = Suffix(direction=Suffix.LOCAL)\n", + " m.experiment_outputs.update(\n", + " [(m.fs.state_block[1].pressure, self.data[\"pressure\"])]\n", + " )\n", + "\n", + " m.measurement_error = Suffix(direction=Suffix.LOCAL)\n", + " m.measurement_error.update([(m.fs.state_block[1].pressure, self.meas_error)])\n", + "\n", + " # Add unknown parameters to the model for easier access\n", + " m.unknown_parameters = Suffix(direction=Suffix.LOCAL)\n", + " m.unknown_parameters.update(\n", + " (k, value(k))\n", + " for k in [\n", + " m.fs.properties.PR_kappa[\"bmimPF6\", \"carbon_dioxide\"],\n", + " m.fs.properties.PR_kappa[\"carbon_dioxide\", \"bmimPF6\"],\n", + " ]\n", + " )\n", + "\n", + " def get_labeled_model(self):\n", + " \"\"\"Return the labeled model\"\"\"\n", + " if self.model is None:\n", + " self.create_model()\n", + " self.label_model()\n", + " return self.model" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 4.2 Pre-process the data into individual experiments\n", + "\n", + "We now separate our data and assign a model for each individual experiments, creating an experiment list. " + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "# Update to new interface\n", + "exp_list = []\n", + "for i in range(data.shape[0]):\n", + " exp_list.append(PRExperiment(data.iloc[i]))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 4.3 Run the parameter estimation\n", + "\n", + "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." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 846\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 720\n", + "\n", + "Total number of variables............................: 362\n", + " variables with only lower bounds: 72\n", + " variables with lower and upper bounds: 270\n", + " variables with only upper bounds: 18\n", + "Total number of equality constraints.................: 360\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 5.00e-01 2.44e-15 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 6.9602464e+06 4.12e-01 1.82e+07 -1.0 2.99e+04 - 3.39e-01 1.72e-01h 3\n", + " 2 1.6667677e+08 2.58e-01 2.70e+08 -1.0 2.58e+04 - 6.19e-01 7.79e-01h 1\n", + " 3 2.8786912e+08 1.32e-01 4.98e+07 -1.0 8.26e+03 - 8.13e-01 9.90e-01h 1\n", + " 4 2.9277551e+08 1.44e-01 5.76e+05 -1.0 3.05e+02 - 9.77e-01 9.90e-01h 1\n", + " 5 2.9282842e+08 3.31e-02 5.28e+03 -1.0 3.24e+00 - 9.90e-01 9.91e-01h 1\n", + " 6 2.9282891e+08 4.65e-03 8.12e+04 -1.0 1.08e+00 - 9.90e-01 1.00e+00h 1\n", + " 7 2.9282891e+08 3.59e-05 2.33e+04 -2.5 9.23e-02 - 9.97e-01 1.00e+00h 1\n", + " 8 2.9282891e+08 3.17e-09 2.26e-05 -3.8 8.65e-04 - 1.00e+00 1.00e+00h 1\n", + " 9 2.9282891e+08 1.29e-12 2.38e-05 -8.6 6.67e-08 - 1.00e+00 1.00e+00f 1\n", + "\n", + "Number of Iterations....: 9\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.9282891309627521e+08 2.9282891309627521e+08\n", + "Dual infeasibility......: 2.3841853781623475e-05 2.3841853781623475e-05\n", + "Constraint violation....: 1.2910152591875072e-12 1.2910152591875072e-12\n", + "Complementarity.........: 2.5062901281861244e-09 2.5062901281861244e-09\n", + "Overall NLP error.......: 2.5062901281861244e-09 2.3841853781623475e-05\n", + "\n", + "\n", + "Number of objective function evaluations = 12\n", + "Number of objective gradient evaluations = 10\n", + "Number of equality constraint evaluations = 12\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 10\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 9\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.006\n", + "Total CPU secs in NLP function evaluations = 0.020\n", + "\n", + "EXIT: Optimal Solution Found.\n" + ] + } + ], + "source": [ + "pest = parmest.Estimator(exp_list, obj_function=\"SSE\", tee=True)\n", + "obj_value, parameters = pest.theta_est()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 5.0 Display results\n", + "\n", + "Let us display the results by running the next cell." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The SSE at the optimal solution is 29.282891\n", + "\n", + "The values for the parameters are as follows:\n", + "fs.properties.PR_kappa[bmimPF6,carbon_dioxide] = -0.40714284008565715\n", + "fs.properties.PR_kappa[carbon_dioxide,bmimPF6] = 0.02059368400143062\n" + ] + } + ], + "source": [ + "print(f\"The SSE at the optimal solution is {obj_value*1e-7:0.6f}\")\n", + "print()\n", + "print(\"The values for the parameters are as follows:\")\n", + "for k, v in parameters.items():\n", + " print(f\"{k} = {v}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "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." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } - ], - "source": [ - "from idaes.core.util.model_statistics import degrees_of_freedom\n", - "import pytest\n", - "\n", - "test_data = {\n", - " \"temperature\": 298,\n", - " \"pressure\": 812323,\n", - " \"x_bmimPF6\": 0.86,\n", - " \"x_carbon_dioxide\": 0.14,\n", - "}\n", - "\n", - "m = PR_model(test_data)\n", - "\n", - "# Check that degrees of freedom is 0\n", - "assert degrees_of_freedom(m) == 0" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 4.0 Parameter estimation using parmest \n", - "\n", - "### 4.1 List of variable names to be estimated\n", - "\n", - "Create a list of vars to estimate" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [], - "source": [ - "variable_name = [\n", - " \"fs.properties.PR_kappa['bmimPF6', 'carbon_dioxide']\",\n", - " \"fs.properties.PR_kappa['carbon_dioxide', 'bmimPF6']\",\n", - "]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.2 Create method to return an expression that computes the sum of squared error\n", - "\n", - "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." - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [], - "source": [ - "def SSE(m, data):\n", - " expr = (float(data[\"pressure\"]) - m.fs.state_block[1].pressure) ** 2\n", - " return expr * 1e-7" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.3 Run the parameter estimation\n", - "\n", - "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." - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": { - "scrolled": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:00 [INFO] idaes.init.fs.state_block: Starting initialization\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "WARNING (W1002): Setting Var\n", - "'fs.state_block[1].log_mole_frac_tbub[Vap,Liq,carbon_dioxide]' to a numeric\n", - "value `4.301303339264284e-06` outside the bounds (None, 0).\n", - " See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:00 [INFO] idaes.init.fs.state_block: Dew and bubble point initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:00 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:00 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:00 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "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\n", - " x = float(data[\"x_carbon_dioxide\"]) + 0.5\n", - "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\n", - " m.fs.state_block[1].temperature.fix(float(data[\"temperature\"]))\n", - "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\n", - " m.fs.state_block[1].pressure.fix(float(data[\"pressure\"]))\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:00 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:00 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:00 [INFO] idaes.init.fs.state_block: Starting initialization\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "WARNING (W1002): Setting Var\n", - "'fs.state_block[1].log_mole_frac_tbub[Vap,Liq,carbon_dioxide]' to a numeric\n", - "value `4.814447495739171e-09` outside the bounds (None, 0).\n", - " See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:00 [INFO] idaes.init.fs.state_block: Dew and bubble point initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:00 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:00 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:00 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "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\n", - " m.fs.state_block[1].temperature.fix(float(data[\"temperature\"]))\n", - "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\n", - " float(data[\"x_bmimPF6\"])\n", - "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\n", - " float(data[\"x_carbon_dioxide\"])\n", - "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\n", - " m.fs.state_block[1].mole_frac_comp[\"bmimPF6\"].fix(float(data[\"x_bmimPF6\"]))\n", - "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\n", - " expr = (float(data[\"pressure\"]) - m.fs.state_block[1].pressure) ** 2\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:00 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:00 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:00 [INFO] idaes.init.fs.state_block: Starting initialization\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "WARNING (W1002): Setting Var\n", - "'fs.state_block[1].log_mole_frac_tbub[Vap,Liq,carbon_dioxide]' to a numeric\n", - "value `6.357548229111755e-06` outside the bounds (None, 0).\n", - " See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:00 [INFO] idaes.init.fs.state_block: Dew and bubble point initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:00 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:00 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:00 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: Starting initialization\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "WARNING (W1002): Setting Var\n", - "'fs.state_block[1].log_mole_frac_tbub[Vap,Liq,carbon_dioxide]' to a numeric\n", - "value `6.169320987299437e-07` outside the bounds (None, 0).\n", - " See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: Dew and bubble point initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: Starting initialization\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "WARNING (W1002): Setting Var\n", - "'fs.state_block[1].log_mole_frac_tbub[Vap,Liq,carbon_dioxide]' to a numeric\n", - "value `7.629131479751715e-08` outside the bounds (None, 0).\n", - " See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: Dew and bubble point initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: Starting initialization\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "WARNING (W1002): Setting Var\n", - "'fs.state_block[1].log_mole_frac_tbub[Vap,Liq,carbon_dioxide]' to a numeric\n", - "value `1.3059472085065408e-08` outside the bounds (None, 0).\n", - " See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: Dew and bubble point initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:01 [INFO] idaes.init.fs.state_block: Starting initialization\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "WARNING (W1002): Setting Var\n", - "'fs.state_block[1].log_mole_frac_tbub[Vap,Liq,carbon_dioxide]' to a numeric\n", - "value `4.761445527533956e-06` outside the bounds (None, 0).\n", - " See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:02 [INFO] idaes.init.fs.state_block: Dew and bubble point initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:02 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:02 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:02 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:02 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:02 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:02 [INFO] idaes.init.fs.state_block: Starting initialization\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "WARNING (W1002): Setting Var\n", - "'fs.state_block[1].log_mole_frac_tbub[Vap,Liq,carbon_dioxide]' to a numeric\n", - "value `7.219204097329158e-09` outside the bounds (None, 0).\n", - " See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:02 [INFO] idaes.init.fs.state_block: Dew and bubble point initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:02 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:02 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:02 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:02 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:02 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:02 [INFO] idaes.init.fs.state_block: Starting initialization\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "WARNING (W1002): Setting Var\n", - "'fs.state_block[1].log_mole_frac_tbub[Vap,Liq,carbon_dioxide]' to a numeric\n", - "value `1.03769179356835e-05` outside the bounds (None, 0).\n", - " See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:02 [INFO] idaes.init.fs.state_block: Dew and bubble point initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:02 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:02 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:02 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:02 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:02 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:02 [INFO] idaes.init.fs.state_block: Starting initialization\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "WARNING (W1002): Setting Var\n", - "'fs.state_block[1].log_mole_frac_tbub[Vap,Liq,carbon_dioxide]' to a numeric\n", - "value `1.269889598521249e-06` outside the bounds (None, 0).\n", - " See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: Dew and bubble point initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: Starting initialization\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "WARNING (W1002): Setting Var\n", - "'fs.state_block[1].log_mole_frac_tbub[Vap,Liq,carbon_dioxide]' to a numeric\n", - "value `2.021447098567687e-07` outside the bounds (None, 0).\n", - " See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: Dew and bubble point initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: Starting initialization\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "WARNING (W1002): Setting Var\n", - "'fs.state_block[1].log_mole_frac_tbub[Vap,Liq,carbon_dioxide]' to a numeric\n", - "value `4.096574706592338e-08` outside the bounds (None, 0).\n", - " See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: Dew and bubble point initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: Starting initialization\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "WARNING (W1002): Setting Var\n", - "'fs.state_block[1].log_mole_frac_tbub[Vap,Liq,carbon_dioxide]' to a numeric\n", - "value `6.21086636630859e-06` outside the bounds (None, 0).\n", - " See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: Dew and bubble point initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:03 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:04 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:04 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:04 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:04 [INFO] idaes.init.fs.state_block: Starting initialization\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "WARNING (W1002): Setting Var\n", - "'fs.state_block[1].log_mole_frac_tbub[Vap,Liq,carbon_dioxide]' to a numeric\n", - "value `1.1919675619879674e-08` outside the bounds (None, 0).\n", - " See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:04 [INFO] idaes.init.fs.state_block: Dew and bubble point initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:04 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:04 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:04 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:04 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:04 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:04 [INFO] idaes.init.fs.state_block: Starting initialization\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "WARNING (W1002): Setting Var\n", - "'fs.state_block[1].log_mole_frac_tbub[Vap,Liq,carbon_dioxide]' to a numeric\n", - "value `1.0197309662820167e-10` outside the bounds (None, 0).\n", - " See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:04 [INFO] idaes.init.fs.state_block: Dew and bubble point initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:04 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:04 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:04 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:04 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:04 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:04 [INFO] idaes.init.fs.state_block: Starting initialization\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "WARNING (W1002): Setting Var\n", - "'fs.state_block[1].log_mole_frac_tbub[Vap,Liq,carbon_dioxide]' to a numeric\n", - "value `2.385494860297472e-06` outside the bounds (None, 0).\n", - " See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:05 [INFO] idaes.init.fs.state_block: Dew and bubble point initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:05 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:05 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:05 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:05 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:05 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:05 [INFO] idaes.init.fs.state_block: Starting initialization\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "WARNING (W1002): Setting Var\n", - "'fs.state_block[1].log_mole_frac_tbub[Vap,Liq,carbon_dioxide]' to a numeric\n", - "value `4.578395178499122e-07` outside the bounds (None, 0).\n", - " See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:05 [INFO] idaes.init.fs.state_block: Dew and bubble point initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:05 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:05 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:05 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:05 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:05 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:05 [INFO] idaes.init.fs.state_block: Starting initialization\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "WARNING (W1002): Setting Var\n", - "'fs.state_block[1].log_mole_frac_tbub[Vap,Liq,carbon_dioxide]' to a numeric\n", - "value `1.0835202436687703e-07` outside the bounds (None, 0).\n", - " See also https://pyomo.readthedocs.io/en/stable/errors.html#w1002\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:05 [INFO] idaes.init.fs.state_block: Dew and bubble point initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:05 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:05 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:05 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:05 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2023-11-02 10:30:05 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 842\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 720\n", - "\n", - "Total number of variables............................: 360\n", - " variables with only lower bounds: 72\n", - " variables with lower and upper bounds: 234\n", - " variables with only upper bounds: 18\n", - "Total number of equality constraints.................: 358\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 5.00e-01 6.99e-14 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 1.1422488e+01 2.60e-01 2.37e+03 -1.0 3.35e+04 - 3.39e-01 6.89e-01h 1\n", - " 2 2.8748813e+01 1.27e-01 1.10e+03 -1.0 1.36e+04 - 8.22e-02 9.88e-01h 1\n", - " 3 2.9813930e+01 1.87e-01 5.94e+02 -1.0 5.01e+02 - 8.73e-01 9.90e-01h 1\n", - " 4 2.9709737e+01 4.27e-02 1.57e+03 -1.0 5.49e+02 - 9.85e-01 9.90e-01h 1\n", - " 5 2.9285216e+01 8.02e-03 9.53e+04 -1.0 2.77e+03 - 9.87e-01 1.00e+00h 1\n", - " 6 2.9283589e+01 1.44e-04 9.56e+04 -1.0 3.48e+02 - 9.90e-01 1.00e+00h 1\n", - " 7 2.9283603e+01 7.59e-08 9.12e+02 -1.0 5.97e-01 - 9.90e-01 1.00e+00h 1\n", - " 8 2.9282891e+01 3.35e-07 1.47e+04 -2.5 1.24e+02 - 9.98e-01 1.00e+00f 1\n", - " 9 2.9282892e+01 2.21e-12 4.97e-08 -2.5 2.39e-01 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 2.9282891e+01 2.85e-10 3.05e+00 -8.6 3.61e+00 - 1.00e+00 1.00e+00h 1\n", - " 11 2.9282891e+01 2.72e-12 3.60e-12 -8.6 2.03e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 11\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.9282891309640156e+01 2.9282891309640156e+01\n", - "Dual infeasibility......: 3.6021722623181066e-12 3.6021722623181066e-12\n", - "Constraint violation....: 2.7191470654339899e-12 2.7191470654339899e-12\n", - "Complementarity.........: 2.5059037693947522e-09 2.5059037693947522e-09\n", - "Overall NLP error.......: 2.5059037693947522e-09 2.5059037693947522e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 12\n", - "Number of objective gradient evaluations = 12\n", - "Number of equality constraint evaluations = 12\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 12\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 11\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.000\n", - "Total CPU secs in NLP function evaluations = 0.048\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "\b\b\b\b\b\b\b\b\b\b\b\b\b\b" - ] - } - ], - "source": [ - "pest = parmest.Estimator(PR_model, data, variable_name, SSE, tee=True)\n", - "\n", - "obj_value, parameters = pest.theta_est()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 5.0 Display results\n", - "\n", - "Let us display the results by running the next cell." - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The SSE at the optimal solution is 29.282891\n", - "\n", - "The values for the parameters are as follows:\n", - "fs.properties.PR_kappa[bmimPF6,carbon_dioxide] = -0.4071428400296551\n", - "fs.properties.PR_kappa[carbon_dioxide,bmimPF6] = 0.020593684002515204\n" - ] + ], + "metadata": { + "kernelspec": { + "display_name": "idaes-pse-and-examples-dev-py313-macmini", + "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.13.13" } - ], - "source": [ - "print(\"The SSE at the optimal solution is %0.6f\" % obj_value)\n", - "print()\n", - "print(\"The values for the parameters are as follows:\")\n", - "for k, v in parameters.items():\n", - " print(k, \"=\", v)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "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." - ] - }, - { - "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.11.5" - } - }, - "nbformat": 4, - "nbformat_minor": 3 -} + "nbformat": 4, + "nbformat_minor": 3 +} \ No newline at end of file diff --git a/idaes_examples/notebooks/docs/properties/parameter_estimation_pr_test.ipynb b/idaes_examples/notebooks/docs/properties/parameter_estimation_pr_test.ipynb index 4d620a5a..e42c5b93 100644 --- a/idaes_examples/notebooks/docs/properties/parameter_estimation_pr_test.ipynb +++ b/idaes_examples/notebooks/docs/properties/parameter_estimation_pr_test.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": { "tags": [ "header", @@ -16,7 +16,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", @@ -31,8 +31,8 @@ "source": [ "# Using Parameter Estimation with Modular Property Packages\n", "Author: Alejandro Garciadego \n", - "Maintainer: Andrew Lee \n", - "Updated: 2023-06-01 \n", + "Maintainer: Stephen Cini \n", + "Updated: 2026-06-11 \n", "## 1. Introduction\n", "\n", "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.\n", @@ -57,12 +57,12 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "# Import objects from pyomo package\n", - "from pyomo.environ import ConcreteModel, SolverFactory, units as pyunits\n", + "from pyomo.environ import ConcreteModel, SolverFactory, value, Suffix\n", "\n", "# Import the main FlowsheetBlock from IDAES. The flowsheet block will contain the unit model\n", "from idaes.core import FlowsheetBlock\n", @@ -83,7 +83,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -99,7 +99,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -121,7 +121,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -146,7 +146,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -161,9 +161,16 @@ " m.fs.state_block = m.fs.properties.build_state_block([1], defined_state=True)\n", "\n", " m.fs.state_block[1].flow_mol.fix(1)\n", - " x = float(data[\"x_carbon_dioxide\"]) + 0.5\n", - " m.fs.state_block[1].temperature.fix(float(data[\"temperature\"]))\n", - " m.fs.state_block[1].pressure.fix(float(data[\"pressure\"]))\n", + " if isinstance(data, dict) or isinstance(data, pd.Series):\n", + " x = float(data[\"x_carbon_dioxide\"]) + 0.5\n", + " m.fs.state_block[1].temperature.fix(float(data[\"temperature\"]))\n", + " m.fs.state_block[1].pressure.fix(float(data[\"pressure\"]))\n", + " elif isinstance(data, pd.DataFrame):\n", + " x = float(data.iloc[0][\"x_carbon_dioxide\"]) + 0.5\n", + " m.fs.state_block[1].temperature.fix(float(data.iloc[0][\"temperature\"]))\n", + " m.fs.state_block[1].pressure.fix(float(data.iloc[0][\"pressure\"]))\n", + " else:\n", + " raise ValueError(\"Unrecognized data type.\")\n", " m.fs.state_block[1].mole_frac_comp[\"bmimPF6\"].fix(1 - x)\n", " m.fs.state_block[1].mole_frac_comp[\"carbon_dioxide\"].fix(x)\n", "\n", @@ -177,15 +184,30 @@ " m.fs.state_block.initialize(outlvl=idaeslog.INFO)\n", "\n", " # Fix the state variables on the state block\n", + " if isinstance(data, dict) or isinstance(data, pd.Series):\n", + " m.fs.state_block[1].temperature.fix(float(data[\"temperature\"]))\n", + " m.fs.state_block[1].mole_frac_phase_comp[\"Liq\", \"bmimPF6\"].fix(\n", + " float(data[\"x_bmimPF6\"])\n", + " )\n", + " m.fs.state_block[1].mole_frac_phase_comp[\"Liq\", \"carbon_dioxide\"].fix(\n", + " float(data[\"x_carbon_dioxide\"])\n", + " )\n", + " m.fs.state_block[1].mole_frac_comp[\"bmimPF6\"].fix(float(data[\"x_bmimPF6\"]))\n", + " elif isinstance(data, pd.DataFrame):\n", + " m.fs.state_block[1].temperature.fix(float(data.iloc[0][\"temperature\"]))\n", + " m.fs.state_block[1].mole_frac_phase_comp[\"Liq\", \"bmimPF6\"].fix(\n", + " float(data.iloc[0][\"x_bmimPF6\"])\n", + " )\n", + " m.fs.state_block[1].mole_frac_phase_comp[\"Liq\", \"carbon_dioxide\"].fix(\n", + " float(data.iloc[0][\"x_carbon_dioxide\"])\n", + " )\n", + " m.fs.state_block[1].mole_frac_comp[\"bmimPF6\"].fix(\n", + " float(data.iloc[0][\"x_bmimPF6\"])\n", + " )\n", + " else:\n", + " raise ValueError(\"Unrecognized data type.\")\n", + "\n", " m.fs.state_block[1].pressure.unfix()\n", - " m.fs.state_block[1].temperature.fix(float(data[\"temperature\"]))\n", - " m.fs.state_block[1].mole_frac_phase_comp[\"Liq\", \"bmimPF6\"].fix(\n", - " float(data[\"x_bmimPF6\"])\n", - " )\n", - " m.fs.state_block[1].mole_frac_phase_comp[\"Liq\", \"carbon_dioxide\"].fix(\n", - " float(data[\"x_carbon_dioxide\"])\n", - " )\n", - " m.fs.state_block[1].mole_frac_comp[\"bmimPF6\"].fix(float(data[\"x_bmimPF6\"]))\n", " m.fs.state_block[1].mole_frac_comp[\"carbon_dioxide\"].unfix()\n", " # Set bounds on variables to be estimated\n", " m.fs.properties.PR_kappa[\"bmimPF6\", \"carbon_dioxide\"].setlb(-5)\n", @@ -207,11 +229,147 @@ }, { "cell_type": "code", - "execution_count": 6, - "metadata": { - "scrolled": false - }, - "outputs": [], + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2026-06-11 12:42:22 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 39\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 25\n", + "\n", + "Total number of variables............................: 18\n", + " variables with only lower bounds: 4\n", + " variables with lower and upper bounds: 13\n", + " variables with only upper bounds: 1\n", + "Total number of equality constraints.................: 18\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 5.00e-01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 0.0000000e+00 1.76e-01 6.65e+03 -1.0 7.51e+04 - 2.67e-01 9.90e-01H 1\n", + " 2 0.0000000e+00 4.81e-02 1.40e+02 -1.0 6.76e+02 - 9.46e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 8.65e-03 1.76e+01 -1.0 9.79e+00 - 9.90e-01 9.90e-01h 1\n", + " 4 0.0000000e+00 1.81e-03 4.99e+04 -1.0 1.20e+00 - 9.90e-01 1.00e+00h 1\n", + " 5 0.0000000e+00 3.48e-03 9.81e+04 -1.0 5.29e+01 - 9.90e-01 1.00e+00h 1\n", + " 6 0.0000000e+00 1.57e-03 8.00e+02 -1.0 1.54e+02 - 9.92e-01 1.00e+00h 1\n", + " 7 0.0000000e+00 7.66e-04 2.93e-04 -2.5 2.52e+02 - 1.00e+00 1.00e+00h 1\n", + " 8 0.0000000e+00 3.81e-04 1.61e-04 -5.7 4.82e+02 - 1.00e+00 1.00e+00h 1\n", + " 9 0.0000000e+00 1.90e-04 6.49e-05 -5.7 9.53e+02 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 0.0000000e+00 9.50e-05 8.68e-05 -5.7 1.90e+03 - 1.00e+00 1.00e+00h 1\n", + " 11 0.0000000e+00 4.75e-05 3.47e-04 -5.7 3.81e+03 - 1.00e+00 1.00e+00h 1\n", + " 12 0.0000000e+00 2.72e-05 1.39e-03 -5.7 7.64e+03 - 1.00e+00 1.00e+00h 1\n", + " 13 0.0000000e+00 1.07e-04 5.57e-03 -5.7 1.54e+04 - 1.00e+00 1.00e+00h 1\n", + " 14 0.0000000e+00 4.09e-04 2.23e-02 -5.7 3.11e+04 - 1.00e+00 1.00e+00h 1\n", + " 15 0.0000000e+00 1.51e-03 8.91e-02 -5.7 6.38e+04 - 1.00e+00 1.00e+00h 1\n", + " 16 0.0000000e+00 5.12e-03 3.53e-01 -5.7 1.33e+05 - 1.00e+00 1.00e+00h 1\n", + " 17 0.0000000e+00 1.49e-02 1.34e+00 -5.7 2.89e+05 - 1.00e+00 1.00e+00h 1\n", + " 18 0.0000000e+00 3.14e-02 4.58e+00 -5.7 6.55e+05 - 1.00e+00 1.00e+00h 1\n", + " 19 0.0000000e+00 2.86e-02 4.32e+00 -5.7 1.51e+06 - 1.00e+00 1.25e-01h 4\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 0.0000000e+00 2.82e-02 4.26e+00 -5.7 1.73e+06 - 1.00e+00 1.56e-02h 7\n", + " 21 0.0000000e+00 2.79e-02 4.23e+00 -5.7 1.76e+06 - 1.00e+00 7.81e-03h 8\n", + " 22 0.0000000e+00 2.79e-02 4.22e+00 -5.7 1.77e+06 - 1.00e+00 4.88e-04h 12\n", + " 23 0.0000000e+00 2.79e-02 4.22e+00 -5.7 1.77e+06 - 1.00e+00 1.22e-04h 14\n", + " 24 0.0000000e+00 7.05e-03 1.51e+01 -5.7 1.77e+06 - 1.00e+00 1.00e+00h 1\n", + " 25 0.0000000e+00 9.63e-04 4.01e+00 -5.7 3.18e+06 - 1.00e+00 1.50e-01h 2\n", + " 26 0.0000000e+00 5.53e-04 8.54e+01 -5.7 3.24e+06 - 1.00e+00 6.53e-02h 2\n", + " 27 0.0000000e+00 5.53e-04 8.57e+01 -5.7 3.20e+06 - 1.00e+00 9.58e-04h 7\n", + " 28 0.0000000e+00 5.53e-04 9.27e+01 -5.7 3.19e+06 - 1.00e+00 9.42e-04h 7\n", + " 29 0.0000000e+00 5.53e-04 2.08e+02 -5.7 3.19e+06 - 1.00e+00 9.27e-04h 7\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30 0.0000000e+00 5.52e-04 7.91e+03 -5.7 1.83e+06 - 1.00e+00 3.17e-03h 6\n", + " 31 0.0000000e+00 3.77e-05 2.11e+06 -5.7 2.63e+04 - 1.00e+00 1.00e+00h 1\n", + " 32 0.0000000e+00 3.77e-05 2.10e+06 -5.7 1.03e+06 - 1.00e+00 5.67e-04h 9\n", + " 33 0.0000000e+00 3.77e-05 2.10e+06 -5.7 1.03e+06 - 1.00e+00 5.65e-04h 9\n", + " 34 0.0000000e+00 3.77e-05 2.10e+06 -5.7 1.02e+06 - 1.00e+00 5.63e-04h 9\n", + " 35 0.0000000e+00 3.77e-05 2.12e+06 -5.7 9.14e+05 - 1.00e+00 6.29e-04h 9\n", + " 36 0.0000000e+00 3.77e-05 2.23e+06 -5.7 9.36e+05 - 1.00e+00 6.11e-04h 9\n", + " 37 0.0000000e+00 3.76e-05 4.98e+06 -5.7 4.23e+05 - 1.00e+00 2.69e-03h 8\n", + " 38 0.0000000e+00 3.76e-05 6.97e+06 -5.7 8.98e+05 - 1.00e+00 6.29e-04h 9\n", + " 39 0.0000000e+00 3.76e-05 5.17e+07 -5.7 6.09e+05 - 1.00e+00 1.85e-03h 8\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 40 0.0000000e+00 3.76e-05 6.29e+07 -5.7 1.03e+06 - 1.00e+00 5.42e-04h 9\n", + " 41 0.0000000e+00 3.76e-05 7.41e+07 -5.7 1.02e+06 - 1.00e+00 5.43e-04h 9\n", + " 42 0.0000000e+00 8.59e-04 7.30e+11 -5.7 1.02e+06 - 1.00e+00 1.39e-01w 1\n", + " 43 0.0000000e+00 8.58e-04 7.30e+11 -5.7 7.14e+03 - 1.00e+00 2.07e-05w 1\n", + "In iteration 43, 2 Slacks too small, adjusting variable bounds\n", + " 44 0.0000000e+00 7.90e-04 5.95e+14 -5.7 4.69e+03 - 1.00e+00 8.02e-02w 1\n", + " 45 0.0000000e+00 3.76e-05 8.53e+07 -5.7 4.31e+03 - 1.00e+00 5.41e-04h 8\n", + " 46 0.0000000e+00 3.75e-05 9.64e+07 -5.7 1.02e+06 - 1.00e+00 5.39e-04h 9\n", + " 47 0.0000000e+00 3.75e-05 1.08e+08 -5.7 1.02e+06 - 1.00e+00 5.37e-04h 9\n", + " 48 0.0000000e+00 3.75e-05 1.19e+08 -5.7 1.02e+06 - 1.00e+00 5.35e-04h 9\n", + " 49 0.0000000e+00 3.75e-05 1.30e+08 -5.7 1.02e+06 - 1.00e+00 5.33e-04h 9\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 50 0.0000000e+00 3.75e-05 1.41e+08 -5.7 1.02e+06 - 1.00e+00 5.31e-04h 9\n", + " 51 0.0000000e+00 3.75e-05 1.52e+08 -5.7 1.02e+06 - 1.00e+00 5.29e-04h 9\n", + " 52 0.0000000e+00 3.75e-05 1.64e+08 -5.7 1.02e+06 - 1.00e+00 5.27e-04h 9\n", + " 53 0.0000000e+00 3.75e-05 1.75e+08 -5.7 1.02e+06 - 1.00e+00 5.25e-04h 9\n", + " 54 0.0000000e+00 3.75e-05 1.86e+08 -5.7 1.02e+06 - 1.00e+00 5.23e-04h 9\n", + " 55 0.0000000e+00 7.97e-04 7.34e+11 -5.7 1.02e+06 - 1.00e+00 1.33e-01w 1\n", + " 56 0.0000000e+00 7.97e-04 6.89e+11 -5.7 6.89e-05 16.0 2.81e-04 5.39e-01w 1\n", + " 57 0.0000000e+00 4.04e-07 2.66e+15 -5.7 4.36e+03 - 2.29e-07 1.00e+00h 1\n", + "Cannot recompute multipliers for feasibility problem. Error in eq_mult_calculator\n", + "\n", + "Number of Iterations....: 57\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 2.6563801083485440e+15 2.6563801083485440e+15\n", + "Constraint violation....: 4.0441652946975677e-07 4.0441652946975677e-07\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 4.0441652946975677e-07 2.6563801083485440e+15\n", + "\n", + "\n", + "Number of objective function evaluations = 337\n", + "Number of objective gradient evaluations = 59\n", + "Number of equality constraint evaluations = 337\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 59\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 58\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", + "Total CPU secs in NLP function evaluations = 0.008\n", + "\n", + "EXIT: Solved To Acceptable Level.\n" + ] + } + ], "source": [ "from idaes.core.util.model_statistics import degrees_of_freedom\n", "import pytest\n", @@ -226,7 +384,11 @@ "m = PR_model(test_data)\n", "\n", "# Check that degrees of freedom is 0\n", - "assert degrees_of_freedom(m) == 0" + "assert degrees_of_freedom(m) == 0\n", + "\n", + "# Solve the model with the default solver and display results\n", + "solver = SolverFactory(\"ipopt\")\n", + "results = solver.solve(m, tee=True)" ] }, { @@ -235,41 +397,87 @@ "source": [ "## 4.0 Parameter estimation using parmest \n", "\n", - "### 4.1 List of variable names to be estimated\n", + "### 4.1 Define the Experiment class\n", "\n", - "Create a list of vars to estimate" + "Define the Experiment class to label model for parameter estimation." ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 8, "metadata": {}, "outputs": [], "source": [ - "variable_name = [\n", - " \"fs.properties.PR_kappa['bmimPF6', 'carbon_dioxide']\",\n", - " \"fs.properties.PR_kappa['carbon_dioxide', 'bmimPF6']\",\n", - "]" + "from pyomo.contrib.parmest.experiment import Experiment\n", + "\n", + "\n", + "# Create experiment class for parameter estimation\n", + "class PRExperiment(Experiment):\n", + "\n", + " def __init__(self, data, meas_error=None):\n", + " \"\"\"Initialize the PR Experiment class\n", + "\n", + " Args:\n", + " data: DataFrame containing the experimental data\n", + " meas_error: Measurement error for the data (optional)\n", + " \"\"\"\n", + " self.model = None\n", + " self.data = data\n", + " self.meas_error = meas_error\n", + "\n", + " def create_model(self):\n", + " \"\"\"Create the Pyomo model for the PR parameter estimation problem\"\"\"\n", + " self.model = PR_model(self.data)\n", + "\n", + " def label_model(self):\n", + " m = self.model\n", + "\n", + " # Add Suffixes to label the outputs, parameters, and measurement error in the model\n", + " m.experiment_outputs = Suffix(direction=Suffix.LOCAL)\n", + " m.experiment_outputs.update(\n", + " [(m.fs.state_block[1].pressure, self.data[\"pressure\"])]\n", + " )\n", + "\n", + " m.measurement_error = Suffix(direction=Suffix.LOCAL)\n", + " m.measurement_error.update([(m.fs.state_block[1].pressure, self.meas_error)])\n", + "\n", + " # Add unknown parameters to the model for easier access\n", + " m.unknown_parameters = Suffix(direction=Suffix.LOCAL)\n", + " m.unknown_parameters.update(\n", + " (k, value(k))\n", + " for k in [\n", + " m.fs.properties.PR_kappa[\"bmimPF6\", \"carbon_dioxide\"],\n", + " m.fs.properties.PR_kappa[\"carbon_dioxide\", \"bmimPF6\"],\n", + " ]\n", + " )\n", + "\n", + " def get_labeled_model(self):\n", + " \"\"\"Return the labeled model\"\"\"\n", + " if self.model is None:\n", + " self.create_model()\n", + " self.label_model()\n", + " return self.model" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### 4.2 Create method to return an expression that computes the sum of squared error\n", + "### 4.2 Pre-process the data into individual experiments\n", "\n", - "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." + "We now separate our data and assign a model for each individual experiments, creating an experiment list. " ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ - "def SSE(m, data):\n", - " expr = (float(data[\"pressure\"]) - m.fs.state_block[1].pressure) ** 2\n", - " return expr * 1e-7" + "# Update to new interface\n", + "exp_list = []\n", + "for i in range(data.shape[0]):\n", + " exp_list.append(PRExperiment(data.iloc[i]))" ] }, { @@ -278,19 +486,218 @@ "source": [ "### 4.3 Run the parameter estimation\n", "\n", - "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." + "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." ] }, { "cell_type": "code", - "execution_count": 9, - "metadata": { - "scrolled": false - }, - "outputs": [], + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 846\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 720\n", + "\n", + "Total number of variables............................: 362\n", + " variables with only lower bounds: 72\n", + " variables with lower and upper bounds: 270\n", + " variables with only upper bounds: 18\n", + "Total number of equality constraints.................: 360\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 5.00e-01 2.44e-15 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 6.9602464e+06 4.12e-01 1.82e+07 -1.0 2.99e+04 - 3.39e-01 1.72e-01h 3\n", + " 2 1.6667677e+08 2.58e-01 2.70e+08 -1.0 2.58e+04 - 6.19e-01 7.79e-01h 1\n", + " 3 2.8786912e+08 1.32e-01 4.98e+07 -1.0 8.26e+03 - 8.13e-01 9.90e-01h 1\n", + " 4 2.9277551e+08 1.44e-01 5.76e+05 -1.0 3.05e+02 - 9.77e-01 9.90e-01h 1\n", + " 5 2.9282842e+08 3.31e-02 5.28e+03 -1.0 3.24e+00 - 9.90e-01 9.91e-01h 1\n", + " 6 2.9282891e+08 4.65e-03 8.12e+04 -1.0 1.08e+00 - 9.90e-01 1.00e+00h 1\n", + " 7 2.9282891e+08 3.59e-05 2.33e+04 -2.5 9.23e-02 - 9.97e-01 1.00e+00h 1\n", + " 8 2.9282891e+08 3.17e-09 2.26e-05 -3.8 8.65e-04 - 1.00e+00 1.00e+00h 1\n", + " 9 2.9282891e+08 1.29e-12 2.38e-05 -8.6 6.67e-08 - 1.00e+00 1.00e+00f 1\n", + "\n", + "Number of Iterations....: 9\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.9282891309627521e+08 2.9282891309627521e+08\n", + "Dual infeasibility......: 2.3841853781623475e-05 2.3841853781623475e-05\n", + "Constraint violation....: 1.2910152591875072e-12 1.2910152591875072e-12\n", + "Complementarity.........: 2.5062901281861244e-09 2.5062901281861244e-09\n", + "Overall NLP error.......: 2.5062901281861244e-09 2.3841853781623475e-05\n", + "\n", + "\n", + "Number of objective function evaluations = 12\n", + "Number of objective gradient evaluations = 10\n", + "Number of equality constraint evaluations = 12\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 10\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 9\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.006\n", + "Total CPU secs in NLP function evaluations = 0.020\n", + "\n", + "EXIT: Optimal Solution Found.\n" + ] + } + ], "source": [ - "pest = parmest.Estimator(PR_model, data, variable_name, SSE, tee=True)\n", - "\n", + "pest = parmest.Estimator(exp_list, obj_function=\"SSE\", tee=True)\n", "obj_value, parameters = pest.theta_est()" ] }, @@ -305,15 +712,27 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 11, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The SSE at the optimal solution is 29.282891\n", + "\n", + "The values for the parameters are as follows:\n", + "fs.properties.PR_kappa[bmimPF6,carbon_dioxide] = -0.40714284008565715\n", + "fs.properties.PR_kappa[carbon_dioxide,bmimPF6] = 0.02059368400143062\n" + ] + } + ], "source": [ - "print(\"The SSE at the optimal solution is %0.6f\" % obj_value)\n", + "print(f\"The SSE at the optimal solution is {obj_value*1e-7:0.6f}\")\n", "print()\n", "print(\"The values for the parameters are as follows:\")\n", "for k, v in parameters.items():\n", - " print(k, \"=\", v)" + " print(f\"{k} = {v}\")" ] }, { @@ -333,7 +752,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "idaes-pse-and-examples-dev-py313-macmini", "language": "python", "name": "python3" }, @@ -347,9 +766,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.12" + "version": "3.13.13" } }, "nbformat": 4, "nbformat_minor": 3 -} +} \ No newline at end of file diff --git a/idaes_examples/notebooks/docs/properties/parameter_estimation_pr_usr.ipynb b/idaes_examples/notebooks/docs/properties/parameter_estimation_pr_usr.ipynb index 4d620a5a..e42c5b93 100644 --- a/idaes_examples/notebooks/docs/properties/parameter_estimation_pr_usr.ipynb +++ b/idaes_examples/notebooks/docs/properties/parameter_estimation_pr_usr.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": { "tags": [ "header", @@ -16,7 +16,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", @@ -31,8 +31,8 @@ "source": [ "# Using Parameter Estimation with Modular Property Packages\n", "Author: Alejandro Garciadego \n", - "Maintainer: Andrew Lee \n", - "Updated: 2023-06-01 \n", + "Maintainer: Stephen Cini \n", + "Updated: 2026-06-11 \n", "## 1. Introduction\n", "\n", "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.\n", @@ -57,12 +57,12 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "# Import objects from pyomo package\n", - "from pyomo.environ import ConcreteModel, SolverFactory, units as pyunits\n", + "from pyomo.environ import ConcreteModel, SolverFactory, value, Suffix\n", "\n", "# Import the main FlowsheetBlock from IDAES. The flowsheet block will contain the unit model\n", "from idaes.core import FlowsheetBlock\n", @@ -83,7 +83,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -99,7 +99,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -121,7 +121,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -146,7 +146,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -161,9 +161,16 @@ " m.fs.state_block = m.fs.properties.build_state_block([1], defined_state=True)\n", "\n", " m.fs.state_block[1].flow_mol.fix(1)\n", - " x = float(data[\"x_carbon_dioxide\"]) + 0.5\n", - " m.fs.state_block[1].temperature.fix(float(data[\"temperature\"]))\n", - " m.fs.state_block[1].pressure.fix(float(data[\"pressure\"]))\n", + " if isinstance(data, dict) or isinstance(data, pd.Series):\n", + " x = float(data[\"x_carbon_dioxide\"]) + 0.5\n", + " m.fs.state_block[1].temperature.fix(float(data[\"temperature\"]))\n", + " m.fs.state_block[1].pressure.fix(float(data[\"pressure\"]))\n", + " elif isinstance(data, pd.DataFrame):\n", + " x = float(data.iloc[0][\"x_carbon_dioxide\"]) + 0.5\n", + " m.fs.state_block[1].temperature.fix(float(data.iloc[0][\"temperature\"]))\n", + " m.fs.state_block[1].pressure.fix(float(data.iloc[0][\"pressure\"]))\n", + " else:\n", + " raise ValueError(\"Unrecognized data type.\")\n", " m.fs.state_block[1].mole_frac_comp[\"bmimPF6\"].fix(1 - x)\n", " m.fs.state_block[1].mole_frac_comp[\"carbon_dioxide\"].fix(x)\n", "\n", @@ -177,15 +184,30 @@ " m.fs.state_block.initialize(outlvl=idaeslog.INFO)\n", "\n", " # Fix the state variables on the state block\n", + " if isinstance(data, dict) or isinstance(data, pd.Series):\n", + " m.fs.state_block[1].temperature.fix(float(data[\"temperature\"]))\n", + " m.fs.state_block[1].mole_frac_phase_comp[\"Liq\", \"bmimPF6\"].fix(\n", + " float(data[\"x_bmimPF6\"])\n", + " )\n", + " m.fs.state_block[1].mole_frac_phase_comp[\"Liq\", \"carbon_dioxide\"].fix(\n", + " float(data[\"x_carbon_dioxide\"])\n", + " )\n", + " m.fs.state_block[1].mole_frac_comp[\"bmimPF6\"].fix(float(data[\"x_bmimPF6\"]))\n", + " elif isinstance(data, pd.DataFrame):\n", + " m.fs.state_block[1].temperature.fix(float(data.iloc[0][\"temperature\"]))\n", + " m.fs.state_block[1].mole_frac_phase_comp[\"Liq\", \"bmimPF6\"].fix(\n", + " float(data.iloc[0][\"x_bmimPF6\"])\n", + " )\n", + " m.fs.state_block[1].mole_frac_phase_comp[\"Liq\", \"carbon_dioxide\"].fix(\n", + " float(data.iloc[0][\"x_carbon_dioxide\"])\n", + " )\n", + " m.fs.state_block[1].mole_frac_comp[\"bmimPF6\"].fix(\n", + " float(data.iloc[0][\"x_bmimPF6\"])\n", + " )\n", + " else:\n", + " raise ValueError(\"Unrecognized data type.\")\n", + "\n", " m.fs.state_block[1].pressure.unfix()\n", - " m.fs.state_block[1].temperature.fix(float(data[\"temperature\"]))\n", - " m.fs.state_block[1].mole_frac_phase_comp[\"Liq\", \"bmimPF6\"].fix(\n", - " float(data[\"x_bmimPF6\"])\n", - " )\n", - " m.fs.state_block[1].mole_frac_phase_comp[\"Liq\", \"carbon_dioxide\"].fix(\n", - " float(data[\"x_carbon_dioxide\"])\n", - " )\n", - " m.fs.state_block[1].mole_frac_comp[\"bmimPF6\"].fix(float(data[\"x_bmimPF6\"]))\n", " m.fs.state_block[1].mole_frac_comp[\"carbon_dioxide\"].unfix()\n", " # Set bounds on variables to be estimated\n", " m.fs.properties.PR_kappa[\"bmimPF6\", \"carbon_dioxide\"].setlb(-5)\n", @@ -207,11 +229,147 @@ }, { "cell_type": "code", - "execution_count": 6, - "metadata": { - "scrolled": false - }, - "outputs": [], + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2026-06-11 12:42:22 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 39\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 25\n", + "\n", + "Total number of variables............................: 18\n", + " variables with only lower bounds: 4\n", + " variables with lower and upper bounds: 13\n", + " variables with only upper bounds: 1\n", + "Total number of equality constraints.................: 18\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 5.00e-01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 0.0000000e+00 1.76e-01 6.65e+03 -1.0 7.51e+04 - 2.67e-01 9.90e-01H 1\n", + " 2 0.0000000e+00 4.81e-02 1.40e+02 -1.0 6.76e+02 - 9.46e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 8.65e-03 1.76e+01 -1.0 9.79e+00 - 9.90e-01 9.90e-01h 1\n", + " 4 0.0000000e+00 1.81e-03 4.99e+04 -1.0 1.20e+00 - 9.90e-01 1.00e+00h 1\n", + " 5 0.0000000e+00 3.48e-03 9.81e+04 -1.0 5.29e+01 - 9.90e-01 1.00e+00h 1\n", + " 6 0.0000000e+00 1.57e-03 8.00e+02 -1.0 1.54e+02 - 9.92e-01 1.00e+00h 1\n", + " 7 0.0000000e+00 7.66e-04 2.93e-04 -2.5 2.52e+02 - 1.00e+00 1.00e+00h 1\n", + " 8 0.0000000e+00 3.81e-04 1.61e-04 -5.7 4.82e+02 - 1.00e+00 1.00e+00h 1\n", + " 9 0.0000000e+00 1.90e-04 6.49e-05 -5.7 9.53e+02 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 0.0000000e+00 9.50e-05 8.68e-05 -5.7 1.90e+03 - 1.00e+00 1.00e+00h 1\n", + " 11 0.0000000e+00 4.75e-05 3.47e-04 -5.7 3.81e+03 - 1.00e+00 1.00e+00h 1\n", + " 12 0.0000000e+00 2.72e-05 1.39e-03 -5.7 7.64e+03 - 1.00e+00 1.00e+00h 1\n", + " 13 0.0000000e+00 1.07e-04 5.57e-03 -5.7 1.54e+04 - 1.00e+00 1.00e+00h 1\n", + " 14 0.0000000e+00 4.09e-04 2.23e-02 -5.7 3.11e+04 - 1.00e+00 1.00e+00h 1\n", + " 15 0.0000000e+00 1.51e-03 8.91e-02 -5.7 6.38e+04 - 1.00e+00 1.00e+00h 1\n", + " 16 0.0000000e+00 5.12e-03 3.53e-01 -5.7 1.33e+05 - 1.00e+00 1.00e+00h 1\n", + " 17 0.0000000e+00 1.49e-02 1.34e+00 -5.7 2.89e+05 - 1.00e+00 1.00e+00h 1\n", + " 18 0.0000000e+00 3.14e-02 4.58e+00 -5.7 6.55e+05 - 1.00e+00 1.00e+00h 1\n", + " 19 0.0000000e+00 2.86e-02 4.32e+00 -5.7 1.51e+06 - 1.00e+00 1.25e-01h 4\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 0.0000000e+00 2.82e-02 4.26e+00 -5.7 1.73e+06 - 1.00e+00 1.56e-02h 7\n", + " 21 0.0000000e+00 2.79e-02 4.23e+00 -5.7 1.76e+06 - 1.00e+00 7.81e-03h 8\n", + " 22 0.0000000e+00 2.79e-02 4.22e+00 -5.7 1.77e+06 - 1.00e+00 4.88e-04h 12\n", + " 23 0.0000000e+00 2.79e-02 4.22e+00 -5.7 1.77e+06 - 1.00e+00 1.22e-04h 14\n", + " 24 0.0000000e+00 7.05e-03 1.51e+01 -5.7 1.77e+06 - 1.00e+00 1.00e+00h 1\n", + " 25 0.0000000e+00 9.63e-04 4.01e+00 -5.7 3.18e+06 - 1.00e+00 1.50e-01h 2\n", + " 26 0.0000000e+00 5.53e-04 8.54e+01 -5.7 3.24e+06 - 1.00e+00 6.53e-02h 2\n", + " 27 0.0000000e+00 5.53e-04 8.57e+01 -5.7 3.20e+06 - 1.00e+00 9.58e-04h 7\n", + " 28 0.0000000e+00 5.53e-04 9.27e+01 -5.7 3.19e+06 - 1.00e+00 9.42e-04h 7\n", + " 29 0.0000000e+00 5.53e-04 2.08e+02 -5.7 3.19e+06 - 1.00e+00 9.27e-04h 7\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30 0.0000000e+00 5.52e-04 7.91e+03 -5.7 1.83e+06 - 1.00e+00 3.17e-03h 6\n", + " 31 0.0000000e+00 3.77e-05 2.11e+06 -5.7 2.63e+04 - 1.00e+00 1.00e+00h 1\n", + " 32 0.0000000e+00 3.77e-05 2.10e+06 -5.7 1.03e+06 - 1.00e+00 5.67e-04h 9\n", + " 33 0.0000000e+00 3.77e-05 2.10e+06 -5.7 1.03e+06 - 1.00e+00 5.65e-04h 9\n", + " 34 0.0000000e+00 3.77e-05 2.10e+06 -5.7 1.02e+06 - 1.00e+00 5.63e-04h 9\n", + " 35 0.0000000e+00 3.77e-05 2.12e+06 -5.7 9.14e+05 - 1.00e+00 6.29e-04h 9\n", + " 36 0.0000000e+00 3.77e-05 2.23e+06 -5.7 9.36e+05 - 1.00e+00 6.11e-04h 9\n", + " 37 0.0000000e+00 3.76e-05 4.98e+06 -5.7 4.23e+05 - 1.00e+00 2.69e-03h 8\n", + " 38 0.0000000e+00 3.76e-05 6.97e+06 -5.7 8.98e+05 - 1.00e+00 6.29e-04h 9\n", + " 39 0.0000000e+00 3.76e-05 5.17e+07 -5.7 6.09e+05 - 1.00e+00 1.85e-03h 8\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 40 0.0000000e+00 3.76e-05 6.29e+07 -5.7 1.03e+06 - 1.00e+00 5.42e-04h 9\n", + " 41 0.0000000e+00 3.76e-05 7.41e+07 -5.7 1.02e+06 - 1.00e+00 5.43e-04h 9\n", + " 42 0.0000000e+00 8.59e-04 7.30e+11 -5.7 1.02e+06 - 1.00e+00 1.39e-01w 1\n", + " 43 0.0000000e+00 8.58e-04 7.30e+11 -5.7 7.14e+03 - 1.00e+00 2.07e-05w 1\n", + "In iteration 43, 2 Slacks too small, adjusting variable bounds\n", + " 44 0.0000000e+00 7.90e-04 5.95e+14 -5.7 4.69e+03 - 1.00e+00 8.02e-02w 1\n", + " 45 0.0000000e+00 3.76e-05 8.53e+07 -5.7 4.31e+03 - 1.00e+00 5.41e-04h 8\n", + " 46 0.0000000e+00 3.75e-05 9.64e+07 -5.7 1.02e+06 - 1.00e+00 5.39e-04h 9\n", + " 47 0.0000000e+00 3.75e-05 1.08e+08 -5.7 1.02e+06 - 1.00e+00 5.37e-04h 9\n", + " 48 0.0000000e+00 3.75e-05 1.19e+08 -5.7 1.02e+06 - 1.00e+00 5.35e-04h 9\n", + " 49 0.0000000e+00 3.75e-05 1.30e+08 -5.7 1.02e+06 - 1.00e+00 5.33e-04h 9\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 50 0.0000000e+00 3.75e-05 1.41e+08 -5.7 1.02e+06 - 1.00e+00 5.31e-04h 9\n", + " 51 0.0000000e+00 3.75e-05 1.52e+08 -5.7 1.02e+06 - 1.00e+00 5.29e-04h 9\n", + " 52 0.0000000e+00 3.75e-05 1.64e+08 -5.7 1.02e+06 - 1.00e+00 5.27e-04h 9\n", + " 53 0.0000000e+00 3.75e-05 1.75e+08 -5.7 1.02e+06 - 1.00e+00 5.25e-04h 9\n", + " 54 0.0000000e+00 3.75e-05 1.86e+08 -5.7 1.02e+06 - 1.00e+00 5.23e-04h 9\n", + " 55 0.0000000e+00 7.97e-04 7.34e+11 -5.7 1.02e+06 - 1.00e+00 1.33e-01w 1\n", + " 56 0.0000000e+00 7.97e-04 6.89e+11 -5.7 6.89e-05 16.0 2.81e-04 5.39e-01w 1\n", + " 57 0.0000000e+00 4.04e-07 2.66e+15 -5.7 4.36e+03 - 2.29e-07 1.00e+00h 1\n", + "Cannot recompute multipliers for feasibility problem. Error in eq_mult_calculator\n", + "\n", + "Number of Iterations....: 57\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 2.6563801083485440e+15 2.6563801083485440e+15\n", + "Constraint violation....: 4.0441652946975677e-07 4.0441652946975677e-07\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 4.0441652946975677e-07 2.6563801083485440e+15\n", + "\n", + "\n", + "Number of objective function evaluations = 337\n", + "Number of objective gradient evaluations = 59\n", + "Number of equality constraint evaluations = 337\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 59\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 58\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", + "Total CPU secs in NLP function evaluations = 0.008\n", + "\n", + "EXIT: Solved To Acceptable Level.\n" + ] + } + ], "source": [ "from idaes.core.util.model_statistics import degrees_of_freedom\n", "import pytest\n", @@ -226,7 +384,11 @@ "m = PR_model(test_data)\n", "\n", "# Check that degrees of freedom is 0\n", - "assert degrees_of_freedom(m) == 0" + "assert degrees_of_freedom(m) == 0\n", + "\n", + "# Solve the model with the default solver and display results\n", + "solver = SolverFactory(\"ipopt\")\n", + "results = solver.solve(m, tee=True)" ] }, { @@ -235,41 +397,87 @@ "source": [ "## 4.0 Parameter estimation using parmest \n", "\n", - "### 4.1 List of variable names to be estimated\n", + "### 4.1 Define the Experiment class\n", "\n", - "Create a list of vars to estimate" + "Define the Experiment class to label model for parameter estimation." ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 8, "metadata": {}, "outputs": [], "source": [ - "variable_name = [\n", - " \"fs.properties.PR_kappa['bmimPF6', 'carbon_dioxide']\",\n", - " \"fs.properties.PR_kappa['carbon_dioxide', 'bmimPF6']\",\n", - "]" + "from pyomo.contrib.parmest.experiment import Experiment\n", + "\n", + "\n", + "# Create experiment class for parameter estimation\n", + "class PRExperiment(Experiment):\n", + "\n", + " def __init__(self, data, meas_error=None):\n", + " \"\"\"Initialize the PR Experiment class\n", + "\n", + " Args:\n", + " data: DataFrame containing the experimental data\n", + " meas_error: Measurement error for the data (optional)\n", + " \"\"\"\n", + " self.model = None\n", + " self.data = data\n", + " self.meas_error = meas_error\n", + "\n", + " def create_model(self):\n", + " \"\"\"Create the Pyomo model for the PR parameter estimation problem\"\"\"\n", + " self.model = PR_model(self.data)\n", + "\n", + " def label_model(self):\n", + " m = self.model\n", + "\n", + " # Add Suffixes to label the outputs, parameters, and measurement error in the model\n", + " m.experiment_outputs = Suffix(direction=Suffix.LOCAL)\n", + " m.experiment_outputs.update(\n", + " [(m.fs.state_block[1].pressure, self.data[\"pressure\"])]\n", + " )\n", + "\n", + " m.measurement_error = Suffix(direction=Suffix.LOCAL)\n", + " m.measurement_error.update([(m.fs.state_block[1].pressure, self.meas_error)])\n", + "\n", + " # Add unknown parameters to the model for easier access\n", + " m.unknown_parameters = Suffix(direction=Suffix.LOCAL)\n", + " m.unknown_parameters.update(\n", + " (k, value(k))\n", + " for k in [\n", + " m.fs.properties.PR_kappa[\"bmimPF6\", \"carbon_dioxide\"],\n", + " m.fs.properties.PR_kappa[\"carbon_dioxide\", \"bmimPF6\"],\n", + " ]\n", + " )\n", + "\n", + " def get_labeled_model(self):\n", + " \"\"\"Return the labeled model\"\"\"\n", + " if self.model is None:\n", + " self.create_model()\n", + " self.label_model()\n", + " return self.model" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### 4.2 Create method to return an expression that computes the sum of squared error\n", + "### 4.2 Pre-process the data into individual experiments\n", "\n", - "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." + "We now separate our data and assign a model for each individual experiments, creating an experiment list. " ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ - "def SSE(m, data):\n", - " expr = (float(data[\"pressure\"]) - m.fs.state_block[1].pressure) ** 2\n", - " return expr * 1e-7" + "# Update to new interface\n", + "exp_list = []\n", + "for i in range(data.shape[0]):\n", + " exp_list.append(PRExperiment(data.iloc[i]))" ] }, { @@ -278,19 +486,218 @@ "source": [ "### 4.3 Run the parameter estimation\n", "\n", - "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." + "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." ] }, { "cell_type": "code", - "execution_count": 9, - "metadata": { - "scrolled": false - }, - "outputs": [], + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:23 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:24 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:25 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Starting initialization\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Bubble, dew, and critical point initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Equilibrium temperature initialization completed.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: State variable initialization completed.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Phase equilibrium initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property initialization: optimal - Optimal Solution Found.\n", + "2026-06-11 12:42:26 [INFO] idaes.init.fs.state_block: Property package initialization: optimal - Optimal Solution Found.\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 846\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 720\n", + "\n", + "Total number of variables............................: 362\n", + " variables with only lower bounds: 72\n", + " variables with lower and upper bounds: 270\n", + " variables with only upper bounds: 18\n", + "Total number of equality constraints.................: 360\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 5.00e-01 2.44e-15 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 6.9602464e+06 4.12e-01 1.82e+07 -1.0 2.99e+04 - 3.39e-01 1.72e-01h 3\n", + " 2 1.6667677e+08 2.58e-01 2.70e+08 -1.0 2.58e+04 - 6.19e-01 7.79e-01h 1\n", + " 3 2.8786912e+08 1.32e-01 4.98e+07 -1.0 8.26e+03 - 8.13e-01 9.90e-01h 1\n", + " 4 2.9277551e+08 1.44e-01 5.76e+05 -1.0 3.05e+02 - 9.77e-01 9.90e-01h 1\n", + " 5 2.9282842e+08 3.31e-02 5.28e+03 -1.0 3.24e+00 - 9.90e-01 9.91e-01h 1\n", + " 6 2.9282891e+08 4.65e-03 8.12e+04 -1.0 1.08e+00 - 9.90e-01 1.00e+00h 1\n", + " 7 2.9282891e+08 3.59e-05 2.33e+04 -2.5 9.23e-02 - 9.97e-01 1.00e+00h 1\n", + " 8 2.9282891e+08 3.17e-09 2.26e-05 -3.8 8.65e-04 - 1.00e+00 1.00e+00h 1\n", + " 9 2.9282891e+08 1.29e-12 2.38e-05 -8.6 6.67e-08 - 1.00e+00 1.00e+00f 1\n", + "\n", + "Number of Iterations....: 9\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.9282891309627521e+08 2.9282891309627521e+08\n", + "Dual infeasibility......: 2.3841853781623475e-05 2.3841853781623475e-05\n", + "Constraint violation....: 1.2910152591875072e-12 1.2910152591875072e-12\n", + "Complementarity.........: 2.5062901281861244e-09 2.5062901281861244e-09\n", + "Overall NLP error.......: 2.5062901281861244e-09 2.3841853781623475e-05\n", + "\n", + "\n", + "Number of objective function evaluations = 12\n", + "Number of objective gradient evaluations = 10\n", + "Number of equality constraint evaluations = 12\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 10\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 9\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.006\n", + "Total CPU secs in NLP function evaluations = 0.020\n", + "\n", + "EXIT: Optimal Solution Found.\n" + ] + } + ], "source": [ - "pest = parmest.Estimator(PR_model, data, variable_name, SSE, tee=True)\n", - "\n", + "pest = parmest.Estimator(exp_list, obj_function=\"SSE\", tee=True)\n", "obj_value, parameters = pest.theta_est()" ] }, @@ -305,15 +712,27 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 11, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The SSE at the optimal solution is 29.282891\n", + "\n", + "The values for the parameters are as follows:\n", + "fs.properties.PR_kappa[bmimPF6,carbon_dioxide] = -0.40714284008565715\n", + "fs.properties.PR_kappa[carbon_dioxide,bmimPF6] = 0.02059368400143062\n" + ] + } + ], "source": [ - "print(\"The SSE at the optimal solution is %0.6f\" % obj_value)\n", + "print(f\"The SSE at the optimal solution is {obj_value*1e-7:0.6f}\")\n", "print()\n", "print(\"The values for the parameters are as follows:\")\n", "for k, v in parameters.items():\n", - " print(k, \"=\", v)" + " print(f\"{k} = {v}\")" ] }, { @@ -333,7 +752,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "idaes-pse-and-examples-dev-py313-macmini", "language": "python", "name": "python3" }, @@ -347,9 +766,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.12" + "version": "3.13.13" } }, "nbformat": 4, "nbformat_minor": 3 -} +} \ No newline at end of file From c059c18b1a4b33580053a89510515d130097a4cc Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Thu, 11 Jun 2026 13:01:37 -0400 Subject: [PATCH 13/23] Fixed bootstrap block typo. --- .../parameter_estimation_nrtl_using_unit_model.ipynb | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb index e641936c..e01d1b95 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb @@ -1125,13 +1125,10 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "# Run parameter estimation using bootstrap resample of the data (10 samples),\n", - "# plot results along with confidence regions\n", - "\n", "# Uncomment the following lines\n", "# bootstrap_theta = pest.theta_est_bootstrap(4, seed=542)\n", "# display(bootstrap_theta)" From 1b20b35b8a6c928a02cfb609dc0c02d7cf8b7dae Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Thu, 11 Jun 2026 13:02:28 -0400 Subject: [PATCH 14/23] Redid preprocessing on unit_model notebooks --- .../parameter_estimation_nrtl_using_unit_model_doc.ipynb | 5 +---- ...parameter_estimation_nrtl_using_unit_model_exercise.ipynb | 5 +---- ...parameter_estimation_nrtl_using_unit_model_solution.ipynb | 5 +---- .../parameter_estimation_nrtl_using_unit_model_test.ipynb | 5 +---- .../parameter_estimation_nrtl_using_unit_model_usr.ipynb | 5 +---- 5 files changed, 5 insertions(+), 20 deletions(-) diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_doc.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_doc.ipynb index 56377f29..444be358 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_doc.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_doc.ipynb @@ -987,13 +987,10 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "# Run parameter estimation using bootstrap resample of the data (10 samples),\n", - "# plot results along with confidence regions\n", - "\n", "# Uncomment the following lines\n", "# bootstrap_theta = pest.theta_est_bootstrap(4, seed=542)\n", "# display(bootstrap_theta)" diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_exercise.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_exercise.ipynb index 9bc7f5e6..e24f2429 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_exercise.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_exercise.ipynb @@ -980,13 +980,10 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "# Run parameter estimation using bootstrap resample of the data (10 samples),\n", - "# plot results along with confidence regions\n", - "\n", "# Uncomment the following lines\n", "# bootstrap_theta = pest.theta_est_bootstrap(4, seed=542)\n", "# display(bootstrap_theta)" diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_solution.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_solution.ipynb index c1d70da8..dedc72d0 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_solution.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_solution.ipynb @@ -1072,13 +1072,10 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "# Run parameter estimation using bootstrap resample of the data (10 samples),\n", - "# plot results along with confidence regions\n", - "\n", "# Uncomment the following lines\n", "# bootstrap_theta = pest.theta_est_bootstrap(4, seed=542)\n", "# display(bootstrap_theta)" diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_test.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_test.ipynb index c5243ffb..a125cb70 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_test.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_test.ipynb @@ -1040,13 +1040,10 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "# Run parameter estimation using bootstrap resample of the data (10 samples),\n", - "# plot results along with confidence regions\n", - "\n", "# Uncomment the following lines\n", "# bootstrap_theta = pest.theta_est_bootstrap(4, seed=542)\n", "# display(bootstrap_theta)" diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_usr.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_usr.ipynb index c1d70da8..dedc72d0 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_usr.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_usr.ipynb @@ -1072,13 +1072,10 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "# Run parameter estimation using bootstrap resample of the data (10 samples),\n", - "# plot results along with confidence regions\n", - "\n", "# Uncomment the following lines\n", "# bootstrap_theta = pest.theta_est_bootstrap(4, seed=542)\n", "# display(bootstrap_theta)" From 1dfe4f9e75fe2344fb57de56ce3e9ff90e9ee521 Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Thu, 11 Jun 2026 16:36:41 -0400 Subject: [PATCH 15/23] Corrected typo --- .../param_est/parameter_estimation_nrtl_using_state_block.ipynb | 2 +- .../param_est/parameter_estimation_nrtl_using_unit_model.ipynb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block.ipynb index 70ef705e..6575037f 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block.ipynb @@ -864,7 +864,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "We define the `exp_list` by spliting the data into individual experiments, or data points." + "We define the `exp_list` by splitting the data into individual experiments, or data points." ] }, { diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb index e01d1b95..c6897244 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb @@ -854,7 +854,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "We define the `exp_list` by spliting the data into individual experiments, or data points." + "We define the `exp_list` by splitting the data into individual experiments, or data points." ] }, { From 23476ac86a8634b06422cdefe0da3a42b89258fa Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Thu, 11 Jun 2026 16:45:31 -0400 Subject: [PATCH 16/23] Processed derivative notebooks to fix typo. --- .../parameter_estimation_nrtl_using_state_block_doc.ipynb | 2 +- .../parameter_estimation_nrtl_using_state_block_exercise.ipynb | 2 +- .../parameter_estimation_nrtl_using_state_block_solution.ipynb | 2 +- .../parameter_estimation_nrtl_using_state_block_test.ipynb | 2 +- .../parameter_estimation_nrtl_using_state_block_usr.ipynb | 2 +- .../parameter_estimation_nrtl_using_unit_model_doc.ipynb | 2 +- .../parameter_estimation_nrtl_using_unit_model_exercise.ipynb | 2 +- .../parameter_estimation_nrtl_using_unit_model_solution.ipynb | 2 +- .../parameter_estimation_nrtl_using_unit_model_test.ipynb | 2 +- .../parameter_estimation_nrtl_using_unit_model_usr.ipynb | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_doc.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_doc.ipynb index 532e84f9..c27bbc2e 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_doc.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_doc.ipynb @@ -746,7 +746,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "We define the `exp_list` by spliting the data into individual experiments, or data points." + "We define the `exp_list` by splitting the data into individual experiments, or data points." ] }, { diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_exercise.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_exercise.ipynb index 390d71fa..66abf7b3 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_exercise.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_exercise.ipynb @@ -736,7 +736,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "We define the `exp_list` by spliting the data into individual experiments, or data points." + "We define the `exp_list` by splitting the data into individual experiments, or data points." ] }, { diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_solution.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_solution.ipynb index 97ab497e..ccc80f73 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_solution.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_solution.ipynb @@ -827,7 +827,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "We define the `exp_list` by spliting the data into individual experiments, or data points." + "We define the `exp_list` by splitting the data into individual experiments, or data points." ] }, { diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_test.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_test.ipynb index 9e504a6e..796c558c 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_test.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_test.ipynb @@ -783,7 +783,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "We define the `exp_list` by spliting the data into individual experiments, or data points." + "We define the `exp_list` by splitting the data into individual experiments, or data points." ] }, { diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_usr.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_usr.ipynb index 97ab497e..ccc80f73 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_usr.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_usr.ipynb @@ -827,7 +827,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "We define the `exp_list` by spliting the data into individual experiments, or data points." + "We define the `exp_list` by splitting the data into individual experiments, or data points." ] }, { diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_doc.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_doc.ipynb index 444be358..9f168b88 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_doc.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_doc.ipynb @@ -732,7 +732,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "We define the `exp_list` by spliting the data into individual experiments, or data points." + "We define the `exp_list` by splitting the data into individual experiments, or data points." ] }, { diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_exercise.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_exercise.ipynb index e24f2429..be34d7d0 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_exercise.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_exercise.ipynb @@ -725,7 +725,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "We define the `exp_list` by spliting the data into individual experiments, or data points." + "We define the `exp_list` by splitting the data into individual experiments, or data points." ] }, { diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_solution.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_solution.ipynb index dedc72d0..9e64c1d9 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_solution.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_solution.ipynb @@ -817,7 +817,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "We define the `exp_list` by spliting the data into individual experiments, or data points." + "We define the `exp_list` by splitting the data into individual experiments, or data points." ] }, { diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_test.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_test.ipynb index a125cb70..5da23dde 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_test.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_test.ipynb @@ -769,7 +769,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "We define the `exp_list` by spliting the data into individual experiments, or data points." + "We define the `exp_list` by splitting the data into individual experiments, or data points." ] }, { diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_usr.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_usr.ipynb index dedc72d0..9e64c1d9 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_usr.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_usr.ipynb @@ -817,7 +817,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "We define the `exp_list` by spliting the data into individual experiments, or data points." + "We define the `exp_list` by splitting the data into individual experiments, or data points." ] }, { From 911a07e259134f9882d777af71f746b657b06ee3 Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Thu, 11 Jun 2026 17:16:31 -0400 Subject: [PATCH 17/23] Update parameter_estimation_nrtl_using_state_block.ipynb --- ...meter_estimation_nrtl_using_state_block.ipynb | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block.ipynb index 6575037f..39d43578 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block.ipynb @@ -89,8 +89,7 @@ "# Todo: import FlowsheetBlock from idaes.core\n", "from idaes.core import FlowsheetBlock\n", "\n", - "# Todo: import Flash unit model from idaes.models.unit_models\n", - "from idaes.models.unit_models import Flash" + "from idaes.core import FlowsheetBlock" ] }, { @@ -390,8 +389,7 @@ " self.model = NRTL_model(self.data)\n", "\n", " def label_model(self):\n", - " import pyomo.environ as pyo\n", - " import pandas as pd\n", + " from pyomo.environ import Set, Expression\n", "\n", " m = self.model\n", "\n", @@ -401,22 +399,22 @@ " m.data_point = pyo.Set(initialize=[0])\n", "\n", " # Wrap IDAES variables in Expressions indexed by data point\n", - " m.liq_benzene_out = pyo.Expression(\n", + " m.liq_benzene_out = Expression(\n", " m.data_point,\n", " rule=lambda m, i: m.fs.state_block.mole_frac_phase_comp[\"Liq\", \"benzene\"],\n", " )\n", "\n", - " m.vap_benzene_out = pyo.Expression(\n", + " m.vap_benzene_out = Expression(\n", " m.data_point,\n", " rule=lambda m, i: m.fs.state_block.mole_frac_phase_comp[\"Vap\", \"benzene\"],\n", " )\n", "\n", - " m.experiment_outputs = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + " m.experiment_outputs = Suffix(direction=Suffix.LOCAL)\n", "\n", " m.experiment_outputs[m.liq_benzene_out[0]] = float(self.data[\"liq_benzene\"])\n", " m.experiment_outputs[m.vap_benzene_out[0]] = float(self.data[\"vap_benzene\"])\n", "\n", - " m.measurement_error = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + " m.measurement_error = Suffix(direction=Suffix.LOCAL)\n", " m.measurement_error.update(\n", " [\n", " (m.liq_benzene_out[0], self.meas_error),\n", @@ -425,7 +423,7 @@ " )\n", "\n", " # Add unknown parameters to the model for easier access\n", - " m.unknown_parameters = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + " m.unknown_parameters = Suffix(direction=Suffix.LOCAL)\n", " m.unknown_parameters.update(\n", " (k, value(k))\n", " for k in [\n", From d8456d713c5bb7783f7dbede8cdbdc114135dc82 Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Thu, 11 Jun 2026 17:17:55 -0400 Subject: [PATCH 18/23] Applied fixed formatting and imports to deriv notebooks --- ...r_estimation_nrtl_using_state_block_doc.ipynb | 16 +++++++--------- ...imation_nrtl_using_state_block_exercise.ipynb | 13 ++++++------- ...imation_nrtl_using_state_block_solution.ipynb | 16 +++++++--------- ..._estimation_nrtl_using_state_block_test.ipynb | 16 +++++++--------- ...r_estimation_nrtl_using_state_block_usr.ipynb | 16 +++++++--------- 5 files changed, 34 insertions(+), 43 deletions(-) diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_doc.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_doc.ipynb index c27bbc2e..02fa5fc1 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_doc.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_doc.ipynb @@ -74,8 +74,7 @@ "# Todo: import FlowsheetBlock from idaes.core\n", "from idaes.core import FlowsheetBlock\n", "\n", - "# Todo: import Flash unit model from idaes.models.unit_models\n", - "from idaes.models.unit_models import Flash" + "from idaes.core import FlowsheetBlock" ] }, { @@ -272,8 +271,7 @@ " self.model = NRTL_model(self.data)\n", "\n", " def label_model(self):\n", - " import pyomo.environ as pyo\n", - " import pandas as pd\n", + " from pyomo.environ import Set, Expression\n", "\n", " m = self.model\n", "\n", @@ -283,22 +281,22 @@ " m.data_point = pyo.Set(initialize=[0])\n", "\n", " # Wrap IDAES variables in Expressions indexed by data point\n", - " m.liq_benzene_out = pyo.Expression(\n", + " m.liq_benzene_out = Expression(\n", " m.data_point,\n", " rule=lambda m, i: m.fs.state_block.mole_frac_phase_comp[\"Liq\", \"benzene\"],\n", " )\n", "\n", - " m.vap_benzene_out = pyo.Expression(\n", + " m.vap_benzene_out = Expression(\n", " m.data_point,\n", " rule=lambda m, i: m.fs.state_block.mole_frac_phase_comp[\"Vap\", \"benzene\"],\n", " )\n", "\n", - " m.experiment_outputs = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + " m.experiment_outputs = Suffix(direction=Suffix.LOCAL)\n", "\n", " m.experiment_outputs[m.liq_benzene_out[0]] = float(self.data[\"liq_benzene\"])\n", " m.experiment_outputs[m.vap_benzene_out[0]] = float(self.data[\"vap_benzene\"])\n", "\n", - " m.measurement_error = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + " m.measurement_error = Suffix(direction=Suffix.LOCAL)\n", " m.measurement_error.update(\n", " [\n", " (m.liq_benzene_out[0], self.meas_error),\n", @@ -307,7 +305,7 @@ " )\n", "\n", " # Add unknown parameters to the model for easier access\n", - " m.unknown_parameters = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + " m.unknown_parameters = Suffix(direction=Suffix.LOCAL)\n", " m.unknown_parameters.update(\n", " (k, value(k))\n", " for k in [\n", diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_exercise.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_exercise.ipynb index 66abf7b3..0311ba2c 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_exercise.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_exercise.ipynb @@ -262,8 +262,7 @@ " self.model = NRTL_model(self.data)\n", "\n", " def label_model(self):\n", - " import pyomo.environ as pyo\n", - " import pandas as pd\n", + " from pyomo.environ import Set, Expression\n", "\n", " m = self.model\n", "\n", @@ -273,22 +272,22 @@ " m.data_point = pyo.Set(initialize=[0])\n", "\n", " # Wrap IDAES variables in Expressions indexed by data point\n", - " m.liq_benzene_out = pyo.Expression(\n", + " m.liq_benzene_out = Expression(\n", " m.data_point,\n", " rule=lambda m, i: m.fs.state_block.mole_frac_phase_comp[\"Liq\", \"benzene\"],\n", " )\n", "\n", - " m.vap_benzene_out = pyo.Expression(\n", + " m.vap_benzene_out = Expression(\n", " m.data_point,\n", " rule=lambda m, i: m.fs.state_block.mole_frac_phase_comp[\"Vap\", \"benzene\"],\n", " )\n", "\n", - " m.experiment_outputs = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + " m.experiment_outputs = Suffix(direction=Suffix.LOCAL)\n", "\n", " m.experiment_outputs[m.liq_benzene_out[0]] = float(self.data[\"liq_benzene\"])\n", " m.experiment_outputs[m.vap_benzene_out[0]] = float(self.data[\"vap_benzene\"])\n", "\n", - " m.measurement_error = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + " m.measurement_error = Suffix(direction=Suffix.LOCAL)\n", " m.measurement_error.update(\n", " [\n", " (m.liq_benzene_out[0], self.meas_error),\n", @@ -297,7 +296,7 @@ " )\n", "\n", " # Add unknown parameters to the model for easier access\n", - " m.unknown_parameters = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + " m.unknown_parameters = Suffix(direction=Suffix.LOCAL)\n", " m.unknown_parameters.update(\n", " (k, value(k))\n", " for k in [\n", diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_solution.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_solution.ipynb index ccc80f73..47545511 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_solution.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_solution.ipynb @@ -89,8 +89,7 @@ "# Todo: import FlowsheetBlock from idaes.core\n", "from idaes.core import FlowsheetBlock\n", "\n", - "# Todo: import Flash unit model from idaes.models.unit_models\n", - "from idaes.models.unit_models import Flash" + "from idaes.core import FlowsheetBlock" ] }, { @@ -353,8 +352,7 @@ " self.model = NRTL_model(self.data)\n", "\n", " def label_model(self):\n", - " import pyomo.environ as pyo\n", - " import pandas as pd\n", + " from pyomo.environ import Set, Expression\n", "\n", " m = self.model\n", "\n", @@ -364,22 +362,22 @@ " m.data_point = pyo.Set(initialize=[0])\n", "\n", " # Wrap IDAES variables in Expressions indexed by data point\n", - " m.liq_benzene_out = pyo.Expression(\n", + " m.liq_benzene_out = Expression(\n", " m.data_point,\n", " rule=lambda m, i: m.fs.state_block.mole_frac_phase_comp[\"Liq\", \"benzene\"],\n", " )\n", "\n", - " m.vap_benzene_out = pyo.Expression(\n", + " m.vap_benzene_out = Expression(\n", " m.data_point,\n", " rule=lambda m, i: m.fs.state_block.mole_frac_phase_comp[\"Vap\", \"benzene\"],\n", " )\n", "\n", - " m.experiment_outputs = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + " m.experiment_outputs = Suffix(direction=Suffix.LOCAL)\n", "\n", " m.experiment_outputs[m.liq_benzene_out[0]] = float(self.data[\"liq_benzene\"])\n", " m.experiment_outputs[m.vap_benzene_out[0]] = float(self.data[\"vap_benzene\"])\n", "\n", - " m.measurement_error = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + " m.measurement_error = Suffix(direction=Suffix.LOCAL)\n", " m.measurement_error.update(\n", " [\n", " (m.liq_benzene_out[0], self.meas_error),\n", @@ -388,7 +386,7 @@ " )\n", "\n", " # Add unknown parameters to the model for easier access\n", - " m.unknown_parameters = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + " m.unknown_parameters = Suffix(direction=Suffix.LOCAL)\n", " m.unknown_parameters.update(\n", " (k, value(k))\n", " for k in [\n", diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_test.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_test.ipynb index 796c558c..03cafe75 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_test.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_test.ipynb @@ -74,8 +74,7 @@ "# Todo: import FlowsheetBlock from idaes.core\n", "from idaes.core import FlowsheetBlock\n", "\n", - "# Todo: import Flash unit model from idaes.models.unit_models\n", - "from idaes.models.unit_models import Flash" + "from idaes.core import FlowsheetBlock" ] }, { @@ -309,8 +308,7 @@ " self.model = NRTL_model(self.data)\n", "\n", " def label_model(self):\n", - " import pyomo.environ as pyo\n", - " import pandas as pd\n", + " from pyomo.environ import Set, Expression\n", "\n", " m = self.model\n", "\n", @@ -320,22 +318,22 @@ " m.data_point = pyo.Set(initialize=[0])\n", "\n", " # Wrap IDAES variables in Expressions indexed by data point\n", - " m.liq_benzene_out = pyo.Expression(\n", + " m.liq_benzene_out = Expression(\n", " m.data_point,\n", " rule=lambda m, i: m.fs.state_block.mole_frac_phase_comp[\"Liq\", \"benzene\"],\n", " )\n", "\n", - " m.vap_benzene_out = pyo.Expression(\n", + " m.vap_benzene_out = Expression(\n", " m.data_point,\n", " rule=lambda m, i: m.fs.state_block.mole_frac_phase_comp[\"Vap\", \"benzene\"],\n", " )\n", "\n", - " m.experiment_outputs = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + " m.experiment_outputs = Suffix(direction=Suffix.LOCAL)\n", "\n", " m.experiment_outputs[m.liq_benzene_out[0]] = float(self.data[\"liq_benzene\"])\n", " m.experiment_outputs[m.vap_benzene_out[0]] = float(self.data[\"vap_benzene\"])\n", "\n", - " m.measurement_error = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + " m.measurement_error = Suffix(direction=Suffix.LOCAL)\n", " m.measurement_error.update(\n", " [\n", " (m.liq_benzene_out[0], self.meas_error),\n", @@ -344,7 +342,7 @@ " )\n", "\n", " # Add unknown parameters to the model for easier access\n", - " m.unknown_parameters = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + " m.unknown_parameters = Suffix(direction=Suffix.LOCAL)\n", " m.unknown_parameters.update(\n", " (k, value(k))\n", " for k in [\n", diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_usr.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_usr.ipynb index ccc80f73..47545511 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_usr.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_usr.ipynb @@ -89,8 +89,7 @@ "# Todo: import FlowsheetBlock from idaes.core\n", "from idaes.core import FlowsheetBlock\n", "\n", - "# Todo: import Flash unit model from idaes.models.unit_models\n", - "from idaes.models.unit_models import Flash" + "from idaes.core import FlowsheetBlock" ] }, { @@ -353,8 +352,7 @@ " self.model = NRTL_model(self.data)\n", "\n", " def label_model(self):\n", - " import pyomo.environ as pyo\n", - " import pandas as pd\n", + " from pyomo.environ import Set, Expression\n", "\n", " m = self.model\n", "\n", @@ -364,22 +362,22 @@ " m.data_point = pyo.Set(initialize=[0])\n", "\n", " # Wrap IDAES variables in Expressions indexed by data point\n", - " m.liq_benzene_out = pyo.Expression(\n", + " m.liq_benzene_out = Expression(\n", " m.data_point,\n", " rule=lambda m, i: m.fs.state_block.mole_frac_phase_comp[\"Liq\", \"benzene\"],\n", " )\n", "\n", - " m.vap_benzene_out = pyo.Expression(\n", + " m.vap_benzene_out = Expression(\n", " m.data_point,\n", " rule=lambda m, i: m.fs.state_block.mole_frac_phase_comp[\"Vap\", \"benzene\"],\n", " )\n", "\n", - " m.experiment_outputs = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + " m.experiment_outputs = Suffix(direction=Suffix.LOCAL)\n", "\n", " m.experiment_outputs[m.liq_benzene_out[0]] = float(self.data[\"liq_benzene\"])\n", " m.experiment_outputs[m.vap_benzene_out[0]] = float(self.data[\"vap_benzene\"])\n", "\n", - " m.measurement_error = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + " m.measurement_error = Suffix(direction=Suffix.LOCAL)\n", " m.measurement_error.update(\n", " [\n", " (m.liq_benzene_out[0], self.meas_error),\n", @@ -388,7 +386,7 @@ " )\n", "\n", " # Add unknown parameters to the model for easier access\n", - " m.unknown_parameters = pyo.Suffix(direction=pyo.Suffix.LOCAL)\n", + " m.unknown_parameters = Suffix(direction=Suffix.LOCAL)\n", " m.unknown_parameters.update(\n", " (k, value(k))\n", " for k in [\n", From 8a2b596231faa25e5d0b5935c87c6539a43474c7 Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Thu, 11 Jun 2026 17:21:24 -0400 Subject: [PATCH 19/23] Update parameter_estimation_nrtl_using_state_block.ipynb --- .../parameter_estimation_nrtl_using_state_block.ipynb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block.ipynb index 39d43578..ec3d53d1 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block.ipynb @@ -54,7 +54,7 @@ "source": [ "
\n", "Inline Exercise:\n", - "import `ConcreteModel`, `value`, and `Suffix` from Pyomo, `FlowsheetBlock` and `Flash` from IDAES. \n", + "import `ConcreteModel`, `value`, and `Suffix` from Pyomo, and `FlowsheetBlock`from IDAES. \n", "
" ] }, @@ -87,8 +87,6 @@ "from pyomo.environ import ConcreteModel, value, Suffix\n", "\n", "# Todo: import FlowsheetBlock from idaes.core\n", - "from idaes.core import FlowsheetBlock\n", - "\n", "from idaes.core import FlowsheetBlock" ] }, From dd14223f93757b552c6ddff14c6989593e72a536 Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Thu, 11 Jun 2026 17:22:06 -0400 Subject: [PATCH 20/23] Push to derived notebooks --- .../parameter_estimation_nrtl_using_state_block_doc.ipynb | 4 +--- ...parameter_estimation_nrtl_using_state_block_exercise.ipynb | 2 +- ...parameter_estimation_nrtl_using_state_block_solution.ipynb | 4 +--- .../parameter_estimation_nrtl_using_state_block_test.ipynb | 4 +--- .../parameter_estimation_nrtl_using_state_block_usr.ipynb | 4 +--- 5 files changed, 5 insertions(+), 13 deletions(-) diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_doc.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_doc.ipynb index 02fa5fc1..a9c05ccb 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_doc.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_doc.ipynb @@ -54,7 +54,7 @@ "source": [ "
\n", "Inline Exercise:\n", - "import `ConcreteModel`, `value`, and `Suffix` from Pyomo, `FlowsheetBlock` and `Flash` from IDAES. \n", + "import `ConcreteModel`, `value`, and `Suffix` from Pyomo, and `FlowsheetBlock`from IDAES. \n", "
" ] }, @@ -72,8 +72,6 @@ "from pyomo.environ import ConcreteModel, value, Suffix\n", "\n", "# Todo: import FlowsheetBlock from idaes.core\n", - "from idaes.core import FlowsheetBlock\n", - "\n", "from idaes.core import FlowsheetBlock" ] }, diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_exercise.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_exercise.ipynb index 0311ba2c..81147fd7 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_exercise.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_exercise.ipynb @@ -54,7 +54,7 @@ "source": [ "
\n", "Inline Exercise:\n", - "import `ConcreteModel`, `value`, and `Suffix` from Pyomo, `FlowsheetBlock` and `Flash` from IDAES. \n", + "import `ConcreteModel`, `value`, and `Suffix` from Pyomo, and `FlowsheetBlock`from IDAES. \n", "
" ] }, diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_solution.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_solution.ipynb index 47545511..392c0dd2 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_solution.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_solution.ipynb @@ -54,7 +54,7 @@ "source": [ "
\n", "Inline Exercise:\n", - "import `ConcreteModel`, `value`, and `Suffix` from Pyomo, `FlowsheetBlock` and `Flash` from IDAES. \n", + "import `ConcreteModel`, `value`, and `Suffix` from Pyomo, and `FlowsheetBlock`from IDAES. \n", "
" ] }, @@ -87,8 +87,6 @@ "from pyomo.environ import ConcreteModel, value, Suffix\n", "\n", "# Todo: import FlowsheetBlock from idaes.core\n", - "from idaes.core import FlowsheetBlock\n", - "\n", "from idaes.core import FlowsheetBlock" ] }, diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_test.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_test.ipynb index 03cafe75..62e77820 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_test.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_test.ipynb @@ -54,7 +54,7 @@ "source": [ "
\n", "Inline Exercise:\n", - "import `ConcreteModel`, `value`, and `Suffix` from Pyomo, `FlowsheetBlock` and `Flash` from IDAES. \n", + "import `ConcreteModel`, `value`, and `Suffix` from Pyomo, and `FlowsheetBlock`from IDAES. \n", "
" ] }, @@ -72,8 +72,6 @@ "from pyomo.environ import ConcreteModel, value, Suffix\n", "\n", "# Todo: import FlowsheetBlock from idaes.core\n", - "from idaes.core import FlowsheetBlock\n", - "\n", "from idaes.core import FlowsheetBlock" ] }, diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_usr.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_usr.ipynb index 47545511..392c0dd2 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_usr.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_usr.ipynb @@ -54,7 +54,7 @@ "source": [ "
\n", "Inline Exercise:\n", - "import `ConcreteModel`, `value`, and `Suffix` from Pyomo, `FlowsheetBlock` and `Flash` from IDAES. \n", + "import `ConcreteModel`, `value`, and `Suffix` from Pyomo, and `FlowsheetBlock`from IDAES. \n", "
" ] }, @@ -87,8 +87,6 @@ "from pyomo.environ import ConcreteModel, value, Suffix\n", "\n", "# Todo: import FlowsheetBlock from idaes.core\n", - "from idaes.core import FlowsheetBlock\n", - "\n", "from idaes.core import FlowsheetBlock" ] }, From e30a29c9a4aa1ffde36b5a9b4fd7d37dfc444896 Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Thu, 11 Jun 2026 17:49:55 -0400 Subject: [PATCH 21/23] Removed extra pyo --- .../param_est/parameter_estimation_nrtl_using_state_block.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block.ipynb index ec3d53d1..bb3c5d21 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block.ipynb @@ -394,7 +394,7 @@ " # Parmest expects the first index of experiment outputs to be the data point\n", " # This is a workaround that will be addressed and corrected in a future release.\n", "\n", - " m.data_point = pyo.Set(initialize=[0])\n", + " m.data_point = Set(initialize=[0])\n", "\n", " # Wrap IDAES variables in Expressions indexed by data point\n", " m.liq_benzene_out = Expression(\n", From 467ad33f5d8e929750c96df085ce5e0d5f4e76d1 Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Thu, 11 Jun 2026 17:52:06 -0400 Subject: [PATCH 22/23] Apply to derived notebooks --- .../parameter_estimation_nrtl_using_state_block_doc.ipynb | 2 +- .../parameter_estimation_nrtl_using_state_block_exercise.ipynb | 2 +- .../parameter_estimation_nrtl_using_state_block_solution.ipynb | 2 +- .../parameter_estimation_nrtl_using_state_block_test.ipynb | 2 +- .../parameter_estimation_nrtl_using_state_block_usr.ipynb | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_doc.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_doc.ipynb index a9c05ccb..b0a8e536 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_doc.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_doc.ipynb @@ -276,7 +276,7 @@ " # Parmest expects the first index of experiment outputs to be the data point\n", " # This is a workaround that will be addressed and corrected in a future release.\n", "\n", - " m.data_point = pyo.Set(initialize=[0])\n", + " m.data_point = Set(initialize=[0])\n", "\n", " # Wrap IDAES variables in Expressions indexed by data point\n", " m.liq_benzene_out = Expression(\n", diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_exercise.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_exercise.ipynb index 81147fd7..d98ce913 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_exercise.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_exercise.ipynb @@ -269,7 +269,7 @@ " # Parmest expects the first index of experiment outputs to be the data point\n", " # This is a workaround that will be addressed and corrected in a future release.\n", "\n", - " m.data_point = pyo.Set(initialize=[0])\n", + " m.data_point = Set(initialize=[0])\n", "\n", " # Wrap IDAES variables in Expressions indexed by data point\n", " m.liq_benzene_out = Expression(\n", diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_solution.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_solution.ipynb index 392c0dd2..3c7e80f9 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_solution.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_solution.ipynb @@ -357,7 +357,7 @@ " # Parmest expects the first index of experiment outputs to be the data point\n", " # This is a workaround that will be addressed and corrected in a future release.\n", "\n", - " m.data_point = pyo.Set(initialize=[0])\n", + " m.data_point = Set(initialize=[0])\n", "\n", " # Wrap IDAES variables in Expressions indexed by data point\n", " m.liq_benzene_out = Expression(\n", diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_test.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_test.ipynb index 62e77820..c732ca01 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_test.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_test.ipynb @@ -313,7 +313,7 @@ " # Parmest expects the first index of experiment outputs to be the data point\n", " # This is a workaround that will be addressed and corrected in a future release.\n", "\n", - " m.data_point = pyo.Set(initialize=[0])\n", + " m.data_point = Set(initialize=[0])\n", "\n", " # Wrap IDAES variables in Expressions indexed by data point\n", " m.liq_benzene_out = Expression(\n", diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_usr.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_usr.ipynb index 392c0dd2..3c7e80f9 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_usr.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_usr.ipynb @@ -357,7 +357,7 @@ " # Parmest expects the first index of experiment outputs to be the data point\n", " # This is a workaround that will be addressed and corrected in a future release.\n", "\n", - " m.data_point = pyo.Set(initialize=[0])\n", + " m.data_point = Set(initialize=[0])\n", "\n", " # Wrap IDAES variables in Expressions indexed by data point\n", " m.liq_benzene_out = Expression(\n", From d9c5a8c892e1e8312285adc35c5b3cf4d3056896 Mon Sep 17 00:00:00 2001 From: Bethany Nicholson Date: Fri, 12 Jun 2026 00:54:54 -0600 Subject: [PATCH 23/23] Fix typo in parameter estimation notebooks Co-authored-by: Bethany Nicholson --- .../param_est/parameter_estimation_nrtl_using_state_block.ipynb | 2 +- .../parameter_estimation_nrtl_using_state_block_doc.ipynb | 2 +- .../parameter_estimation_nrtl_using_state_block_exercise.ipynb | 2 +- .../parameter_estimation_nrtl_using_state_block_solution.ipynb | 2 +- .../parameter_estimation_nrtl_using_state_block_test.ipynb | 2 +- .../parameter_estimation_nrtl_using_state_block_usr.ipynb | 2 +- .../param_est/parameter_estimation_nrtl_using_unit_model.ipynb | 2 +- .../parameter_estimation_nrtl_using_unit_model_doc.ipynb | 2 +- .../parameter_estimation_nrtl_using_unit_model_exercise.ipynb | 2 +- .../parameter_estimation_nrtl_using_unit_model_solution.ipynb | 2 +- .../parameter_estimation_nrtl_using_unit_model_test.ipynb | 2 +- .../parameter_estimation_nrtl_using_unit_model_usr.ipynb | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block.ipynb index bb3c5d21..9cce791e 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block.ipynb @@ -344,7 +344,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Here we build an experiment class to label our model problem for parameter estimation. The labels are defined as a `Suffix`, and the main labels for our model are `experiment_outputs`, `unknown_parameters`. and `measurement_error`.\n", + "Here we build an experiment class to label our model problem for parameter estimation. The labels are defined as a `Suffix`, and the main labels for our model are `experiment_outputs`, `unknown_parameters`, and `measurement_error`.\n", "\n", "For this problem, the error will be computed for the mole fraction of benzene in the vapor and liquid phase between the model prediction and data. The `experimental_outputs` will therefore be the mole fraction of benzene in the two phases.\n", "\n", diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_doc.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_doc.ipynb index b0a8e536..e75daf77 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_doc.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_doc.ipynb @@ -226,7 +226,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Here we build an experiment class to label our model problem for parameter estimation. The labels are defined as a `Suffix`, and the main labels for our model are `experiment_outputs`, `unknown_parameters`. and `measurement_error`.\n", + "Here we build an experiment class to label our model problem for parameter estimation. The labels are defined as a `Suffix`, and the main labels for our model are `experiment_outputs`, `unknown_parameters`, and `measurement_error`.\n", "\n", "For this problem, the error will be computed for the mole fraction of benzene in the vapor and liquid phase between the model prediction and data. The `experimental_outputs` will therefore be the mole fraction of benzene in the two phases.\n", "\n", diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_exercise.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_exercise.ipynb index d98ce913..97bf86ad 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_exercise.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_exercise.ipynb @@ -219,7 +219,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Here we build an experiment class to label our model problem for parameter estimation. The labels are defined as a `Suffix`, and the main labels for our model are `experiment_outputs`, `unknown_parameters`. and `measurement_error`.\n", + "Here we build an experiment class to label our model problem for parameter estimation. The labels are defined as a `Suffix`, and the main labels for our model are `experiment_outputs`, `unknown_parameters`, and `measurement_error`.\n", "\n", "For this problem, the error will be computed for the mole fraction of benzene in the vapor and liquid phase between the model prediction and data. The `experimental_outputs` will therefore be the mole fraction of benzene in the two phases.\n", "\n", diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_solution.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_solution.ipynb index 3c7e80f9..1d5d1b1e 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_solution.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_solution.ipynb @@ -307,7 +307,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Here we build an experiment class to label our model problem for parameter estimation. The labels are defined as a `Suffix`, and the main labels for our model are `experiment_outputs`, `unknown_parameters`. and `measurement_error`.\n", + "Here we build an experiment class to label our model problem for parameter estimation. The labels are defined as a `Suffix`, and the main labels for our model are `experiment_outputs`, `unknown_parameters`, and `measurement_error`.\n", "\n", "For this problem, the error will be computed for the mole fraction of benzene in the vapor and liquid phase between the model prediction and data. The `experimental_outputs` will therefore be the mole fraction of benzene in the two phases.\n", "\n", diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_test.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_test.ipynb index c732ca01..735706d0 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_test.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_test.ipynb @@ -263,7 +263,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Here we build an experiment class to label our model problem for parameter estimation. The labels are defined as a `Suffix`, and the main labels for our model are `experiment_outputs`, `unknown_parameters`. and `measurement_error`.\n", + "Here we build an experiment class to label our model problem for parameter estimation. The labels are defined as a `Suffix`, and the main labels for our model are `experiment_outputs`, `unknown_parameters`, and `measurement_error`.\n", "\n", "For this problem, the error will be computed for the mole fraction of benzene in the vapor and liquid phase between the model prediction and data. The `experimental_outputs` will therefore be the mole fraction of benzene in the two phases.\n", "\n", diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_usr.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_usr.ipynb index 3c7e80f9..1d5d1b1e 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_usr.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_state_block_usr.ipynb @@ -307,7 +307,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Here we build an experiment class to label our model problem for parameter estimation. The labels are defined as a `Suffix`, and the main labels for our model are `experiment_outputs`, `unknown_parameters`. and `measurement_error`.\n", + "Here we build an experiment class to label our model problem for parameter estimation. The labels are defined as a `Suffix`, and the main labels for our model are `experiment_outputs`, `unknown_parameters`, and `measurement_error`.\n", "\n", "For this problem, the error will be computed for the mole fraction of benzene in the vapor and liquid phase between the model prediction and data. The `experimental_outputs` will therefore be the mole fraction of benzene in the two phases.\n", "\n", diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb index c6897244..4bb23c01 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model.ipynb @@ -348,7 +348,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Here we build an experiment class to label our model problem for parameter estimation. The labels are defined as a `Suffix`, and the main labels for our model are `experiment_outputs`, `unknown_parameters`. and `measurement_error`.\n", + "Here we build an experiment class to label our model problem for parameter estimation. The labels are defined as a `Suffix`, and the main labels for our model are `experiment_outputs`, `unknown_parameters`, and `measurement_error`.\n", "\n", "For this problem, the error will be computed for the mole fraction of benzene in the vapor and liquid phase between the model prediction and data. The `experimental_outputs` will therefore be the mole fraction of benzene in the two phases.\n", "\n", diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_doc.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_doc.ipynb index 9f168b88..20914a4d 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_doc.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_doc.ipynb @@ -226,7 +226,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Here we build an experiment class to label our model problem for parameter estimation. The labels are defined as a `Suffix`, and the main labels for our model are `experiment_outputs`, `unknown_parameters`. and `measurement_error`.\n", + "Here we build an experiment class to label our model problem for parameter estimation. The labels are defined as a `Suffix`, and the main labels for our model are `experiment_outputs`, `unknown_parameters`, and `measurement_error`.\n", "\n", "For this problem, the error will be computed for the mole fraction of benzene in the vapor and liquid phase between the model prediction and data. The `experimental_outputs` will therefore be the mole fraction of benzene in the two phases.\n", "\n", diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_exercise.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_exercise.ipynb index be34d7d0..6eb2aa0a 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_exercise.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_exercise.ipynb @@ -219,7 +219,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Here we build an experiment class to label our model problem for parameter estimation. The labels are defined as a `Suffix`, and the main labels for our model are `experiment_outputs`, `unknown_parameters`. and `measurement_error`.\n", + "Here we build an experiment class to label our model problem for parameter estimation. The labels are defined as a `Suffix`, and the main labels for our model are `experiment_outputs`, `unknown_parameters`, and `measurement_error`.\n", "\n", "For this problem, the error will be computed for the mole fraction of benzene in the vapor and liquid phase between the model prediction and data. The `experimental_outputs` will therefore be the mole fraction of benzene in the two phases.\n", "\n", diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_solution.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_solution.ipynb index 9e64c1d9..ad88977a 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_solution.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_solution.ipynb @@ -311,7 +311,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Here we build an experiment class to label our model problem for parameter estimation. The labels are defined as a `Suffix`, and the main labels for our model are `experiment_outputs`, `unknown_parameters`. and `measurement_error`.\n", + "Here we build an experiment class to label our model problem for parameter estimation. The labels are defined as a `Suffix`, and the main labels for our model are `experiment_outputs`, `unknown_parameters`, and `measurement_error`.\n", "\n", "For this problem, the error will be computed for the mole fraction of benzene in the vapor and liquid phase between the model prediction and data. The `experimental_outputs` will therefore be the mole fraction of benzene in the two phases.\n", "\n", diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_test.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_test.ipynb index 5da23dde..26cc82ee 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_test.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_test.ipynb @@ -263,7 +263,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Here we build an experiment class to label our model problem for parameter estimation. The labels are defined as a `Suffix`, and the main labels for our model are `experiment_outputs`, `unknown_parameters`. and `measurement_error`.\n", + "Here we build an experiment class to label our model problem for parameter estimation. The labels are defined as a `Suffix`, and the main labels for our model are `experiment_outputs`, `unknown_parameters`, and `measurement_error`.\n", "\n", "For this problem, the error will be computed for the mole fraction of benzene in the vapor and liquid phase between the model prediction and data. The `experimental_outputs` will therefore be the mole fraction of benzene in the two phases.\n", "\n", diff --git a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_usr.ipynb b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_usr.ipynb index 9e64c1d9..ad88977a 100644 --- a/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_usr.ipynb +++ b/idaes_examples/notebooks/docs/param_est/parameter_estimation_nrtl_using_unit_model_usr.ipynb @@ -311,7 +311,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Here we build an experiment class to label our model problem for parameter estimation. The labels are defined as a `Suffix`, and the main labels for our model are `experiment_outputs`, `unknown_parameters`. and `measurement_error`.\n", + "Here we build an experiment class to label our model problem for parameter estimation. The labels are defined as a `Suffix`, and the main labels for our model are `experiment_outputs`, `unknown_parameters`, and `measurement_error`.\n", "\n", "For this problem, the error will be computed for the mole fraction of benzene in the vapor and liquid phase between the model prediction and data. The `experimental_outputs` will therefore be the mole fraction of benzene in the two phases.\n", "\n",