0038. A specified split's energy imbalance is stated, and the plant closure takes it¶
- Status: Proposed
- Date: 2026-10-30
Context¶
The simulation's energy audit (domains/process/simulation/energy.py, cheme process energy,
predictive.energy-closure) closes every unit and the plant on the solved stream enthalpies.
A component_separator (DWSIM's ComponentSeparator) splits its feed by given recoveries
(basis: specified), so nothing in it conserves energy: its outlets' enthalpy differs from
its inlet's by whatever the split implies. DWSIM reports that difference as EnergyImb, but
the sign of EnergyImb was never shown, so the audit refused the unit
(sim-energy-unsupported, "the sign of the component separator's energy imbalance is not
established") and with it the whole plant. In the ammonia-1 platform run (core#60,
process-library#86, D-024) every reactor closed but the plant audit stayed unsupported
because of C301 (aMDEA CO2 removal) and X401 (dryer). The specified split is the documented
fallback for units core cannot simulate (electrolyte absorption, adsorption, drying,
membranes), so no plant that relies on it could show its energy closure.
Options considered:
- Establish the sign of
EnergyImbin a live DWSIM test and use it as a duty. That needs DWSIM, and it would still count a bookkeeping number as a heat duty. - Leave the plant unsupported (the status quo).
- Take the imbalance from the solved streams themselves (enthalpy out minus in, the same
enthalpy flows every other closure uses), state it with a fixed sign convention, and close
the plant with it as a stated residual.
EnergyImbis then not needed. Each run records how it relates to the streams' value.
Decision¶
cheme-as-code takes option 3.
- A specified split (
STATED_UNITS:component_separator) getsstatus: statedinenergy.closure.units, withimbalance_kW= sum of outlet enthalpy flows minus sum of inlet enthalpy flows (kW, simulator enthalpies),sign_convention(positive: the heat the unit would have to take in for its balance to close),heat_in_kWequal to it, the enthalpy flows and the unit tolerance. It is not judged: noresidual_kW, neversim-energy-unbalanced. - The simulator's
EnergyImb(the worker'sduty_kW) is recorded assimulator_imbalance_kWwithsimulator_convention:out-minus-inorin-minus-out(it equals the stated value or its negative within the tolerance),negligible,indeterminate(the stated value is at most twice the tolerance, so a sign cannot be told apart),differsornot-reported. A sign is assigned only when the stated value exceeds twice the tolerance. The closure never relies on it. - The plant closure adds
stated_kW(the sum) andstated(unit -> kW). Its residual is boundary enthalpy out minus in (plus the formation term) minus the units' heat and work minusstated_kW;heat_in_kWstays the units' heat without the stated imbalances. The tolerance counts the sum of the stated magnitudes (each|stated|, so opposite imbalances do not cancel) with the duties. - A specified split whose imbalance exceeds its tolerance gives
cheme.process-sim-energy-stated(info), which names the value and its sign. A specified split without stream enthalpies makes the plantnot-evaluable, with the reason. - The stated imbalance is not a utility (
utilitiesdoes not count it). The real unit's duties (regenerator reboiler, dryer heating) are not modelled by the split and are accounted for separately. predictive.energy-closurepasses on a plant that closes with stated imbalances, and its detail names them. Runs recorded before this change keep theirunsupportedplant until they are simulated again;cheme process energysays so.cheme process simulatestill writes no duty to a separator's energy stream (run.py_into_unit).
Consequences¶
- Positive: plants that keep a specified split for a unit core cannot simulate get a plant energy verdict. The verdict tests the rest of the flowsheet (every other unit, recycle convergence) and shows the split's imbalance as a number with a sign. It does not depend on an unverified simulator sign, and every run records evidence for DWSIM's convention.
- Negative: a large stated imbalance can hide a real modelling gap (the energy a real absorber or dryer needs). It is shown as an info finding and in the plant line, not as a failure. Reviewers have to read it.
- Open: once
simulator_conventionhas been observed in live runs, the energy stream of a separator could carry its duty (run.py). The record does not keep per-stream enthalpies, so an older run cannot be re-audited without simulating again.
Evidence¶
- Issue core#60.
src/chemeascode/domains/process/simulation/energy.py(_stated,_closure),src/chemeascode/domains/process/energy.py(energy_text),src/chemeascode/project/maturity.py(_energy_audit).tests/test_energy_closure.py(specified-split tests).