###############################################################################
# The Institute for the Design of Advanced Energy Systems Integrated Platform
# Framework (IDAES IP) was produced under the DOE Institute for the
# Design of Advanced Energy Systems (IDAES).
#
# Copyright (c) 2018-2024 by the software owners: The Regents of the
# University of California, through Lawrence Berkeley National Laboratory,
# National Technology & Engineering Solutions of Sandia, LLC, Carnegie Mellon
# University, West Virginia University Research Corporation, et al.
# All rights reserved. Please see the files COPYRIGHT.md and LICENSE.md
# for full copyright and license information.
###############################################################################
from enum import Enum
import pandas as pd
import numpy as np
import pyomo.environ as pyo
from pyomo.common.collections import ComponentSet, ComponentMap
from pyomo.util.calc_var_value import calculate_variable_from_constraint
import idaes.core.util.scaling as iscale
from pyomo.dae import DerivativeVar
from idaes.core.solvers import petsc
import idaes.logger as idaeslog
import idaes.core.util.model_serializer as ms
from idaes_examples.mod.power_gen.soc_dynamic_flowsheet import (
SocStandaloneFlowsheet as SocFlowsheet,
)
import matplotlib.pyplot as plt
from idaes.models.control.controller import (
ControllerType,
ControllerMVBoundType,
ControllerAntiwindupType,
)
from IPython.display import SVG, display
SOC Flowsheet — PID Control#
Author: Douglas Allan
Maintainer: Douglas Allan
Updated: 2024-26-03
1. Introduction#
This example is designed to demonstrate the use of PI controllers in a complex flowsheet to simulate ramping between different, predetermined setpoints. Steady-state optimization to obtain these setpoints is the subject of a future example.
2. Model Description#
The underlying flowsheet consists of a solid oxide cell (SOC) and supporting equipment consisting of electric trim heaters, heat exchangers, a blower for sweep air input, and a condenser to remove excess water from a hydrogen-rich stream. The flowsheet is sized appropriately to produce about 2 kg/s of hydrogen when at its current density limit. Power production mode is then sized to be whatever the net power production is at an average of 400 \(\text{mA}/\text{cm}^2\). The trim heaters and heat exchangers are modeled in considerable detail in order to accurately gauge the thermal capacitance of the system. The condenser, on the other hand, is modeled as having perfect control to keep its output temperature at \(45^\circ C\). The steam source (presumably an electric boiler) and hydrogen compression train (which would include additional condensers/water traps) are not modeled.
The OperatingScenario Enum allows the user to select which initial condition to use. The functions are helper functions for later.
class OperatingScenario(Enum):
maximum_production = 1
power_mode = 2
def scale_indexed_constraint(con, sf):
for idx, c in con.items():
iscale.constraint_scaling_transform(c, sf)
def set_indexed_variable_bounds(var, bounds):
for idx, subvar in var.items():
subvar.bounds = bounds
def create_ramping_eqns(fs, vars, time_scaling_factor=1):
def rule_ramp(b, t, dvdt, v_ramp):
return dvdt[t] == v_ramp[t]
t0 = fs.time.first()
for var in vars:
var.unfix()
shortname = var.name.split(".")[-1]
blk = var.parent_block()
dvdt = DerivativeVar(var, wrt=fs.time, initialize=0)
setattr(blk, "d" + shortname + "dt", dvdt)
v_ramp = pyo.Var(fs.time, initialize=0)
setattr(blk, shortname + "_ramp_rate", v_ramp)
v_ramp_eqn = pyo.Constraint(
fs.time, rule=lambda b, t: rule_ramp(b, t, dvdt, v_ramp)
)
setattr(blk, shortname + "_ramp_rate_eqn", v_ramp_eqn)
for t in fs.time:
sv = iscale.get_scaling_factor(var[t], default=1)
iscale.set_scaling_factor(dvdt[t], sv / time_scaling_factor)
iscale.set_scaling_factor(v_ramp[t], sv / time_scaling_factor)
iscale.constraint_scaling_transform(v_ramp_eqn[t], sv / time_scaling_factor)
v_ramp_eqn[t0].deactivate()
v_ramp[t0].fix(0)
We begin by ramping from the maximum H2 production setpoint to maximum power production. The ramp starts at one hour, the ramp lasts five minutes, the system is allowed to settle at maximum power mode for two hours, there is another five minute ramp back to maximum H2 production, then the system is given three hours to settle at the end.
operating_scenario = OperatingScenario.maximum_production
m = pyo.ConcreteModel()
t_start = 1 * 60 * 60
t_ramp = 5 * 60
t_settle = 2 * 60 * 60
t_end = 3 * 60 * 60
dt_set = [t_start, t_ramp, t_settle, t_ramp, t_end]
time_set = [sum(dt_set[:j]) for j in range(len(dt_set) + 1)]
# The names here correspond to the row names in
# soec_flowsheet_operating_conditions.csv
# There should be len(time_set) entries here.
# We start simulating a period at maximum production
# in order to confirm the system is at steady state.
if operating_scenario == OperatingScenario.maximum_production:
setpoints = [
"maximum_H2",
"maximum_H2",
"power",
"power",
"maximum_H2",
"maximum_H2",
]
elif operating_scenario == OperatingScenario.power_mode:
setpoints = [
"power",
"power",
"maximum_H2",
"maximum_H2",
"power",
"power",
]
else:
raise RuntimeError("Please choose a valid operating scenario")
m.fs = SocFlowsheet(
dynamic=True,
time_set=time_set,
time_units=pyo.units.s,
thin_electrolyte_and_oxygen_electrode=True,
include_interconnect=True,
)
scaling_log = idaeslog.getLogger("idaes.core.util.scaling")
scaling_log.setLevel(idaeslog.ERROR)
iscale.calculate_scaling_factors(m)
2025-10-27 10:39:12 [WARNING] idaes.models.properties.modular_properties.transport_properties.no_method: Skipping construction of thermal conductivity for phase Liq
2025-10-27 10:39:12 [WARNING] idaes.models.properties.modular_properties.transport_properties.no_method: Skipping construction of dynamic viscosity for phase Liq
Interior point solvers like IPOPT have difficulties when unconstrained solutions occur too close to variable bounds. We therefore strip bounds from some variables that previous simulations have shown to be causing problems.
for t in m.fs.time:
m.fs.condenser_flash.control_volume.properties_in[t].flow_mol_phase[
"Liq"
].domain = pyo.Reals
m.fs.condenser_flash.control_volume.properties_in[t].flow_mol_phase[
"Liq"
].bounds = (None, None)
m.fs.condenser_flash.control_volume.properties_in[t].phase_frac[
"Liq"
].domain = pyo.Reals
m.fs.condenser_flash.control_volume.properties_in[t].phase_frac["Liq"].bounds = (
None,
None,
)
for var in [
m.fs.condenser_flash.control_volume.properties_in[t].log_mole_frac_tdew,
m.fs.condenser_flash.control_volume.properties_in[t]._mole_frac_tdew,
]:
for idx in var.index_set():
var[idx].domain = pyo.Reals
var[idx].bounds = (None, None)
3. Process Control#
Now we add controllers to the flowsheet. The flowsheet has a helper function, add_controllers that adds the controllers if passed a ComponentMap that maps manipulated variables (MVs) to tuples that specify the controller. The tuple contains the controller name, the corresponding controlled variable (CV), the type of controller used, the way the controller handles MV bounds, and the antiwindup method.
We restrict ourselves to using P and PI controllers, because derivative action is severely degraded by noise, but PETSc cannot incorporate noise into its simulations.
Controllers can either have no bounds with the NONE option (which may result in use of unphysical controls), the SMOOTH_BOUND option which uses smooth max and min functions in order to keep the MV within certain thresholds, and the LOGISTIC option, which uses a logistic function to keep the MV within bounds. The LOGISTIC option is a worse representation of an actual thresholding function than SMOOTH_BOUND but may be easier for integrators to handle.
When both variable bounds and integral action are present, integral windup is a problem. If one uses the NONE option, no antiwindup is used. If one uses the CONDITIONAL_INTEGRATION method, setpoint error does not integrate when the system is at its bounds. This method is relatively easy to implement but the transition between integrating and not integrating causes integrators to slow down significantly. The BACK_CALCULATION method subtracts an amount proportional to the difference between the current MV value and the value that the controller would use without variable bounds from the integrated error. This method gives better performance (and is much easier to integrate) than CONDITIONAL_INTEGRATION, but it requires a back calculation gain term to be chosen.
antiwindup = ControllerAntiwindupType.BACK_CALCULATION
inner_controller_pairs = ComponentMap()
inner_controller_pairs[m.fs.feed_heater.electric_heat_duty] = (
"feed_heater_inner_controller",
m.fs.soc_module.fuel_inlet.temperature,
ControllerType.PI,
ControllerMVBoundType.SMOOTH_BOUND,
antiwindup,
)
inner_controller_pairs[m.fs.sweep_heater.electric_heat_duty] = (
"sweep_heater_inner_controller",
m.fs.soc_module.oxygen_inlet.temperature,
ControllerType.PI,
ControllerMVBoundType.SMOOTH_BOUND,
antiwindup,
)
m.fs.add_controllers(inner_controller_pairs)
variable_pairs = ComponentMap()
variable_pairs[m.fs.feed_heater_inner_controller.setpoint] = (
"feed_heater_outer_controller",
m.fs.soc_module.fuel_outlet.temperature,
ControllerType.P,
ControllerMVBoundType.NONE,
ControllerAntiwindupType.NONE,
)
variable_pairs[m.fs.sweep_heater_inner_controller.setpoint] = (
"sweep_heater_outer_controller",
m.fs.soc_module.oxygen_outlet.temperature,
ControllerType.P,
ControllerMVBoundType.NONE,
ControllerAntiwindupType.NONE,
)
variable_pairs[m.fs.soc_module.potential_cell] = (
"voltage_controller",
m.fs.soc_module.fuel_outlet_mole_frac_comp_H2,
ControllerType.PI,
ControllerMVBoundType.SMOOTH_BOUND,
antiwindup,
)
variable_pairs[m.fs.sweep_blower.inlet.flow_mol] = (
"sweep_blower_controller",
m.fs.stack_core_temperature,
ControllerType.P,
ControllerMVBoundType.SMOOTH_BOUND,
# antiwindup,
ControllerAntiwindupType.NONE,
)
variable_pairs[m.fs.makeup_mix.makeup.flow_mol] = (
"h2_production_rate_controller",
m.fs.h2_mass_production,
ControllerType.P,
ControllerMVBoundType.SMOOTH_BOUND,
ControllerAntiwindupType.NONE,
# antiwindup,
)
m.fs.add_controllers(variable_pairs)
Now that the controllers have been added to the flowsheet, they need to be tuned and bounds for the MVs need to be set. Additionally, the smooth_eps term used in the SMOOTH_BOUND method of handling variable bounds needs to be tuned to the size of the MV. A heuristic is to use \(10^{-3}\) or \(10^{-4}\) a typical value of the MV.
K = 10e4
tau_I = 15 * 60
tau_D = 5 * 60
m.fs.feed_heater_inner_controller.gain_p.fix(K)
m.fs.feed_heater_inner_controller.gain_i.fix(K / tau_I)
m.fs.feed_heater_inner_controller.mv_lb = 0
m.fs.feed_heater_inner_controller.mv_ub = 10e6
m.fs.feed_heater_inner_controller.smooth_eps = 1000
if antiwindup == ControllerAntiwindupType.BACK_CALCULATION:
m.fs.feed_heater_inner_controller.gain_b.fix(0.5 / tau_I)
K = 20e4
tau_I = 15 * 60
tau_D = 5 * 60
m.fs.sweep_heater_inner_controller.gain_p.fix(K)
m.fs.sweep_heater_inner_controller.gain_i.fix(K / tau_I)
m.fs.sweep_heater_inner_controller.mv_lb = 0
m.fs.sweep_heater_inner_controller.mv_ub = 10e6
m.fs.sweep_heater_inner_controller.smooth_eps = 1000
if antiwindup == ControllerAntiwindupType.BACK_CALCULATION:
m.fs.sweep_heater_inner_controller.gain_b.fix(0.5 / tau_I)
K = 0.75
tau_I = 60 * 60
m.fs.feed_heater_outer_controller.gain_p.fix(K)
K = 0.75
tau_I = 60 * 60
m.fs.sweep_heater_outer_controller.gain_p.fix(K)
K = -2
tau_I = 240
m.fs.voltage_controller.gain_p.fix(K)
m.fs.voltage_controller.gain_i.fix(K / tau_I)
m.fs.voltage_controller.mv_lb = 0.7
m.fs.voltage_controller.mv_ub = 1.6
m.fs.voltage_controller.smooth_eps = 0.01
if antiwindup == ControllerAntiwindupType.BACK_CALCULATION:
m.fs.voltage_controller.gain_b.fix(0.5 / tau_I)
K = -50
tau_I = 40 * 60
m.fs.sweep_blower_controller.gain_p.fix(K)
m.fs.sweep_blower_controller.mv_lb = 1500
m.fs.sweep_blower_controller.mv_ub = 10000
m.fs.sweep_blower_controller.smooth_eps = 10
K = 200
tau_I = 20 * 60
m.fs.h2_production_rate_controller.gain_p.fix(K)
m.fs.h2_production_rate_controller.mv_lb = 1
m.fs.h2_production_rate_controller.mv_ub = 1500
m.fs.h2_production_rate_controller.smooth_eps = 1
Most MVs we want to ramp between the old and new setpoints, but there are a few, especially when changing the controller gain, that we need to step.
step_mvs = ComponentSet([])
step_mvs.add(m.fs.voltage_controller.mv_ref)
step_mvs.add(m.fs.voltage_controller.setpoint)
step_mvs.add(m.fs.makeup_mix.makeup_mole_frac_comp_H2)
step_mvs.add(m.fs.makeup_mix.makeup_mole_frac_comp_H2O)
step_mvs.add(m.fs.h2_production_rate_controller.setpoint)
step_mvs.add(m.fs.h2_production_rate_controller.gain_p)
ramp_mvs = m.fs.manipulated_variables - step_mvs
create_ramping_eqns(m.fs, ramp_mvs, 1)
In the present system of scaling, we cannot guarantee that controller MVs and CVs have had scaling factors set when a controller is scaled, so we need to iterate through the controllers and scale them again after the fact.
for ctrl in m.fs.controller_set:
iscale.calculate_scaling_factors(ctrl)
iscale.calculate_scaling_factors(ctrl)
Discretize the time domain. We choose time_nfe to be one less than the length of m.fs.time so that Pyomo doesn’t create any additional time points. After the time discretization equations are created, they are then scaled.
time_nfe = len(m.fs.time) - 1
pyo.TransformationFactory("dae.finite_difference").apply_to(
m.fs, nfe=time_nfe, wrt=m.fs.time, scheme="BACKWARD"
)
iscale.scale_time_discretization_equations(m, m.fs.time, 1 / (60 * 5))
Load and fix the right initial condition. The .json.gz file is generated beforehand by a steady-state optimization. In this case, all these files are pregenerated and committed to the examples repo.
Since we are loading an initial condition from a file, we don’t need to solve a steady state problem at t=0. Therefore, we need to fix variables corresponding to the differential variables of the system and deactivate certain equations that become degenerate.
if operating_scenario == OperatingScenario.maximum_production:
ms.from_json(m, fname="max_production.json.gz", wts=ms.StoreSpec.value())
elif operating_scenario == OperatingScenario.power_mode:
ms.from_json(m, fname="power_mode.json.gz", wts=ms.StoreSpec.value())
m.fs.fix_initial_conditions()
Now that we have loaded an initial condition, we can view it in the flowsheet. The write_pfd function iterates through a template .svg file and adds numbers to it by comparing the object name in the .svg to tags in the flowsheet.
m.fs.write_pfd(fname="soc_dynamic_flowsheet.svg")
display(
"SOC Dynamic Flowsheet",
SVG(filename="soc_dynamic_flowsheet.svg"),
)
'SOC Dynamic Flowsheet'
We create a ComponentMap to translate between the column names in soec_flowsheet_operating_conditions.csv to the variables in the actual flowsheet so we can use them as setpoints.
alias_dict = ComponentMap()
alias_dict[m.fs.voltage_controller.mv_ref] = "potential"
alias_dict[m.fs.voltage_controller.setpoint] = "soc_fuel_outlet_mole_frac_comp_H2"
alias_dict[m.fs.soc_module.fuel_outlet_mole_frac_comp_H2] = (
"soc_fuel_outlet_mole_frac_comp_H2"
)
alias_dict[m.fs.h2_production_rate_controller.mv_ref] = "makeup_feed_rate"
alias_dict[m.fs.h2_production_rate_controller.setpoint] = "h2_production_rate"
alias_dict[m.fs.h2_production_rate_controller.gain_p] = (
"h2_production_rate_controller_gain_p"
)
alias_dict[m.fs.sweep_blower_controller.mv_ref] = "sweep_feed_rate"
alias_dict[m.fs.sweep_blower_controller.setpoint] = "stack_core_temperature"
alias_dict[m.fs.feed_heater_inner_controller.mv_ref] = "feed_heater_duty"
alias_dict[m.fs.feed_heater_outer_controller.mv_ref] = "feed_heater_outlet_temperature"
alias_dict[m.fs.feed_heater_outer_controller.setpoint] = "fuel_outlet_temperature"
alias_dict[m.fs.sweep_heater_inner_controller.mv_ref] = "sweep_heater_duty"
alias_dict[m.fs.sweep_heater_outer_controller.mv_ref] = (
"sweep_heater_outlet_temperature"
)
alias_dict[m.fs.sweep_heater_outer_controller.setpoint] = "sweep_outlet_temperature"
alias_dict[m.fs.makeup_mix.makeup_mole_frac_comp_H2] = "makeup_mole_frac_comp_H2"
alias_dict[m.fs.makeup_mix.makeup_mole_frac_comp_H2O] = "makeup_mole_frac_comp_H2O"
alias_dict[m.fs.condenser_flash.vap_outlet.temperature] = (
"condenser_hot_outlet_temperature"
)
alias_dict[m.fs.sweep_recycle_split.recycle_ratio] = "sweep_recycle_ratio"
alias_dict[m.fs.feed_recycle_split.recycle_ratio] = "fuel_recycle_ratio"
alias_dict[m.fs.condenser_split.recycle_ratio] = "vgr_recycle_ratio"
df = pd.read_csv("soec_flowsheet_operating_conditions.csv", index_col=0)
These loops iterate through the flowsheet and fix ramp rate variables or set variables to the appropriate values for the given setpoints.
t0 = m.fs.time.first()
for var in ramp_mvs:
shortname = var.name.split(".")[-1]
alias = alias_dict[var]
blk = var.parent_block()
v_ramp = getattr(blk, shortname + "_ramp_rate")
var[t0].fix(float(df[alias][setpoints[0]]))
for i, t in enumerate(time_set):
v_ramp[t].fix(
float(
(df[alias][setpoints[i]] - df[alias][setpoints[i - 1]])
/ (time_set[i] - time_set[i - 1])
)
)
for var in step_mvs:
shortname = var.name.split(".")[-1]
alias = alias_dict[var]
for i, t in enumerate(time_set):
var[t].fix(float(df[alias][setpoints[i]]))
Here we initialize the controllers. Unit model .initialize methods tend to be for steady state optimization, so we manually set variable values and calculate variables from constraints.
# Need to initialize the setpoint for the inner controller or else it starts with the default value 0.5.
m.fs.feed_heater_inner_controller.setpoint[0].value = (
m.fs.feed_heater_outer_controller.mv_ref[0].value
)
m.fs.sweep_heater_inner_controller.setpoint[0].value = (
m.fs.sweep_heater_outer_controller.mv_ref[0].value
)
for ctrl in m.fs.controller_set:
if hasattr(ctrl, "mv_eqn"):
calculate_variable_from_constraint(ctrl.manipulated_var[0], ctrl.mv_eqn[0])
Here we run PETSc to integrate the flowsheet with the TS integrator. Because we are loading from a solved flowsheet, in principle we could set skip_initial=True. However, due to user error there is sometimes a discrepancy between the setpoints loaded and the initial conditions loaded, so we leave it in. There are many options for PETSc-TS that can be read about in the PETSc documentation.
idaeslog.solver_log.tee = True
results = petsc.petsc_dae_by_time_element(
m,
time=m.fs.time,
keepfiles=True,
symbolic_solver_labels=True,
ts_options={
"--ts_type": "beuler",
"--ts_dt": 0.1,
"--ts_rtol": 1e-3,
# "--ts_adapt_clip":"0.001,3600",
# "--ksp_monitor":"",
"--ts_adapt_dt_min": 1e-3,
"--ts_adapt_dt_max": 3600,
"--snes_type": "newtontr",
# "--ts_max_reject": 200,
# "--snes_monitor":"",
"--ts_monitor": "",
"--ts_save_trajectory": 1,
"--ts_trajectory_type": "visualization",
"--ts_max_snes_failures": 25,
# "--show_cl":"",
"-snes_max_it": 50,
"-snes_rtol": 0,
"-snes_stol": 0,
"-snes_atol": 1e-6,
},
skip_initial=False,
initial_solver="ipopt",
initial_solver_options={
"constr_viol_tol": 1e-8,
"nlp_scaling_method": "user-scaling",
"linear_solver": "ma57",
"OF_ma57_automatic_scaling": "yes",
"max_iter": 300,
"tol": 1e-8,
"halt_on_ampl_error": "no",
},
)
for result in results.results:
pyo.assert_optimal_termination(result)
WARNING: model contains export suffix 'scaling_factor' that contains 457
component keys that are not exported as part of the NL file. Skipping.
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae: Ipopt 3.13.2: constr_viol_tol=1e-08
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae: nlp_scaling_method=user-scaling
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae: linear_solver=ma57
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae: max_iter=300
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae: tol=1e-08
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae: halt_on_ampl_error=no
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae: option_file_name=C:\Users\dallan\AppData\Local\Temp\tmpk74hymrw_ipopt.opt
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae:
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae: Using option file "C:\Users\dallan\AppData\Local\Temp\tmpk74hymrw_ipopt.opt".
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae:
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae:
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae: ******************************************************************************
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae: This program contains Ipopt, a library for large-scale nonlinear optimization.
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae: Ipopt is released as open source code under the Eclipse Public License (EPL).
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae: For more information visit http://projects.coin-or.org/Ipopt
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae:
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae: This version of Ipopt was compiled from source code available at
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae: https://github.com/IDAES/Ipopt as part of the Institute for the Design of
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae: Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae: Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae:
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae: This version of Ipopt was compiled using HSL, a collection of Fortran codes
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae: for large-scale scientific computation. All technical papers, sales and
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae: publicity material resulting from use of the HSL codes within IPOPT must
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae: contain the following acknowledgement:
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae: HSL, a collection of Fortran codes for large-scale scientific
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae: computation. See http://www.hsl.rl.ac.uk.
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae: ******************************************************************************
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae:
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae: This is Ipopt version 3.13.2, running with linear solver ma57.
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae:
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae: Number of nonzeros in equality constraint Jacobian...: 16536
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae: Number of nonzeros in inequality constraint Jacobian.: 0
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae: Number of nonzeros in Lagrangian Hessian.............: 10354
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae:
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae: Total number of variables............................: 4194
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae: variables with only lower bounds: 723
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae: variables with lower and upper bounds: 1707
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae: variables with only upper bounds: 31
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae: Total number of equality constraints.................: 4194
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae: Total number of inequality constraints...............: 0
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae: inequality constraints with only lower bounds: 0
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae: inequality constraints with lower and upper bounds: 0
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae: inequality constraints with only upper bounds: 0
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae:
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae: iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae: 0 0.0000000e+00 7.08e-01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae: Reallocating memory for MA57: lfact (327732)
2025-10-27 10:39:44 [INFO] idaes.solve.petsc-dae: 1 0.0000000e+00 1.06e-02 1.64e+02 -1.0 1.57e-02 - 9.90e-01 9.85e-01h 1
2025-10-27 10:39:45 [INFO] idaes.solve.petsc-dae: 2 0.0000000e+00 1.05e-04 1.72e+02 -1.0 1.80e-02 - 9.90e-01 9.90e-01h 1
2025-10-27 10:39:45 [INFO] idaes.solve.petsc-dae: 3 0.0000000e+00 3.52e-07 2.82e+04 -1.0 6.27e-03 - 1.00e+00 9.97e-01h 1
2025-10-27 10:39:45 [INFO] idaes.solve.petsc-dae: 4 0.0000000e+00 3.05e-11 4.27e+03 -1.0 7.30e-04 - 1.00e+00 1.00e+00h 1
2025-10-27 10:39:45 [INFO] idaes.solve.petsc-dae:
2025-10-27 10:39:45 [INFO] idaes.solve.petsc-dae: Number of Iterations....: 4
2025-10-27 10:39:45 [INFO] idaes.solve.petsc-dae:
2025-10-27 10:39:45 [INFO] idaes.solve.petsc-dae: (scaled) (unscaled)
2025-10-27 10:39:45 [INFO] idaes.solve.petsc-dae: Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00
2025-10-27 10:39:45 [INFO] idaes.solve.petsc-dae: Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00
2025-10-27 10:39:45 [INFO] idaes.solve.petsc-dae: Constraint violation....: 3.0518274817729390e-11 3.0518274817729390e-11
2025-10-27 10:39:45 [INFO] idaes.solve.petsc-dae: Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00
2025-10-27 10:39:45 [INFO] idaes.solve.petsc-dae: Overall NLP error.......: 3.0518274817729390e-11 3.0518274817729390e-11
2025-10-27 10:39:45 [INFO] idaes.solve.petsc-dae:
2025-10-27 10:39:45 [INFO] idaes.solve.petsc-dae:
2025-10-27 10:39:45 [INFO] idaes.solve.petsc-dae: Number of objective function evaluations = 5
2025-10-27 10:39:45 [INFO] idaes.solve.petsc-dae: Number of objective gradient evaluations = 5
2025-10-27 10:39:45 [INFO] idaes.solve.petsc-dae: Number of equality constraint evaluations = 5
2025-10-27 10:39:45 [INFO] idaes.solve.petsc-dae: Number of inequality constraint evaluations = 0
2025-10-27 10:39:45 [INFO] idaes.solve.petsc-dae: Number of equality constraint Jacobian evaluations = 5
2025-10-27 10:39:45 [INFO] idaes.solve.petsc-dae: Number of inequality constraint Jacobian evaluations = 0
2025-10-27 10:39:45 [INFO] idaes.solve.petsc-dae: Number of Lagrangian Hessian evaluations = 4
2025-10-27 10:39:45 [INFO] idaes.solve.petsc-dae: Total CPU secs in IPOPT (w/o function evaluations) = 0.261
2025-10-27 10:39:45 [INFO] idaes.solve.petsc-dae: Total CPU secs in NLP function evaluations = 0.043
2025-10-27 10:39:45 [INFO] idaes.solve.petsc-dae:
2025-10-27 10:39:45 [INFO] idaes.solve.petsc-dae: EXIT: Optimal Solution Found.
WARNING: model contains export suffix 'scaling_factor' that contains 291
component keys that are not exported as part of the NL file. Skipping.
2025-10-27 10:39:57 [INFO] idaes.solve.petsc-dae: Solver log file: 'C:\Users\dallan\AppData\Local\Temp\tmp04mf15n5_petsc_ts.log'
2025-10-27 10:39:57 [INFO] idaes.solve.petsc-dae: Solver solution file: 'C:\Users\dallan\AppData\Local\Temp\tmplql10r7w.pyomo.sol'
2025-10-27 10:39:57 [INFO] idaes.solve.petsc-dae: Solver problem files: ('C:\\Users\\dallan\\AppData\\Local\\Temp\\tmplql10r7w.pyomo.nl',)
2025-10-27 10:39:58 [INFO] idaes.solve.petsc-dae: Called fg_read, err: 0 (0 is good)
2025-10-27 10:39:58 [INFO] idaes.solve.petsc-dae: ---------------------------------------------------
2025-10-27 10:39:58 [INFO] idaes.solve.petsc-dae: DAE: 1
2025-10-27 10:39:58 [INFO] idaes.solve.petsc-dae: Reading nl file: C:\Users\dallan\AppData\Local\Temp\tmplql10r7w.pyomo.nl
2025-10-27 10:39:58 [INFO] idaes.solve.petsc-dae: Number of constraints: 4258
2025-10-27 10:39:58 [INFO] idaes.solve.petsc-dae: Number of nonlinear constraints: 1981
2025-10-27 10:39:58 [INFO] idaes.solve.petsc-dae: Number of linear constraints: 2277
2025-10-27 10:39:58 [INFO] idaes.solve.petsc-dae: Number of inequalities: 0
2025-10-27 10:39:58 [INFO] idaes.solve.petsc-dae: Number of variables: 4353
2025-10-27 10:39:58 [INFO] idaes.solve.petsc-dae: Number of integers: 0
2025-10-27 10:39:58 [INFO] idaes.solve.petsc-dae: Number of binary: 0
2025-10-27 10:39:58 [INFO] idaes.solve.petsc-dae: Number of objectives: 0 (Ignoring)
2025-10-27 10:39:58 [INFO] idaes.solve.petsc-dae: Number of non-zeros in Jacobian: 17083
2025-10-27 10:39:58 [INFO] idaes.solve.petsc-dae: Explicit time variable: 0
2025-10-27 10:39:58 [INFO] idaes.solve.petsc-dae: Number of derivatives: 95
2025-10-27 10:39:58 [INFO] idaes.solve.petsc-dae: Number of differential vars: 95
2025-10-27 10:39:58 [INFO] idaes.solve.petsc-dae: Number of algebraic vars: 4163
2025-10-27 10:39:58 [INFO] idaes.solve.petsc-dae: Number of state vars: 4258
2025-10-27 10:39:58 [INFO] idaes.solve.petsc-dae: Number of degrees of freedom: 0
2025-10-27 10:39:58 [INFO] idaes.solve.petsc-dae: ---------------------------------------------------
2025-10-27 10:39:58 [INFO] idaes.solve.petsc-dae: 0 TS dt 0.1 time 0.
2025-10-27 10:39:58 [INFO] idaes.solve.petsc-dae: 1 TS dt 0.1 time 0.1
2025-10-27 10:39:58 [INFO] idaes.solve.petsc-dae: 2 TS dt 0.428051 time 0.2
2025-10-27 10:39:58 [INFO] idaes.solve.petsc-dae: 3 TS dt 4.28051 time 0.628051
2025-10-27 10:39:58 [INFO] idaes.solve.petsc-dae: 4 TS dt 42.8051 time 4.90857
2025-10-27 10:39:58 [INFO] idaes.solve.petsc-dae: 5 TS dt 90.9897 time 47.7137
2025-10-27 10:39:58 [INFO] idaes.solve.petsc-dae: 6 TS dt 249.484 time 138.703
2025-10-27 10:39:58 [INFO] idaes.solve.petsc-dae: 7 TS dt 931.416 time 388.187
2025-10-27 10:39:58 [INFO] idaes.solve.petsc-dae: 8 TS dt 2280.4 time 1319.6
2025-10-27 10:39:58 [INFO] idaes.solve.petsc-dae: 9 TS dt 3600. time 3600.
2025-10-27 10:39:58 [INFO] idaes.solve.petsc-dae: TSConvergedReason = TS_CONVERGED_TIME
2025-10-27 10:39:58 [INFO] idaes.solve.petsc-dae: TS_CONVERGED_TIME
WARNING: model contains export suffix 'scaling_factor' that contains 376
component keys that are not exported as part of the NL file. Skipping.
2025-10-27 10:40:02 [INFO] idaes.solve.petsc-dae: Solver log file: 'C:\Users\dallan\AppData\Local\Temp\tmpwl2pldeq_petsc_ts.log'
2025-10-27 10:40:02 [INFO] idaes.solve.petsc-dae: Solver solution file: 'C:\Users\dallan\AppData\Local\Temp\tmpu_8mtjnx.pyomo.sol'
2025-10-27 10:40:02 [INFO] idaes.solve.petsc-dae: Solver problem files: ('C:\\Users\\dallan\\AppData\\Local\\Temp\\tmpu_8mtjnx.pyomo.nl',)
2025-10-27 10:40:02 [INFO] idaes.solve.petsc-dae: Called fg_read, err: 0 (0 is good)
2025-10-27 10:40:02 [INFO] idaes.solve.petsc-dae: ---------------------------------------------------
2025-10-27 10:40:02 [INFO] idaes.solve.petsc-dae: DAE: 1
2025-10-27 10:40:02 [INFO] idaes.solve.petsc-dae: Reading nl file: C:\Users\dallan\AppData\Local\Temp\tmpu_8mtjnx.pyomo.nl
2025-10-27 10:40:02 [INFO] idaes.solve.petsc-dae: Number of constraints: 4258
2025-10-27 10:40:02 [INFO] idaes.solve.petsc-dae: Number of nonlinear constraints: 1981
2025-10-27 10:40:02 [INFO] idaes.solve.petsc-dae: Number of linear constraints: 2277
2025-10-27 10:40:02 [INFO] idaes.solve.petsc-dae: Number of inequalities: 0
2025-10-27 10:40:02 [INFO] idaes.solve.petsc-dae: Number of variables: 4353
2025-10-27 10:40:02 [INFO] idaes.solve.petsc-dae: Number of integers: 0
2025-10-27 10:40:02 [INFO] idaes.solve.petsc-dae: Number of binary: 0
2025-10-27 10:40:02 [INFO] idaes.solve.petsc-dae: Number of objectives: 0 (Ignoring)
2025-10-27 10:40:02 [INFO] idaes.solve.petsc-dae: Number of non-zeros in Jacobian: 17083
2025-10-27 10:40:02 [INFO] idaes.solve.petsc-dae: Explicit time variable: 0
2025-10-27 10:40:02 [INFO] idaes.solve.petsc-dae: Number of derivatives: 95
2025-10-27 10:40:02 [INFO] idaes.solve.petsc-dae: Number of differential vars: 95
2025-10-27 10:40:02 [INFO] idaes.solve.petsc-dae: Number of algebraic vars: 4163
2025-10-27 10:40:02 [INFO] idaes.solve.petsc-dae: Number of state vars: 4258
2025-10-27 10:40:02 [INFO] idaes.solve.petsc-dae: Number of degrees of freedom: 0
2025-10-27 10:40:02 [INFO] idaes.solve.petsc-dae: ---------------------------------------------------
2025-10-27 10:40:02 [INFO] idaes.solve.petsc-dae: 0 TS dt 0.1 time 3600.
2025-10-27 10:40:02 [INFO] idaes.solve.petsc-dae: 1 TS dt 0.1 time 3600.1
2025-10-27 10:40:02 [INFO] idaes.solve.petsc-dae: 2 TS dt 0.00192587 time 3600.1
2025-10-27 10:40:02 [INFO] idaes.solve.petsc-dae: 3 TS dt 0.0192587 time 3600.1
2025-10-27 10:40:02 [INFO] idaes.solve.petsc-dae: 4 TS dt 0.192587 time 3600.12
2025-10-27 10:40:03 [INFO] idaes.solve.petsc-dae: 5 TS dt 0.773565 time 3600.31
2025-10-27 10:40:03 [INFO] idaes.solve.petsc-dae: 6 TS dt 1.0239 time 3601.09
2025-10-27 10:40:03 [INFO] idaes.solve.petsc-dae: 7 TS dt 1.35581 time 3602.11
2025-10-27 10:40:03 [INFO] idaes.solve.petsc-dae: 8 TS dt 1.42841 time 3603.47
2025-10-27 10:40:03 [INFO] idaes.solve.petsc-dae: 9 TS dt 1.56123 time 3604.9
2025-10-27 10:40:03 [INFO] idaes.solve.petsc-dae: 10 TS dt 1.53345 time 3606.46
2025-10-27 10:40:03 [INFO] idaes.solve.petsc-dae: 11 TS dt 1.67474 time 3607.99
2025-10-27 10:40:03 [INFO] idaes.solve.petsc-dae: 12 TS dt 1.70162 time 3609.67
2025-10-27 10:40:03 [INFO] idaes.solve.petsc-dae: 13 TS dt 1.76709 time 3611.37
2025-10-27 10:40:03 [INFO] idaes.solve.petsc-dae: 14 TS dt 1.80265 time 3613.13
2025-10-27 10:40:03 [INFO] idaes.solve.petsc-dae: 15 TS dt 1.89285 time 3614.94
2025-10-27 10:40:04 [INFO] idaes.solve.petsc-dae: 16 TS dt 1.81475 time 3616.83
2025-10-27 10:40:04 [INFO] idaes.solve.petsc-dae: 17 TS dt 1.79379 time 3618.64
2025-10-27 10:40:04 [INFO] idaes.solve.petsc-dae: 18 TS dt 2.18529 time 3620.44
2025-10-27 10:40:04 [INFO] idaes.solve.petsc-dae: 19 TS dt 2.26992 time 3622.62
2025-10-27 10:40:04 [INFO] idaes.solve.petsc-dae: 20 TS dt 2.11354 time 3624.89
2025-10-27 10:40:04 [INFO] idaes.solve.petsc-dae: 21 TS dt 2.33315 time 3627.01
2025-10-27 10:40:04 [INFO] idaes.solve.petsc-dae: 22 TS dt 2.44773 time 3629.34
2025-10-27 10:40:04 [INFO] idaes.solve.petsc-dae: 23 TS dt 2.35111 time 3631.79
2025-10-27 10:40:04 [INFO] idaes.solve.petsc-dae: 24 TS dt 0.781707 time 3632.24
2025-10-27 10:40:05 [INFO] idaes.solve.petsc-dae: 25 TS dt 2.34754 time 3633.02
2025-10-27 10:40:05 [INFO] idaes.solve.petsc-dae: 26 TS dt 2.63991 time 3635.37
2025-10-27 10:40:05 [INFO] idaes.solve.petsc-dae: 27 TS dt 3.57975 time 3638.01
2025-10-27 10:40:05 [INFO] idaes.solve.petsc-dae: 28 TS dt 3.84204 time 3641.59
2025-10-27 10:40:05 [INFO] idaes.solve.petsc-dae: 29 TS dt 4.41048 time 3645.43
2025-10-27 10:40:05 [INFO] idaes.solve.petsc-dae: 30 TS dt 4.63714 time 3649.84
2025-10-27 10:40:05 [INFO] idaes.solve.petsc-dae: 31 TS dt 1.56505 time 3650.73
2025-10-27 10:40:05 [INFO] idaes.solve.petsc-dae: 32 TS dt 4.05836 time 3652.3
2025-10-27 10:40:06 [INFO] idaes.solve.petsc-dae: 33 TS dt 4.62866 time 3656.36
2025-10-27 10:40:06 [INFO] idaes.solve.petsc-dae: 34 TS dt 5.69237 time 3660.99
2025-10-27 10:40:06 [INFO] idaes.solve.petsc-dae: 35 TS dt 6.03798 time 3666.68
2025-10-27 10:40:06 [INFO] idaes.solve.petsc-dae: 36 TS dt 6.65395 time 3672.72
2025-10-27 10:40:06 [INFO] idaes.solve.petsc-dae: 37 TS dt 7.06769 time 3679.37
2025-10-27 10:40:06 [INFO] idaes.solve.petsc-dae: 38 TS dt 7.59622 time 3686.44
2025-10-27 10:40:06 [INFO] idaes.solve.petsc-dae: 39 TS dt 8.05664 time 3694.03
2025-10-27 10:40:06 [INFO] idaes.solve.petsc-dae: 40 TS dt 8.51293 time 3702.09
2025-10-27 10:40:06 [INFO] idaes.solve.petsc-dae: 41 TS dt 8.84319 time 3710.6
2025-10-27 10:40:07 [INFO] idaes.solve.petsc-dae: 42 TS dt 8.90564 time 3719.45
2025-10-27 10:40:07 [INFO] idaes.solve.petsc-dae: 43 TS dt 8.08811 time 3728.35
2025-10-27 10:40:07 [INFO] idaes.solve.petsc-dae: 44 TS dt 8.36063 time 3736.44
2025-10-27 10:40:07 [INFO] idaes.solve.petsc-dae: 45 TS dt 9.35735 time 3744.8
2025-10-27 10:40:07 [INFO] idaes.solve.petsc-dae: 46 TS dt 10.2149 time 3754.16
2025-10-27 10:40:07 [INFO] idaes.solve.petsc-dae: 47 TS dt 10.7521 time 3764.37
2025-10-27 10:40:07 [INFO] idaes.solve.petsc-dae: 48 TS dt 10.6608 time 3775.12
2025-10-27 10:40:07 [INFO] idaes.solve.petsc-dae: 49 TS dt 10.3517 time 3785.79
2025-10-27 10:40:07 [INFO] idaes.solve.petsc-dae: 50 TS dt 9.39277 time 3796.14
2025-10-27 10:40:07 [INFO] idaes.solve.petsc-dae: 51 TS dt 10.7893 time 3805.53
2025-10-27 10:40:08 [INFO] idaes.solve.petsc-dae: 52 TS dt 11.1973 time 3816.32
2025-10-27 10:40:08 [INFO] idaes.solve.petsc-dae: 53 TS dt 9.82286 time 3826.13
2025-10-27 10:40:08 [INFO] idaes.solve.petsc-dae: 54 TS dt 13.101 time 3835.95
2025-10-27 10:40:08 [INFO] idaes.solve.petsc-dae: 55 TS dt 13.092 time 3849.05
2025-10-27 10:40:08 [INFO] idaes.solve.petsc-dae: 56 TS dt 13.7479 time 3862.14
2025-10-27 10:40:08 [INFO] idaes.solve.petsc-dae: 57 TS dt 12.0538 time 3875.89
2025-10-27 10:40:08 [INFO] idaes.solve.petsc-dae: 58 TS dt 12.0538 time 3887.95
2025-10-27 10:40:08 [INFO] idaes.solve.petsc-dae: 59 TS dt 2.25146 time 3897.75
2025-10-27 10:40:09 [INFO] idaes.solve.petsc-dae: 60 TS dt 14.2905 time 3900.
2025-10-27 10:40:09 [INFO] idaes.solve.petsc-dae: TSConvergedReason = TS_CONVERGED_TIME
2025-10-27 10:40:09 [INFO] idaes.solve.petsc-dae: TS_CONVERGED_TIME
WARNING: model contains export suffix 'scaling_factor' that contains 376
component keys that are not exported as part of the NL file. Skipping.
2025-10-27 10:40:12 [INFO] idaes.solve.petsc-dae: Solver log file: 'C:\Users\dallan\AppData\Local\Temp\tmpira_xg7y_petsc_ts.log'
2025-10-27 10:40:12 [INFO] idaes.solve.petsc-dae: Solver solution file: 'C:\Users\dallan\AppData\Local\Temp\tmpkbeeqa_k.pyomo.sol'
2025-10-27 10:40:12 [INFO] idaes.solve.petsc-dae: Solver problem files: ('C:\\Users\\dallan\\AppData\\Local\\Temp\\tmpkbeeqa_k.pyomo.nl',)
2025-10-27 10:40:12 [INFO] idaes.solve.petsc-dae: Called fg_read, err: 0 (0 is good)
2025-10-27 10:40:12 [INFO] idaes.solve.petsc-dae: ---------------------------------------------------
2025-10-27 10:40:12 [INFO] idaes.solve.petsc-dae: DAE: 1
2025-10-27 10:40:12 [INFO] idaes.solve.petsc-dae: Reading nl file: C:\Users\dallan\AppData\Local\Temp\tmpkbeeqa_k.pyomo.nl
2025-10-27 10:40:12 [INFO] idaes.solve.petsc-dae: Number of constraints: 4258
2025-10-27 10:40:12 [INFO] idaes.solve.petsc-dae: Number of nonlinear constraints: 1981
2025-10-27 10:40:12 [INFO] idaes.solve.petsc-dae: Number of linear constraints: 2277
2025-10-27 10:40:12 [INFO] idaes.solve.petsc-dae: Number of inequalities: 0
2025-10-27 10:40:12 [INFO] idaes.solve.petsc-dae: Number of variables: 4353
2025-10-27 10:40:12 [INFO] idaes.solve.petsc-dae: Number of integers: 0
2025-10-27 10:40:12 [INFO] idaes.solve.petsc-dae: Number of binary: 0
2025-10-27 10:40:12 [INFO] idaes.solve.petsc-dae: Number of objectives: 0 (Ignoring)
2025-10-27 10:40:12 [INFO] idaes.solve.petsc-dae: Number of non-zeros in Jacobian: 17083
2025-10-27 10:40:12 [INFO] idaes.solve.petsc-dae: Explicit time variable: 0
2025-10-27 10:40:12 [INFO] idaes.solve.petsc-dae: Number of derivatives: 95
2025-10-27 10:40:12 [INFO] idaes.solve.petsc-dae: Number of differential vars: 95
2025-10-27 10:40:12 [INFO] idaes.solve.petsc-dae: Number of algebraic vars: 4163
2025-10-27 10:40:12 [INFO] idaes.solve.petsc-dae: Number of state vars: 4258
2025-10-27 10:40:12 [INFO] idaes.solve.petsc-dae: Number of degrees of freedom: 0
2025-10-27 10:40:12 [INFO] idaes.solve.petsc-dae: ---------------------------------------------------
2025-10-27 10:40:12 [INFO] idaes.solve.petsc-dae: 0 TS dt 0.1 time 3900.
2025-10-27 10:40:13 [INFO] idaes.solve.petsc-dae: 1 TS dt 0.1 time 3900.1
2025-10-27 10:40:13 [INFO] idaes.solve.petsc-dae: 2 TS dt 1. time 3900.2
2025-10-27 10:40:13 [INFO] idaes.solve.petsc-dae: 3 TS dt 2.59622 time 3901.2
2025-10-27 10:40:13 [INFO] idaes.solve.petsc-dae: 4 TS dt 2.64107 time 3903.8
2025-10-27 10:40:13 [INFO] idaes.solve.petsc-dae: 5 TS dt 3.71649 time 3906.44
2025-10-27 10:40:13 [INFO] idaes.solve.petsc-dae: 6 TS dt 4.0841 time 3910.15
2025-10-27 10:40:13 [INFO] idaes.solve.petsc-dae: 7 TS dt 4.67688 time 3914.24
2025-10-27 10:40:13 [INFO] idaes.solve.petsc-dae: 8 TS dt 5.07459 time 3918.91
2025-10-27 10:40:13 [INFO] idaes.solve.petsc-dae: 9 TS dt 5.77782 time 3923.99
2025-10-27 10:40:13 [INFO] idaes.solve.petsc-dae: 10 TS dt 6.22547 time 3929.77
2025-10-27 10:40:13 [INFO] idaes.solve.petsc-dae: 11 TS dt 6.74718 time 3935.99
2025-10-27 10:40:13 [INFO] idaes.solve.petsc-dae: 12 TS dt 7.14071 time 3942.74
2025-10-27 10:40:13 [INFO] idaes.solve.petsc-dae: 13 TS dt 7.96982 time 3949.88
2025-10-27 10:40:14 [INFO] idaes.solve.petsc-dae: 14 TS dt 8.85113 time 3957.85
2025-10-27 10:40:14 [INFO] idaes.solve.petsc-dae: 15 TS dt 10.0467 time 3966.7
2025-10-27 10:40:14 [INFO] idaes.solve.petsc-dae: 16 TS dt 11.4483 time 3976.75
2025-10-27 10:40:14 [INFO] idaes.solve.petsc-dae: 17 TS dt 12.9312 time 3988.2
2025-10-27 10:40:14 [INFO] idaes.solve.petsc-dae: 18 TS dt 14.8713 time 4001.13
2025-10-27 10:40:14 [INFO] idaes.solve.petsc-dae: 19 TS dt 17.8919 time 4016.
2025-10-27 10:40:14 [INFO] idaes.solve.petsc-dae: 20 TS dt 20.7564 time 4033.89
2025-10-27 10:40:14 [INFO] idaes.solve.petsc-dae: 21 TS dt 23.9227 time 4054.65
2025-10-27 10:40:14 [INFO] idaes.solve.petsc-dae: 22 TS dt 26.4687 time 4078.57
2025-10-27 10:40:14 [INFO] idaes.solve.petsc-dae: 23 TS dt 27.8946 time 4105.04
2025-10-27 10:40:14 [INFO] idaes.solve.petsc-dae: 24 TS dt 29.6263 time 4132.93
2025-10-27 10:40:14 [INFO] idaes.solve.petsc-dae: 25 TS dt 30.949 time 4162.56
2025-10-27 10:40:14 [INFO] idaes.solve.petsc-dae: 26 TS dt 35.9283 time 4193.51
2025-10-27 10:40:14 [INFO] idaes.solve.petsc-dae: 27 TS dt 39.1479 time 4229.44
2025-10-27 10:40:14 [INFO] idaes.solve.petsc-dae: 28 TS dt 43.4963 time 4268.58
2025-10-27 10:40:14 [INFO] idaes.solve.petsc-dae: 29 TS dt 46.757 time 4312.08
2025-10-27 10:40:14 [INFO] idaes.solve.petsc-dae: 30 TS dt 48.1099 time 4358.84
2025-10-27 10:40:15 [INFO] idaes.solve.petsc-dae: 31 TS dt 45.0065 time 4401.73
2025-10-27 10:40:15 [INFO] idaes.solve.petsc-dae: 32 TS dt 49.7051 time 4446.73
2025-10-27 10:40:15 [INFO] idaes.solve.petsc-dae: 33 TS dt 48.8039 time 4496.44
2025-10-27 10:40:15 [INFO] idaes.solve.petsc-dae: 34 TS dt 46.5776 time 4545.24
2025-10-27 10:40:15 [INFO] idaes.solve.petsc-dae: 35 TS dt 53.211 time 4591.82
2025-10-27 10:40:15 [INFO] idaes.solve.petsc-dae: 36 TS dt 52.2518 time 4645.03
2025-10-27 10:40:15 [INFO] idaes.solve.petsc-dae: 37 TS dt 52.034 time 4697.28
2025-10-27 10:40:15 [INFO] idaes.solve.petsc-dae: 38 TS dt 50.3068 time 4749.32
2025-10-27 10:40:15 [INFO] idaes.solve.petsc-dae: 39 TS dt 57.009 time 4799.62
2025-10-27 10:40:15 [INFO] idaes.solve.petsc-dae: 40 TS dt 60.3992 time 4856.63
2025-10-27 10:40:15 [INFO] idaes.solve.petsc-dae: 41 TS dt 63.5156 time 4917.03
2025-10-27 10:40:15 [INFO] idaes.solve.petsc-dae: 42 TS dt 59.9095 time 4980.55
2025-10-27 10:40:15 [INFO] idaes.solve.petsc-dae: 43 TS dt 72.8498 time 5040.46
2025-10-27 10:40:16 [INFO] idaes.solve.petsc-dae: 44 TS dt 78.2579 time 5113.31
2025-10-27 10:40:16 [INFO] idaes.solve.petsc-dae: 45 TS dt 89.6447 time 5191.56
2025-10-27 10:40:16 [INFO] idaes.solve.petsc-dae: 46 TS dt 98.0675 time 5281.21
2025-10-27 10:40:16 [INFO] idaes.solve.petsc-dae: 47 TS dt 110.095 time 5379.28
2025-10-27 10:40:16 [INFO] idaes.solve.petsc-dae: 48 TS dt 122.423 time 5489.37
2025-10-27 10:40:16 [INFO] idaes.solve.petsc-dae: 49 TS dt 138.445 time 5611.79
2025-10-27 10:40:16 [INFO] idaes.solve.petsc-dae: 50 TS dt 157.438 time 5750.24
2025-10-27 10:40:16 [INFO] idaes.solve.petsc-dae: 51 TS dt 181.473 time 5907.68
2025-10-27 10:40:16 [INFO] idaes.solve.petsc-dae: 52 TS dt 209.513 time 6089.15
2025-10-27 10:40:16 [INFO] idaes.solve.petsc-dae: 53 TS dt 234.089 time 6298.66
2025-10-27 10:40:16 [INFO] idaes.solve.petsc-dae: 54 TS dt 78.4508 time 6339.47
2025-10-27 10:40:16 [INFO] idaes.solve.petsc-dae: 55 TS dt 37.279 time 6365.47
2025-10-27 10:40:16 [INFO] idaes.solve.petsc-dae: 56 TS dt 93.1291 time 6402.75
2025-10-27 10:40:17 [INFO] idaes.solve.petsc-dae: 57 TS dt 107.212 time 6495.88
2025-10-27 10:40:17 [INFO] idaes.solve.petsc-dae: 58 TS dt 145.336 time 6603.09
2025-10-27 10:40:17 [INFO] idaes.solve.petsc-dae: 59 TS dt 136.71 time 6726.21
2025-10-27 10:40:17 [INFO] idaes.solve.petsc-dae: 60 TS dt 145.821 time 6862.92
2025-10-27 10:40:17 [INFO] idaes.solve.petsc-dae: 61 TS dt 206.494 time 7008.74
2025-10-27 10:40:17 [INFO] idaes.solve.petsc-dae: 62 TS dt 236.93 time 7215.24
2025-10-27 10:40:17 [INFO] idaes.solve.petsc-dae: 63 TS dt 262.649 time 7452.17
2025-10-27 10:40:17 [INFO] idaes.solve.petsc-dae: 64 TS dt 284.815 time 7714.82
2025-10-27 10:40:17 [INFO] idaes.solve.petsc-dae: 65 TS dt 323.331 time 7999.63
2025-10-27 10:40:17 [INFO] idaes.solve.petsc-dae: 66 TS dt 353.816 time 8322.96
2025-10-27 10:40:17 [INFO] idaes.solve.petsc-dae: 67 TS dt 391.33 time 8676.78
2025-10-27 10:40:17 [INFO] idaes.solve.petsc-dae: 68 TS dt 430.576 time 9068.11
2025-10-27 10:40:17 [INFO] idaes.solve.petsc-dae: 69 TS dt 476.835 time 9498.68
2025-10-27 10:40:17 [INFO] idaes.solve.petsc-dae: 70 TS dt 528.315 time 9975.52
2025-10-27 10:40:17 [INFO] idaes.solve.petsc-dae: 71 TS dt 298.083 time 10503.8
2025-10-27 10:40:17 [INFO] idaes.solve.petsc-dae: 72 TS dt 298.083 time 10801.9
2025-10-27 10:40:17 [INFO] idaes.solve.petsc-dae: 73 TS dt 677.007 time 11100.
2025-10-27 10:40:17 [INFO] idaes.solve.petsc-dae: TSConvergedReason = TS_CONVERGED_TIME
2025-10-27 10:40:17 [INFO] idaes.solve.petsc-dae: TS_CONVERGED_TIME
WARNING: model contains export suffix 'scaling_factor' that contains 376
component keys that are not exported as part of the NL file. Skipping.
2025-10-27 10:40:21 [INFO] idaes.solve.petsc-dae: Solver log file: 'C:\Users\dallan\AppData\Local\Temp\tmpyq_do7p7_petsc_ts.log'
2025-10-27 10:40:21 [INFO] idaes.solve.petsc-dae: Solver solution file: 'C:\Users\dallan\AppData\Local\Temp\tmpabzf1_40.pyomo.sol'
2025-10-27 10:40:21 [INFO] idaes.solve.petsc-dae: Solver problem files: ('C:\\Users\\dallan\\AppData\\Local\\Temp\\tmpabzf1_40.pyomo.nl',)
2025-10-27 10:40:21 [INFO] idaes.solve.petsc-dae: Called fg_read, err: 0 (0 is good)
2025-10-27 10:40:21 [INFO] idaes.solve.petsc-dae: ---------------------------------------------------
2025-10-27 10:40:21 [INFO] idaes.solve.petsc-dae: DAE: 1
2025-10-27 10:40:21 [INFO] idaes.solve.petsc-dae: Reading nl file: C:\Users\dallan\AppData\Local\Temp\tmpabzf1_40.pyomo.nl
2025-10-27 10:40:21 [INFO] idaes.solve.petsc-dae: Number of constraints: 4258
2025-10-27 10:40:21 [INFO] idaes.solve.petsc-dae: Number of nonlinear constraints: 1981
2025-10-27 10:40:21 [INFO] idaes.solve.petsc-dae: Number of linear constraints: 2277
2025-10-27 10:40:21 [INFO] idaes.solve.petsc-dae: Number of inequalities: 0
2025-10-27 10:40:21 [INFO] idaes.solve.petsc-dae: Number of variables: 4353
2025-10-27 10:40:21 [INFO] idaes.solve.petsc-dae: Number of integers: 0
2025-10-27 10:40:21 [INFO] idaes.solve.petsc-dae: Number of binary: 0
2025-10-27 10:40:21 [INFO] idaes.solve.petsc-dae: Number of objectives: 0 (Ignoring)
2025-10-27 10:40:21 [INFO] idaes.solve.petsc-dae: Number of non-zeros in Jacobian: 17083
2025-10-27 10:40:21 [INFO] idaes.solve.petsc-dae: Explicit time variable: 0
2025-10-27 10:40:21 [INFO] idaes.solve.petsc-dae: Number of derivatives: 95
2025-10-27 10:40:21 [INFO] idaes.solve.petsc-dae: Number of differential vars: 95
2025-10-27 10:40:21 [INFO] idaes.solve.petsc-dae: Number of algebraic vars: 4163
2025-10-27 10:40:21 [INFO] idaes.solve.petsc-dae: Number of state vars: 4258
2025-10-27 10:40:21 [INFO] idaes.solve.petsc-dae: Number of degrees of freedom: 0
2025-10-27 10:40:21 [INFO] idaes.solve.petsc-dae: ---------------------------------------------------
2025-10-27 10:40:21 [INFO] idaes.solve.petsc-dae: 0 TS dt 0.1 time 11100.
2025-10-27 10:40:22 [INFO] idaes.solve.petsc-dae: 1 TS dt 0.1 time 11100.1
2025-10-27 10:40:22 [INFO] idaes.solve.petsc-dae: 2 TS dt 0.00401986 time 11100.1
2025-10-27 10:40:22 [INFO] idaes.solve.petsc-dae: 3 TS dt 0.0401986 time 11100.1
2025-10-27 10:40:22 [INFO] idaes.solve.petsc-dae: 4 TS dt 0.401986 time 11100.1
2025-10-27 10:40:22 [INFO] idaes.solve.petsc-dae: 5 TS dt 0.85705 time 11100.5
2025-10-27 10:40:22 [INFO] idaes.solve.petsc-dae: 6 TS dt 0.982707 time 11101.4
2025-10-27 10:40:22 [INFO] idaes.solve.petsc-dae: 7 TS dt 0.970915 time 11102.4
2025-10-27 10:40:22 [INFO] idaes.solve.petsc-dae: 8 TS dt 1.09915 time 11103.4
2025-10-27 10:40:23 [INFO] idaes.solve.petsc-dae: 9 TS dt 0.933007 time 11104.3
2025-10-27 10:40:23 [INFO] idaes.solve.petsc-dae: 10 TS dt 0.922211 time 11105.
2025-10-27 10:40:23 [INFO] idaes.solve.petsc-dae: 11 TS dt 0.280419 time 11105.2
2025-10-27 10:40:23 [INFO] idaes.solve.petsc-dae: 12 TS dt 0.859313 time 11105.4
2025-10-27 10:40:23 [INFO] idaes.solve.petsc-dae: 13 TS dt 0.708354 time 11106.2
2025-10-27 10:40:23 [INFO] idaes.solve.petsc-dae: 14 TS dt 1.00186 time 11106.9
2025-10-27 10:40:23 [INFO] idaes.solve.petsc-dae: 15 TS dt 0.95887 time 11107.9
2025-10-27 10:40:23 [INFO] idaes.solve.petsc-dae: 16 TS dt 1.14532 time 11108.8
2025-10-27 10:40:24 [INFO] idaes.solve.petsc-dae: 17 TS dt 1.27028 time 11110.
2025-10-27 10:40:24 [INFO] idaes.solve.petsc-dae: 18 TS dt 1.46316 time 11111.3
2025-10-27 10:40:24 [INFO] idaes.solve.petsc-dae: 19 TS dt 1.5561 time 11112.7
2025-10-27 10:40:24 [INFO] idaes.solve.petsc-dae: 20 TS dt 1.49179 time 11114.3
2025-10-27 10:40:24 [INFO] idaes.solve.petsc-dae: 21 TS dt 1.34724 time 11115.4
2025-10-27 10:40:24 [INFO] idaes.solve.petsc-dae: 22 TS dt 1.3327 time 11116.8
2025-10-27 10:40:24 [INFO] idaes.solve.petsc-dae: 23 TS dt 1.54707 time 11118.1
2025-10-27 10:40:24 [INFO] idaes.solve.petsc-dae: 24 TS dt 1.43277 time 11119.6
2025-10-27 10:40:24 [INFO] idaes.solve.petsc-dae: 25 TS dt 1.80797 time 11121.1
2025-10-27 10:40:25 [INFO] idaes.solve.petsc-dae: 26 TS dt 1.75478 time 11122.9
2025-10-27 10:40:25 [INFO] idaes.solve.petsc-dae: 27 TS dt 1.74308 time 11124.6
2025-10-27 10:40:25 [INFO] idaes.solve.petsc-dae: 28 TS dt 1.85951 time 11126.4
2025-10-27 10:40:25 [INFO] idaes.solve.petsc-dae: 29 TS dt 1.80246 time 11128.2
2025-10-27 10:40:25 [INFO] idaes.solve.petsc-dae: 30 TS dt 1.90679 time 11130.
2025-10-27 10:40:25 [INFO] idaes.solve.petsc-dae: 31 TS dt 1.7926 time 11132.
2025-10-27 10:40:25 [INFO] idaes.solve.petsc-dae: 32 TS dt 1.76472 time 11133.7
2025-10-27 10:40:25 [INFO] idaes.solve.petsc-dae: 33 TS dt 1.7285 time 11135.5
2025-10-27 10:40:25 [INFO] idaes.solve.petsc-dae: 34 TS dt 1.59402 time 11137.2
2025-10-27 10:40:26 [INFO] idaes.solve.petsc-dae: 35 TS dt 1.47188 time 11138.6
2025-10-27 10:40:26 [INFO] idaes.solve.petsc-dae: 36 TS dt 1.91015 time 11139.
2025-10-27 10:40:26 [INFO] idaes.solve.petsc-dae: 37 TS dt 0.933002 time 11139.6
2025-10-27 10:40:26 [INFO] idaes.solve.petsc-dae: 38 TS dt 0.848753 time 11140.6
2025-10-27 10:40:26 [INFO] idaes.solve.petsc-dae: 39 TS dt 0.790858 time 11141.3
2025-10-27 10:40:26 [INFO] idaes.solve.petsc-dae: 40 TS dt 0.591596 time 11141.8
2025-10-27 10:40:27 [INFO] idaes.solve.petsc-dae: 41 TS dt 0.669715 time 11142.2
2025-10-27 10:40:27 [INFO] idaes.solve.petsc-dae: 42 TS dt 0.454412 time 11142.6
2025-10-27 10:40:27 [INFO] idaes.solve.petsc-dae: 43 TS dt 0.432591 time 11143.
2025-10-27 10:40:27 [INFO] idaes.solve.petsc-dae: 44 TS dt 0.516455 time 11143.5
2025-10-27 10:40:27 [INFO] idaes.solve.petsc-dae: 45 TS dt 0.688358 time 11144.
2025-10-27 10:40:27 [INFO] idaes.solve.petsc-dae: 46 TS dt 0.927665 time 11144.2
2025-10-27 10:40:27 [INFO] idaes.solve.petsc-dae: 47 TS dt 0.255097 time 11144.5
2025-10-27 10:40:27 [INFO] idaes.solve.petsc-dae: 48 TS dt 0.558846 time 11144.7
2025-10-27 10:40:27 [INFO] idaes.solve.petsc-dae: 49 TS dt 0.714038 time 11145.3
2025-10-27 10:40:28 [INFO] idaes.solve.petsc-dae: 50 TS dt 0.778766 time 11146.
2025-10-27 10:40:28 [INFO] idaes.solve.petsc-dae: 51 TS dt 0.953738 time 11146.5
2025-10-27 10:40:28 [INFO] idaes.solve.petsc-dae: 52 TS dt 0.821838 time 11147.2
2025-10-27 10:40:28 [INFO] idaes.solve.petsc-dae: 53 TS dt 0.916896 time 11148.
2025-10-27 10:40:28 [INFO] idaes.solve.petsc-dae: 54 TS dt 1.40668 time 11148.9
2025-10-27 10:40:28 [INFO] idaes.solve.petsc-dae: 55 TS dt 1.54644 time 11150.3
2025-10-27 10:40:28 [INFO] idaes.solve.petsc-dae: 56 TS dt 1.7421 time 11151.9
2025-10-27 10:40:28 [INFO] idaes.solve.petsc-dae: 57 TS dt 1.68254 time 11153.6
2025-10-27 10:40:28 [INFO] idaes.solve.petsc-dae: 58 TS dt 1.52427 time 11155.3
2025-10-27 10:40:29 [INFO] idaes.solve.petsc-dae: 59 TS dt 2.25389 time 11155.7
2025-10-27 10:40:29 [INFO] idaes.solve.petsc-dae: 60 TS dt 1.55333 time 11155.8
2025-10-27 10:40:29 [INFO] idaes.solve.petsc-dae: 61 TS dt 1.0298 time 11156.
2025-10-27 10:40:29 [INFO] idaes.solve.petsc-dae: 62 TS dt 1.03301 time 11156.2
2025-10-27 10:40:29 [INFO] idaes.solve.petsc-dae: 63 TS dt 0.629966 time 11156.5
2025-10-27 10:40:30 [INFO] idaes.solve.petsc-dae: 64 TS dt 0.742563 time 11157.1
2025-10-27 10:40:30 [INFO] idaes.solve.petsc-dae: 65 TS dt 1.36242 time 11157.9
2025-10-27 10:40:30 [INFO] idaes.solve.petsc-dae: 66 TS dt 1.71404 time 11159.2
2025-10-27 10:40:30 [INFO] idaes.solve.petsc-dae: 67 TS dt 2.21613 time 11161.
2025-10-27 10:40:30 [INFO] idaes.solve.petsc-dae: 68 TS dt 2.48039 time 11163.2
2025-10-27 10:40:30 [INFO] idaes.solve.petsc-dae: 69 TS dt 2.76158 time 11165.6
2025-10-27 10:40:30 [INFO] idaes.solve.petsc-dae: 70 TS dt 3.11811 time 11168.4
2025-10-27 10:40:30 [INFO] idaes.solve.petsc-dae: 71 TS dt 3.35994 time 11171.5
2025-10-27 10:40:30 [INFO] idaes.solve.petsc-dae: 72 TS dt 3.55341 time 11174.9
2025-10-27 10:40:30 [INFO] idaes.solve.petsc-dae: 73 TS dt 3.56764 time 11178.4
2025-10-27 10:40:30 [INFO] idaes.solve.petsc-dae: 74 TS dt 3.3326 time 11182.
2025-10-27 10:40:31 [INFO] idaes.solve.petsc-dae: 75 TS dt 3.87403 time 11185.3
2025-10-27 10:40:31 [INFO] idaes.solve.petsc-dae: 76 TS dt 3.91403 time 11189.2
2025-10-27 10:40:31 [INFO] idaes.solve.petsc-dae: 77 TS dt 4.55559 time 11193.1
2025-10-27 10:40:31 [INFO] idaes.solve.petsc-dae: 78 TS dt 4.75871 time 11197.7
2025-10-27 10:40:31 [INFO] idaes.solve.petsc-dae: 79 TS dt 5.14255 time 11202.4
2025-10-27 10:40:31 [INFO] idaes.solve.petsc-dae: 80 TS dt 5.28567 time 11207.6
2025-10-27 10:40:31 [INFO] idaes.solve.petsc-dae: 81 TS dt 5.41457 time 11212.9
2025-10-27 10:40:31 [INFO] idaes.solve.petsc-dae: 82 TS dt 5.55755 time 11218.3
2025-10-27 10:40:31 [INFO] idaes.solve.petsc-dae: 83 TS dt 5.67731 time 11223.8
2025-10-27 10:40:31 [INFO] idaes.solve.petsc-dae: 84 TS dt 5.63723 time 11229.5
2025-10-27 10:40:31 [INFO] idaes.solve.petsc-dae: 85 TS dt 5.57779 time 11235.2
2025-10-27 10:40:31 [INFO] idaes.solve.petsc-dae: 86 TS dt 5.62503 time 11240.7
2025-10-27 10:40:32 [INFO] idaes.solve.petsc-dae: 87 TS dt 5.81727 time 11246.4
2025-10-27 10:40:32 [INFO] idaes.solve.petsc-dae: 88 TS dt 5.8176 time 11252.2
2025-10-27 10:40:32 [INFO] idaes.solve.petsc-dae: 89 TS dt 5.38543 time 11258.
2025-10-27 10:40:32 [INFO] idaes.solve.petsc-dae: 90 TS dt 5.4221 time 11263.4
2025-10-27 10:40:32 [INFO] idaes.solve.petsc-dae: 91 TS dt 5.02963 time 11268.
2025-10-27 10:40:32 [INFO] idaes.solve.petsc-dae: 92 TS dt 6.34422 time 11269.4
2025-10-27 10:40:33 [INFO] idaes.solve.petsc-dae: 93 TS dt 3.90981 time 11270.5
2025-10-27 10:40:33 [INFO] idaes.solve.petsc-dae: 94 TS dt 4.34918 time 11271.
2025-10-27 10:40:33 [INFO] idaes.solve.petsc-dae: 95 TS dt 2.41634 time 11273.3
2025-10-27 10:40:33 [INFO] idaes.solve.petsc-dae: 96 TS dt 3.54243 time 11275.7
2025-10-27 10:40:33 [INFO] idaes.solve.petsc-dae: 97 TS dt 4.8789 time 11279.2
2025-10-27 10:40:33 [INFO] idaes.solve.petsc-dae: 98 TS dt 4.87475 time 11284.1
2025-10-27 10:40:33 [INFO] idaes.solve.petsc-dae: 99 TS dt 4.99915 time 11288.4
2025-10-27 10:40:34 [INFO] idaes.solve.petsc-dae: 100 TS dt 7.28325 time 11289.2
2025-10-27 10:40:34 [INFO] idaes.solve.petsc-dae: 101 TS dt 2.17618 time 11291.4
2025-10-27 10:40:34 [INFO] idaes.solve.petsc-dae: 102 TS dt 3.24782 time 11293.6
2025-10-27 10:40:34 [INFO] idaes.solve.petsc-dae: 103 TS dt 3.41553 time 11296.9
2025-10-27 10:40:34 [INFO] idaes.solve.petsc-dae: 104 TS dt 3.41342 time 11300.3
2025-10-27 10:40:34 [INFO] idaes.solve.petsc-dae: 105 TS dt 3.81469 time 11303.7
2025-10-27 10:40:34 [INFO] idaes.solve.petsc-dae: 106 TS dt 4.57985 time 11307.5
2025-10-27 10:40:34 [INFO] idaes.solve.petsc-dae: 107 TS dt 7.16372 time 11312.1
2025-10-27 10:40:35 [INFO] idaes.solve.petsc-dae: 108 TS dt 7.028 time 11319.3
2025-10-27 10:40:35 [INFO] idaes.solve.petsc-dae: 109 TS dt 7.17926 time 11326.3
2025-10-27 10:40:35 [INFO] idaes.solve.petsc-dae: 110 TS dt 6.55286 time 11333.5
2025-10-27 10:40:35 [INFO] idaes.solve.petsc-dae: 111 TS dt 5.77721 time 11338.9
2025-10-27 10:40:35 [INFO] idaes.solve.petsc-dae: 112 TS dt 5.21685 time 11344.7
2025-10-27 10:40:35 [INFO] idaes.solve.petsc-dae: 113 TS dt 5.52183 time 11349.9
2025-10-27 10:40:35 [INFO] idaes.solve.petsc-dae: 114 TS dt 5.52016 time 11355.4
2025-10-27 10:40:35 [INFO] idaes.solve.petsc-dae: 115 TS dt 5.30574 time 11361.
2025-10-27 10:40:36 [INFO] idaes.solve.petsc-dae: 116 TS dt 4.99355 time 11366.3
2025-10-27 10:40:36 [INFO] idaes.solve.petsc-dae: 117 TS dt 5.05425 time 11371.3
2025-10-27 10:40:36 [INFO] idaes.solve.petsc-dae: 118 TS dt 4.75443 time 11376.3
2025-10-27 10:40:36 [INFO] idaes.solve.petsc-dae: 119 TS dt 4.31281 time 11381.1
2025-10-27 10:40:36 [INFO] idaes.solve.petsc-dae: 120 TS dt 3.89632 time 11385.4
2025-10-27 10:40:36 [INFO] idaes.solve.petsc-dae: 121 TS dt 3.46295 time 11388.8
2025-10-27 10:40:36 [INFO] idaes.solve.petsc-dae: 122 TS dt 3.05323 time 11391.8
2025-10-27 10:40:36 [INFO] idaes.solve.petsc-dae: 123 TS dt 2.6921 time 11394.5
2025-10-27 10:40:37 [INFO] idaes.solve.petsc-dae: 124 TS dt 1.61265 time 11396.8
2025-10-27 10:40:37 [INFO] idaes.solve.petsc-dae: 125 TS dt 1.61265 time 11398.4
2025-10-27 10:40:37 [INFO] idaes.solve.petsc-dae: 126 TS dt 1.83824 time 11400.
2025-10-27 10:40:37 [INFO] idaes.solve.petsc-dae: TSConvergedReason = TS_CONVERGED_TIME
2025-10-27 10:40:37 [INFO] idaes.solve.petsc-dae: TS_CONVERGED_TIME
WARNING: model contains export suffix 'scaling_factor' that contains 376
component keys that are not exported as part of the NL file. Skipping.
2025-10-27 10:40:41 [INFO] idaes.solve.petsc-dae: Solver log file: 'C:\Users\dallan\AppData\Local\Temp\tmpc6cr8hoa_petsc_ts.log'
2025-10-27 10:40:41 [INFO] idaes.solve.petsc-dae: Solver solution file: 'C:\Users\dallan\AppData\Local\Temp\tmp2kxkmwxm.pyomo.sol'
2025-10-27 10:40:41 [INFO] idaes.solve.petsc-dae: Solver problem files: ('C:\\Users\\dallan\\AppData\\Local\\Temp\\tmp2kxkmwxm.pyomo.nl',)
2025-10-27 10:40:41 [INFO] idaes.solve.petsc-dae: Called fg_read, err: 0 (0 is good)
2025-10-27 10:40:41 [INFO] idaes.solve.petsc-dae: ---------------------------------------------------
2025-10-27 10:40:41 [INFO] idaes.solve.petsc-dae: DAE: 1
2025-10-27 10:40:41 [INFO] idaes.solve.petsc-dae: Reading nl file: C:\Users\dallan\AppData\Local\Temp\tmp2kxkmwxm.pyomo.nl
2025-10-27 10:40:41 [INFO] idaes.solve.petsc-dae: Number of constraints: 4258
2025-10-27 10:40:41 [INFO] idaes.solve.petsc-dae: Number of nonlinear constraints: 1981
2025-10-27 10:40:41 [INFO] idaes.solve.petsc-dae: Number of linear constraints: 2277
2025-10-27 10:40:41 [INFO] idaes.solve.petsc-dae: Number of inequalities: 0
2025-10-27 10:40:41 [INFO] idaes.solve.petsc-dae: Number of variables: 4353
2025-10-27 10:40:41 [INFO] idaes.solve.petsc-dae: Number of integers: 0
2025-10-27 10:40:41 [INFO] idaes.solve.petsc-dae: Number of binary: 0
2025-10-27 10:40:41 [INFO] idaes.solve.petsc-dae: Number of objectives: 0 (Ignoring)
2025-10-27 10:40:41 [INFO] idaes.solve.petsc-dae: Number of non-zeros in Jacobian: 17083
2025-10-27 10:40:41 [INFO] idaes.solve.petsc-dae: Explicit time variable: 0
2025-10-27 10:40:41 [INFO] idaes.solve.petsc-dae: Number of derivatives: 95
2025-10-27 10:40:41 [INFO] idaes.solve.petsc-dae: Number of differential vars: 95
2025-10-27 10:40:41 [INFO] idaes.solve.petsc-dae: Number of algebraic vars: 4163
2025-10-27 10:40:41 [INFO] idaes.solve.petsc-dae: Number of state vars: 4258
2025-10-27 10:40:41 [INFO] idaes.solve.petsc-dae: Number of degrees of freedom: 0
2025-10-27 10:40:41 [INFO] idaes.solve.petsc-dae: ---------------------------------------------------
2025-10-27 10:40:41 [INFO] idaes.solve.petsc-dae: 0 TS dt 0.1 time 11400.
2025-10-27 10:40:41 [INFO] idaes.solve.petsc-dae: 1 TS dt 0.1 time 11400.1
2025-10-27 10:40:41 [INFO] idaes.solve.petsc-dae: 2 TS dt 1. time 11400.2
2025-10-27 10:40:41 [INFO] idaes.solve.petsc-dae: 3 TS dt 1.75692 time 11401.2
2025-10-27 10:40:41 [INFO] idaes.solve.petsc-dae: 4 TS dt 2.22857 time 11403.
2025-10-27 10:40:41 [INFO] idaes.solve.petsc-dae: 5 TS dt 2.54586 time 11405.2
2025-10-27 10:40:42 [INFO] idaes.solve.petsc-dae: 6 TS dt 2.77711 time 11407.7
2025-10-27 10:40:42 [INFO] idaes.solve.petsc-dae: 7 TS dt 2.98467 time 11410.5
2025-10-27 10:40:42 [INFO] idaes.solve.petsc-dae: 8 TS dt 3.18022 time 11413.5
2025-10-27 10:40:42 [INFO] idaes.solve.petsc-dae: 9 TS dt 3.45234 time 11416.7
2025-10-27 10:40:42 [INFO] idaes.solve.petsc-dae: 10 TS dt 3.7309 time 11420.1
2025-10-27 10:40:42 [INFO] idaes.solve.petsc-dae: 11 TS dt 4.15349 time 11423.9
2025-10-27 10:40:42 [INFO] idaes.solve.petsc-dae: 12 TS dt 4.58333 time 11428.
2025-10-27 10:40:42 [INFO] idaes.solve.petsc-dae: 13 TS dt 5.07512 time 11432.6
2025-10-27 10:40:42 [INFO] idaes.solve.petsc-dae: 14 TS dt 5.58338 time 11437.7
2025-10-27 10:40:42 [INFO] idaes.solve.petsc-dae: 15 TS dt 6.39501 time 11443.3
2025-10-27 10:40:42 [INFO] idaes.solve.petsc-dae: 16 TS dt 7.40589 time 11449.6
2025-10-27 10:40:42 [INFO] idaes.solve.petsc-dae: 17 TS dt 8.75925 time 11457.1
2025-10-27 10:40:42 [INFO] idaes.solve.petsc-dae: 18 TS dt 10.5575 time 11465.8
2025-10-27 10:40:42 [INFO] idaes.solve.petsc-dae: 19 TS dt 13.0647 time 11476.4
2025-10-27 10:40:42 [INFO] idaes.solve.petsc-dae: 20 TS dt 16.5577 time 11489.4
2025-10-27 10:40:42 [INFO] idaes.solve.petsc-dae: 21 TS dt 21.0088 time 11506.
2025-10-27 10:40:42 [INFO] idaes.solve.petsc-dae: 22 TS dt 24.9675 time 11527.
2025-10-27 10:40:42 [INFO] idaes.solve.petsc-dae: 23 TS dt 27.3419 time 11552.
2025-10-27 10:40:43 [INFO] idaes.solve.petsc-dae: 24 TS dt 28.9024 time 11579.3
2025-10-27 10:40:43 [INFO] idaes.solve.petsc-dae: 25 TS dt 32.0455 time 11608.2
2025-10-27 10:40:43 [INFO] idaes.solve.petsc-dae: 26 TS dt 34.8504 time 11640.3
2025-10-27 10:40:43 [INFO] idaes.solve.petsc-dae: 27 TS dt 38.1684 time 11675.1
2025-10-27 10:40:43 [INFO] idaes.solve.petsc-dae: 28 TS dt 41.3077 time 11713.3
2025-10-27 10:40:43 [INFO] idaes.solve.petsc-dae: 29 TS dt 46.0383 time 11754.6
2025-10-27 10:40:43 [INFO] idaes.solve.petsc-dae: 30 TS dt 50.7414 time 11800.6
2025-10-27 10:40:43 [INFO] idaes.solve.petsc-dae: 31 TS dt 56.0326 time 11851.4
2025-10-27 10:40:43 [INFO] idaes.solve.petsc-dae: 32 TS dt 60.757 time 11907.4
2025-10-27 10:40:43 [INFO] idaes.solve.petsc-dae: 33 TS dt 65.4299 time 11968.2
2025-10-27 10:40:43 [INFO] idaes.solve.petsc-dae: 34 TS dt 70.2792 time 12033.6
2025-10-27 10:40:43 [INFO] idaes.solve.petsc-dae: 35 TS dt 76.165 time 12103.9
2025-10-27 10:40:43 [INFO] idaes.solve.petsc-dae: 36 TS dt 82.9977 time 12180.
2025-10-27 10:40:44 [INFO] idaes.solve.petsc-dae: 37 TS dt 90.9439 time 12263.
2025-10-27 10:40:44 [INFO] idaes.solve.petsc-dae: 38 TS dt 100.418 time 12354.
2025-10-27 10:40:44 [INFO] idaes.solve.petsc-dae: 39 TS dt 111.024 time 12454.4
2025-10-27 10:40:44 [INFO] idaes.solve.petsc-dae: 40 TS dt 121.781 time 12565.4
2025-10-27 10:40:44 [INFO] idaes.solve.petsc-dae: 41 TS dt 131.746 time 12687.2
2025-10-27 10:40:44 [INFO] idaes.solve.petsc-dae: 42 TS dt 139.683 time 12818.9
2025-10-27 10:40:44 [INFO] idaes.solve.petsc-dae: 43 TS dt 144.027 time 12958.6
2025-10-27 10:40:44 [INFO] idaes.solve.petsc-dae: 44 TS dt 146.548 time 13102.6
2025-10-27 10:40:44 [INFO] idaes.solve.petsc-dae: 45 TS dt 144.579 time 13249.2
2025-10-27 10:40:44 [INFO] idaes.solve.petsc-dae: 46 TS dt 149.842 time 13393.8
2025-10-27 10:40:44 [INFO] idaes.solve.petsc-dae: 47 TS dt 154.839 time 13543.6
2025-10-27 10:40:44 [INFO] idaes.solve.petsc-dae: 48 TS dt 157.477 time 13698.5
2025-10-27 10:40:44 [INFO] idaes.solve.petsc-dae: 49 TS dt 163.75 time 13855.9
2025-10-27 10:40:44 [INFO] idaes.solve.petsc-dae: 50 TS dt 180.28 time 14019.7
2025-10-27 10:40:44 [INFO] idaes.solve.petsc-dae: 51 TS dt 194.619 time 14200.
2025-10-27 10:40:44 [INFO] idaes.solve.petsc-dae: 52 TS dt 213.113 time 14394.6
2025-10-27 10:40:45 [INFO] idaes.solve.petsc-dae: 53 TS dt 231.685 time 14607.7
2025-10-27 10:40:45 [INFO] idaes.solve.petsc-dae: 54 TS dt 253.829 time 14839.4
2025-10-27 10:40:45 [INFO] idaes.solve.petsc-dae: 55 TS dt 278.328 time 15093.2
2025-10-27 10:40:45 [INFO] idaes.solve.petsc-dae: 56 TS dt 307.256 time 15371.5
2025-10-27 10:40:45 [INFO] idaes.solve.petsc-dae: 57 TS dt 341.199 time 15678.8
2025-10-27 10:40:45 [INFO] idaes.solve.petsc-dae: 58 TS dt 383.534 time 16020.
2025-10-27 10:40:45 [INFO] idaes.solve.petsc-dae: 59 TS dt 434.226 time 16403.5
2025-10-27 10:40:45 [INFO] idaes.solve.petsc-dae: 60 TS dt 510.361 time 16837.8
2025-10-27 10:40:45 [INFO] idaes.solve.petsc-dae: 61 TS dt 605.445 time 17348.1
2025-10-27 10:40:45 [INFO] idaes.solve.petsc-dae: 62 TS dt 733.317 time 17953.6
2025-10-27 10:40:45 [INFO] idaes.solve.petsc-dae: 63 TS dt 899.413 time 18686.9
2025-10-27 10:40:45 [INFO] idaes.solve.petsc-dae: 64 TS dt 1110.73 time 19586.3
2025-10-27 10:40:45 [INFO] idaes.solve.petsc-dae: 65 TS dt 751.493 time 20697.
2025-10-27 10:40:45 [INFO] idaes.solve.petsc-dae: 66 TS dt 751.493 time 21448.5
2025-10-27 10:40:45 [INFO] idaes.solve.petsc-dae: 67 TS dt 1598.02 time 22200.
2025-10-27 10:40:45 [INFO] idaes.solve.petsc-dae: TSConvergedReason = TS_CONVERGED_TIME
2025-10-27 10:40:45 [INFO] idaes.solve.petsc-dae: TS_CONVERGED_TIME
Load certain variables into a dictionary for plotting convenience.
ramp_list = np.array(m.fs.time)[1:]
traj = results.trajectory
time_set = m.fs.time.ordered_data()
tf = time_set[-1]
soec = m.fs.soc_module.solid_oxide_cell
results_dict = {
"ramp_list": np.array(ramp_list),
"time": np.array(traj.time),
"potential": np.array(traj.vecs[str(soec.potential[tf])]),
"current": np.array(traj.vecs[str(m.fs.soc_module.total_current[tf])]),
"soec_fuel_inlet_flow": np.array(
traj.vecs[str(m.fs.soc_module.fuel_inlet.flow_mol[tf])]
),
"soec_oxygen_inlet_flow": np.array(
traj.vecs[str(m.fs.soc_module.oxygen_inlet.flow_mol[tf])]
),
"fuel_heater_duty": np.array(
traj.vecs[str(m.fs.feed_heater.electric_heat_duty[tf])]
),
"sweep_heater_duty": np.array(
traj.vecs[str(m.fs.sweep_heater.electric_heat_duty[tf])]
),
"fuel_inlet_H2": np.array(traj.vecs[str(soec.fuel_inlet.mole_frac_comp[tf, "H2"])]),
"fuel_inlet_H2O": np.array(
traj.vecs[str(soec.fuel_inlet.mole_frac_comp[tf, "H2O"])]
),
"fuel_outlet_H2O": np.array(
traj.vecs[
str(
soec.fuel_channel.mole_frac_comp[
tf,
soec.iznodes.last(),
"H2O",
]
)
]
),
"sweep_inlet_O2": np.array(
traj.vecs[str(soec.oxygen_inlet.mole_frac_comp[tf, "O2"])]
),
"sweep_outlet_O2": np.array(
traj.vecs[
str(soec.oxygen_channel.mole_frac_comp[tf, soec.iznodes.first(), "O2"])
]
),
"H2_production": np.array(traj.vecs[str(m.fs.h2_mass_production[tf])]),
"fuel_outlet_mole_frac_comp_H2": np.array(
traj.vecs[str(m.fs.soc_module.fuel_outlet_mole_frac_comp_H2[tf])]
),
"steam_feed_rate": np.array(traj.vecs[str(m.fs.makeup_mix.makeup.flow_mol[tf])]),
"sweep_feed_rate": np.array(traj.vecs[str(m.fs.sweep_blower.inlet.flow_mol[tf])]),
"total_electric_power": np.array(traj.vecs[str(m.fs.total_electric_power[tf])]),
"fuel_inlet_temperature": np.array(
traj.vecs[str(soec.fuel_channel.temperature_inlet[tf])]
),
"sweep_inlet_temperature": np.array(
traj.vecs[str(soec.oxygen_channel.temperature_inlet[tf])]
),
"stack_core_temperature": np.array(traj.vecs[str(m.fs.stack_core_temperature[tf])]),
"fuel_outlet_temperature": np.array(
traj.vecs[str(soec.fuel_channel.temperature_outlet[tf])]
),
"sweep_outlet_temperature": np.array(
traj.vecs[str(soec.oxygen_channel.temperature_outlet[tf])]
),
"product_mole_frac_H2": np.array(
traj.vecs[str(m.fs.condenser_split.inlet.mole_frac_comp[tf, "H2"])]
),
"condenser_outlet_temperature": np.array(
traj.vecs[
str(m.fs.condenser_flash.control_volume.properties_out[tf].temperature)
]
),
"condenser_heat_duty": np.array(traj.vecs[str(m.fs.condenser_flash.heat_duty[tf])]),
"temperature_z": np.array(
[traj.vecs[str(soec.temperature_z[tf, iz])] for iz in soec.iznodes]
),
"fuel_electrode_temperature_deviation_x": np.array(
[
traj.vecs[str(soec.fuel_electrode.temperature_deviation_x[tf, 1, iz])]
for iz in soec.iznodes
]
),
"interconnect_temperature_deviation_x": np.array(
[
traj.vecs[str(soec.interconnect.temperature_deviation_x[tf, 1, iz])]
for iz in soec.iznodes
]
),
"temperature_z_gradient": np.array(
[traj.vecs[str(soec.dtemperature_z_dz[tf, iz])] for iz in soec.iznodes]
),
"fuel_electrode_gradient": np.array(
[
traj.vecs[str(soec.fuel_electrode.dtemperature_dz[tf, 1, iz])]
for iz in soec.iznodes
]
),
"fuel_electrode_mixed_partial": np.array(
[
traj.vecs[str(soec.fuel_electrode.d2temperature_dzdt_dummy[tf, 1, iz])]
for iz in soec.iznodes
]
),
"interconnect_gradient": np.array(
[
traj.vecs[str(soec.interconnect.dtemperature_dz[tf, 1, iz])]
for iz in soec.iznodes
]
),
"current_density": np.array(
[traj.vecs[str(soec.current_density[tf, iz])] for iz in soec.iznodes]
),
"feed_heater_temperature": np.array(
[
traj.vecs[str(m.fs.feed_heater.temp_wall_center[tf, z])]
for z in m.fs.feed_heater.control_volume.length_domain
]
),
"sweep_heater_temperature": np.array(
[
traj.vecs[str(m.fs.sweep_heater.temp_wall_center[tf, z])]
for z in m.fs.sweep_heater.control_volume.length_domain
]
),
"feed_medium_exchanger_temperature": np.array(
[
traj.vecs[str(m.fs.feed_medium_exchanger.temp_wall_center[tf, z])]
for z in m.fs.feed_medium_exchanger.cold_side.length_domain
]
),
"feed_hot_exchanger_temperature": np.array(
[
traj.vecs[str(m.fs.feed_hot_exchanger.temp_wall_center[tf, z])]
for z in m.fs.feed_hot_exchanger.cold_side.length_domain
]
),
"sweep_exchanger_temperature": np.array(
[
traj.vecs[str(m.fs.sweep_exchanger.temp_wall_center[tf, z])]
for z in m.fs.sweep_exchanger.cold_side.length_domain
]
),
}
for controller in m.fs.controller_set:
ctrl_name = controller.local_name
results_dict[ctrl_name + "_mv_ref"] = np.array(
traj.vecs[str(controller.mv_ref[tf])]
)
results_dict[ctrl_name + "_setpoint"] = np.array(
traj.vecs[str(controller.setpoint[tf])]
)
Here we plot a number of system variables that we use to gauge system performance. The user is free to adapt this code to view other variables of interest. Note that PETSc preserves trajectories only for Pyomo Vars, not named Expressions—if you have an Expression you want to track, create a Var and a simple equality Constraint so PETSc will track it. (Don’t forget to scale the Var and Constraint.)
include_PI = True
def _demarcate_ramps(ax, results_dict):
for tpoint in np.squeeze(results_dict["ramp_list"])[:-1]:
ax.plot(np.array([tpoint, tpoint]) / 60**2, [-1e6, 1e6], "k--")
for key, value in results_dict.items():
# Turn n by 1 arrays in into vectors
results_dict[key] = np.squeeze(value)
demarcate_ramps = lambda ax: _demarcate_ramps(ax, results_dict)
time = results_dict["time"] / 60**2
ax_fontsize = 14
title_fontsize = 16
iz_plot = [1, 3, 5, 8, 10]
fig = plt.figure()
ax = fig.subplots()
ax.plot(time, results_dict["potential"])
if include_PI:
ax.plot(
time,
results_dict["voltage_controller_mv_ref"],
color="darkblue",
linestyle="dotted",
)
demarcate_ramps(ax)
ax.set_xlim(time[0], time[-1])
ax.set_ylim((0.65, 1.45))
ax.set_xlabel("Time (hr)", fontsize=ax_fontsize)
ax.set_ylabel("Cell potential (V)", fontsize=ax_fontsize)
ax.set_title("SOEC Voltage", fontsize=title_fontsize)
fig = plt.figure()
ax = fig.subplots()
ax.plot(time, results_dict["current"] * 1e-6)
demarcate_ramps(ax)
ax.set_xlim(time[0], time[-1])
ax.set_ylim((-250, 125))
ax.set_xlabel("Time (hr)", fontsize=ax_fontsize)
ax.set_ylabel("Current (MA)", fontsize=ax_fontsize)
ax.set_title("Total module current", fontsize=title_fontsize)
fig = plt.figure()
ax = fig.subplots()
ax.plot(time, results_dict["soec_fuel_inlet_flow"], label="Fuel")
ax.plot(time, results_dict["soec_oxygen_inlet_flow"], label="Sweep")
demarcate_ramps(ax)
ax.set_xlim(time[0], time[-1])
ax.set_ylim((0, 20000))
ax.set_xlabel("Time (hr)", fontsize=ax_fontsize)
ax.set_ylabel("SOEC inlet molar flow (mol/s)", fontsize=ax_fontsize)
ax.set_title("Inlet molar flow rates", fontsize=title_fontsize)
ax.legend()
fig = plt.figure()
ax = fig.subplots()
ax.plot(time, 1e-6 * results_dict["fuel_heater_duty"], label="Fuel", color="tab:blue")
ax.plot(
time, 1e-6 * results_dict["sweep_heater_duty"], label="Sweep", color="tab:orange"
)
if include_PI:
ax.plot(
time,
1e-6 * results_dict["feed_heater_inner_controller_mv_ref"],
label="Fuel reference",
color="darkblue",
linestyle="dotted",
)
ax.plot(
time,
1e-6 * results_dict["sweep_heater_inner_controller_mv_ref"],
label="Sweep reference",
color="saddlebrown",
linestyle="dotted",
)
demarcate_ramps(ax)
ax.set_xlim(time[0], time[-1])
ax.set_ylim((0, 11))
ax.set_xlabel("Time (hr)", fontsize=ax_fontsize)
ax.set_ylabel("Heater duty (MW)", fontsize=ax_fontsize)
ax.set_title("Trim heater duties", fontsize=title_fontsize)
ax.legend()
fig = plt.figure()
ax = fig.subplots()
ax.plot(time, results_dict["fuel_inlet_H2O"], label="Inlet $H_2O$")
ax.plot(time, results_dict["fuel_outlet_H2O"], label="Outlet $H_2O$")
ax.plot(time, results_dict["sweep_inlet_O2"], label="Inlet $O_2$")
ax.plot(time, results_dict["sweep_outlet_O2"], label="Outlet $O_2$")
ax.plot(time, results_dict["product_mole_frac_H2"], label="Product $H_2$")
ax.plot(time, 0.35 * np.ones(time.shape), "--")
ax.plot(time, 0.25 * np.ones(time.shape), "--")
demarcate_ramps(ax)
ax.set_xlim(time[0], time[-1])
ax.set_ylim((0, 1))
ax.set_xlabel("Time (hr)", fontsize=ax_fontsize)
ax.set_ylabel("Mole fraction", fontsize=ax_fontsize)
ax.set_title("Reactor feed and effluent concentrations", fontsize=title_fontsize)
ax.legend()
fig = plt.figure()
ax = fig.subplots()
ax.plot(time, results_dict["H2_production"])
demarcate_ramps(ax)
ax.set_xlim(time[0], time[-1])
ax.set_ylim((-1.25, 2.5))
ax.set_xlabel("Time (hr)", fontsize=ax_fontsize)
ax.set_ylabel("Hydrogen Production Rate (kg/s)", fontsize=ax_fontsize)
ax.set_title("Instantaneous $H_2$ production rate", fontsize=title_fontsize)
if include_PI:
ax.plot(
time,
results_dict["h2_production_rate_controller_setpoint"],
label="Target",
color="darkblue",
linestyle="dotted",
)
ax.legend()
fig = plt.figure()
ax = fig.subplots()
ax.plot(time, results_dict["steam_feed_rate"])
if include_PI:
ax.plot(
time,
results_dict["h2_production_rate_controller_mv_ref"],
label="Target",
color="darkblue",
linestyle="dotted",
)
demarcate_ramps(ax)
ax.set_xlim(time[0], time[-1])
ax.set_ylim((0, 7500))
ax.set_xlabel("Time (hr)", fontsize=ax_fontsize)
ax.set_ylabel("Steam feed rate (mol/s)", fontsize=ax_fontsize)
ax.set_title("Steam feed rate", fontsize=title_fontsize)
ax.legend()
fig = plt.figure()
ax = fig.subplots()
ax.plot(time, results_dict["sweep_feed_rate"])
if include_PI:
ax.plot(
time,
results_dict["sweep_blower_controller_mv_ref"],
label="Target",
color="darkblue",
linestyle="dotted",
)
demarcate_ramps(ax)
ax.set_xlim(time[0], time[-1])
ax.set_ylim((0, 11000))
ax.set_xlabel("Time (hr)", fontsize=ax_fontsize)
ax.set_ylabel("Sweep feed rate (mol/s)", fontsize=ax_fontsize)
ax.set_title("Sweep feed rate", fontsize=title_fontsize)
ax.legend()
fig = plt.figure()
ax = fig.subplots()
ax.plot(time, 1e-6 * results_dict["total_electric_power"], "b", label="Total power")
demarcate_ramps(ax)
ax.set_xlim(time[0], time[-1])
ax.set_ylim((-125, 350))
ax.set_xlabel("Time (hr)", fontsize=ax_fontsize)
ax.set_ylabel("Power usage (MW)", color="blue", fontsize=ax_fontsize)
ax.set_title("Power usage", fontsize=title_fontsize)
fig = plt.figure()
ax = fig.subplots()
ax.plot(time, results_dict["fuel_inlet_temperature"], label="Fuel", color="tab:blue")
ax.plot(
time, results_dict["sweep_inlet_temperature"], label="Sweep", color="tab:orange"
)
ax.plot(
time, results_dict["stack_core_temperature"], label="Stack core", color="darkgreen"
)
if include_PI:
ax.plot(
time,
results_dict["feed_heater_inner_controller_setpoint"],
label="Fuel target",
color="darkblue",
linestyle="dotted",
)
ax.plot(
time,
results_dict["sweep_heater_inner_controller_setpoint"],
label="Sweep target",
color="saddlebrown",
linestyle="dotted",
)
ax.plot(
time,
results_dict["sweep_blower_controller_setpoint"],
label="Core target",
color="olivedrab",
linestyle="dotted",
)
ax.set_xlim(time[0], time[-1])
ax.set_ylim((850, 1150))
ax.set_xlabel("Time (hr)", fontsize=ax_fontsize)
ax.set_ylabel("Temperature (K)", fontsize=ax_fontsize)
demarcate_ramps(ax)
ax.set_title("SOEC temperature", fontsize=title_fontsize)
ax.legend()
fig = plt.figure()
ax = fig.subplots()
ax.plot(time, results_dict["fuel_outlet_temperature"], label="Fuel", color="tab:blue")
ax.plot(
time, results_dict["sweep_outlet_temperature"], label="Sweep", color="tab:orange"
)
if include_PI:
ax.plot(
time,
results_dict["feed_heater_outer_controller_setpoint"],
label="Fuel target",
color="darkblue",
linestyle="dotted",
)
ax.plot(
time,
results_dict["sweep_heater_outer_controller_setpoint"],
label="Sweep target",
color="saddlebrown",
linestyle="dotted",
)
ax.set_xlim(time[0], time[-1])
ax.set_ylim((890, 1100))
ax.set_xlabel("Time (hr)", fontsize=ax_fontsize)
ax.set_ylabel("Temperature (K)", fontsize=ax_fontsize)
demarcate_ramps(ax)
ax.set_title("SOEC outlet temperature", fontsize=title_fontsize)
ax.legend()
fig = plt.figure()
ax = fig.subplots()
for iz in iz_plot:
ax.plot(time, results_dict["temperature_z"][iz - 1, :], label=f"z node {iz}")
ax.set_xlim(time[0], time[-1])
ax.set_ylim((890, 1100))
ax.set_xlabel("Time (hr)", fontsize=ax_fontsize)
ax.set_ylabel("Temperature (K)", fontsize=ax_fontsize)
demarcate_ramps(ax)
ax.set_title("SOEC temperature profile", fontsize=title_fontsize)
ax.legend()
fig = plt.figure()
ax = fig.subplots()
for iz in iz_plot:
ax.plot(
time,
results_dict["temperature_z"][iz - 1, :]
+ results_dict["fuel_electrode_temperature_deviation_x"][iz - 1, :],
label=f"z node {iz}",
)
ax.set_xlim(time[0], time[-1])
ax.set_ylim((890, 1100))
ax.set_xlabel("Time (hr)", fontsize=ax_fontsize)
ax.set_ylabel("Temperature (K)", fontsize=ax_fontsize)
demarcate_ramps(ax)
ax.set_title("Temperature electrode", fontsize=title_fontsize)
ax.legend()
fig = plt.figure()
ax = fig.subplots()
for iz in iz_plot:
ax.plot(
time,
results_dict["temperature_z"][iz - 1, :]
+ results_dict["interconnect_temperature_deviation_x"][iz - 1, :],
label=f"z node {iz}",
)
ax.set_xlim(time[0], time[-1])
ax.set_ylim((890, 1100))
ax.set_xlabel("Time (hr)", fontsize=ax_fontsize)
ax.set_ylabel("Temperature (K)", fontsize=ax_fontsize)
demarcate_ramps(ax)
ax.set_title("Temperature interconnect", fontsize=title_fontsize)
ax.legend()
fig = plt.figure()
ax = fig.subplots()
for iz in iz_plot:
ax.plot(
time, results_dict["fuel_electrode_gradient"][iz - 1, :], label=f"node {iz}"
)
ax.set_xlim(time[0], time[-1])
ax.set_ylim((-1000, 1000))
ax.set_xlabel("Time (hr)", fontsize=ax_fontsize)
ax.set_ylabel("$dT/dz$ ($K/m$)", fontsize=ax_fontsize)
ax.set_title("SOEC PEN temperature gradient", fontsize=title_fontsize)
demarcate_ramps(ax)
ax.legend()
fig = plt.figure()
ax = fig.subplots()
for iz in iz_plot:
ax.plot(
time,
results_dict["fuel_electrode_mixed_partial"][iz - 1, :],
label=f"node {iz}",
)
ax.set_xlim(time[0], time[-1])
ax.set_ylim((-2, 2))
ax.set_xlabel("Time (hr)", fontsize=ax_fontsize)
ax.set_ylabel("$d^2T/dzdt$ ($K/(m s)$)", fontsize=ax_fontsize)
ax.set_title("SOEC PEN temperature mixed partial", fontsize=title_fontsize)
demarcate_ramps(ax)
ax.legend()
fig = plt.figure()
ax = fig.subplots()
for iz in iz_plot:
ax.plot(time, results_dict["current_density"][iz - 1, :] / 10, label=f"z node {iz}")
ax.set_xlim(time[0], time[-1])
# ax.set_ylim((575,875))
ax.set_ylim((-1000, 650))
ax.set_xlabel("Time (hr)", fontsize=ax_fontsize)
ax.set_ylabel("Current density ($mA/cm^2$)", fontsize=ax_fontsize)
ax.set_title("SOEC current density", fontsize=title_fontsize)
demarcate_ramps(ax)
ax.legend()
fig = plt.figure()
ax = fig.subplots()
ax.set_xlabel("Time (hr)", fontsize=ax_fontsize)
ax.set_ylabel("Temperature (K)", fontsize=ax_fontsize)
for z in range(results_dict["feed_heater_temperature"].shape[0]):
ax.plot(
time,
results_dict["feed_heater_temperature"][z, :],
label=f"Feed wall node {z+1}",
)
ax.plot(
time,
results_dict["sweep_heater_temperature"][z, :],
label=f"Sweep wall node {z+1}",
)
ax.set_xlim(time[0], time[-1])
ax.set_ylim((870, 1175))
demarcate_ramps(ax)
ax.set_title("Trim heater wall temperature", fontsize=title_fontsize)
ax.legend()
fig = plt.figure()
ax = fig.subplots()
ax.set_xlabel("Time (hr)", fontsize=ax_fontsize)
ax.set_ylabel("Temperature (K)", fontsize=ax_fontsize)
for z in range(results_dict["feed_medium_exchanger_temperature"].shape[0]):
ax.plot(
time,
results_dict["feed_medium_exchanger_temperature"][z, :],
label=f"Node {z + 1}",
)
ax.set_xlim(time[0], time[-1])
ax.set_ylim((370, 520))
demarcate_ramps(ax)
ax.set_title("Medium exchanger wall temperature", fontsize=title_fontsize)
ax.legend()
fig = plt.figure()
ax = fig.subplots()
ax.set_xlabel("Time (hr)", fontsize=ax_fontsize)
ax.set_ylabel("Temperature (K)", fontsize=ax_fontsize)
for z in range(results_dict["feed_hot_exchanger_temperature"].shape[0]):
ax.plot(
time,
results_dict["feed_hot_exchanger_temperature"][z, :],
label=f"Node {z + 1}",
)
ax.set_xlim(time[0], time[-1])
ax.set_ylim((700, 950))
demarcate_ramps(ax)
ax.set_title("Hot exchanger wall temperature", fontsize=title_fontsize)
ax.legend()
fig = plt.figure()
ax = fig.subplots()
ax.set_xlabel("Time (hr)", fontsize=ax_fontsize)
ax.set_ylabel("Temperature (K)", fontsize=ax_fontsize)
for z in range(results_dict["sweep_exchanger_temperature"].shape[0]):
ax.plot(time, results_dict["sweep_exchanger_temperature"][z, :], label=f"Node {z}")
ax.set_xlim(time[0], time[-1])
ax.set_ylim((700, 1020))
demarcate_ramps(ax)
ax.set_title("Sweep exchanger wall temperature", fontsize=title_fontsize)
ax.legend()
fig = plt.figure()
ax = fig.subplots()
ax2 = ax.twinx()
ax.plot(
time,
results_dict["condenser_outlet_temperature"],
label="Temperature",
color="tab:blue",
)
ax2.plot(
time,
results_dict["product_mole_frac_H2"],
label="H2 mole fraction",
color="tab:orange",
)
ax.set_xlim(time[0], time[-1])
ax.set_ylim((273.15, 373.15))
ax.set_xlabel("Time (hr)", fontsize=ax_fontsize)
ax.set_ylabel("Temperature (K)", fontsize=ax_fontsize, color="tab:blue")
ax2.set_ylim((0, 1))
ax2.set_ylabel("Mole fraction $H_2$", fontsize=ax_fontsize, color="tab:orange")
demarcate_ramps(ax)
ax.set_title("Condenser Vapor Outlet", fontsize=title_fontsize)
fig = plt.figure()
ax = fig.subplots()
ax.plot(time, 1e-6 * results_dict["condenser_heat_duty"])
ax.set_xlim(time[0], time[-1])
ax.set_ylim((-40, -12))
ax.set_xlabel("Time (hr)", fontsize=ax_fontsize)
ax.set_ylabel("Heat Duty (MW)", fontsize=ax_fontsize)
demarcate_ramps(ax)
ax.set_title("Condenser Heat Duty", fontsize=title_fontsize)
plt.show()
C:\Users\dallan\AppData\Local\Temp\ipykernel_89136\3422529511.py:405: RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface (`matplotlib.pyplot.figure`) are retained until explicitly closed and may consume too much memory. (To control this warning, see the rcParam `figure.max_open_warning`). Consider using `matplotlib.pyplot.close()`.
fig = plt.figure()