You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Status: Verified bug against the current master source in this fork.
Severity: High.
Area labels: area:reactors.
Tackle batch: P2 - shared thermo, phase, and basis correctness.
The source review confirmed that the cited code path and failure mode are still present. The original audit details are preserved below for reproduction notes and suggested fixes.
Original audit details
Severity: High · Part of #67 (round-2 audit batch)
Convective enthalpy term weights the second enthalpy by holdup instead of inlet concentration, contradicting the no-outflow material balance
Location:PharmaPy/Reactors.py:1046-1048 (CSTR.energy_balances flow_term), reached for SemibatchReactor via lines 1289-1294 and 1013-1069
SemibatchReactor reuses CSTR.energy_balances. flow_term = inlet_flow*(h_in - h_temp) with h_in = sum(inlet_conch_inj) (inlet composition) and h_temp = sum(mole_conch_tempj) (HOLDUP composition) (lines 1046-1048). This is the correct in-minus-out form for a CSTR, but a semibatch reactor has NO outflow: its material balance (1289-1294, dN_i/dt = FC_in,i + r_iV; dvol_dt = inlet_flow at 1292) is pure accumulation. Deriving the consistent temperature-form balance gives NCpdT/dt = Fsum(C_in,i*(h_in,i(T_in) - h_i(T))) + source - ht, i.e. BOTH enthalpy terms must be weighted by inlet C_in,i. The code instead subtracts Fsum(C_ih_i(T)) using holdup C_i, an enthalpy of a nonexistent outflow, leaving a spurious error term F*sum((C_in,i - C_i)*h_i(T)). Since h_i is sensible enthalpy referenced to 298.15 K, the error does not vanish even when T_in ~ T.
Trigger: SemibatchReactor(vol_tank=..., isothermal=False) (isothermal=False is documented, lines 1233-1235) with a feed composition different from the initial charge (the normal case), then solve_unit(). Exercised in tests/Flowsheet/flowsheet_tests.py:131 (holdup B+solvent, feed pure A).
Wrong result: dtemp_dt (line 1069) uses the wrong convective enthalpy, so the temperature trajectory is wrong; through Arrhenius temp_term this also corrupts reaction rates and hence the concentration profiles of every non-isothermal semibatch run with feed composition != charge. No crash; silently wrong.
Suggested fix: Override energy_balances for SemibatchReactor (or branch in CSTR.energy_balances on 'vol' in states_uo): replace h_temp with the inlet-weighted holdup enthalpy, flow_term = inlet_flow*(inlet_conc*(h_inj - h_tempj)).sum(axis=1)1000 = Fsum(C_in,i*(h_in,i(T_in) - h_i(T))), removing the spurious outflow-at-holdup-composition term.
Related existing issues (referenced, not modified):#34 (CSTR equilibrium getHeatOfRxn signature), #38/#25/#24/#48/#68/#80 (Mixer/crystallizer/drying/extraction enthalpy-reference issues) -- reference only; none address the semibatch convective enthalpy term.
Found by a multi-agent source audit (round 2); confirmed by re-reading the source and cross-checked against all 80 existing open issues. Each defect was verified by an independent code-truth skeptic and a novelty skeptic.
Maintainer triage (June 29, 2026)
mastersource in this fork.The source review confirmed that the cited code path and failure mode are still present. The original audit details are preserved below for reproduction notes and suggested fixes.
Original audit details
Severity: High · Part of #67 (round-2 audit batch)
Convective enthalpy term weights the second enthalpy by holdup instead of inlet concentration, contradicting the no-outflow material balance
Location:
PharmaPy/Reactors.py:1046-1048 (CSTR.energy_balances flow_term), reached for SemibatchReactor via lines 1289-1294 and 1013-1069SemibatchReactor reuses CSTR.energy_balances. flow_term = inlet_flow*(h_in - h_temp) with h_in = sum(inlet_conch_inj) (inlet composition) and h_temp = sum(mole_conch_tempj) (HOLDUP composition) (lines 1046-1048). This is the correct in-minus-out form for a CSTR, but a semibatch reactor has NO outflow: its material balance (1289-1294, dN_i/dt = FC_in,i + r_iV; dvol_dt = inlet_flow at 1292) is pure accumulation. Deriving the consistent temperature-form balance gives NCpdT/dt = Fsum(C_in,i*(h_in,i(T_in) - h_i(T))) + source - ht, i.e. BOTH enthalpy terms must be weighted by inlet C_in,i. The code instead subtracts Fsum(C_ih_i(T)) using holdup C_i, an enthalpy of a nonexistent outflow, leaving a spurious error term F*sum((C_in,i - C_i)*h_i(T)). Since h_i is sensible enthalpy referenced to 298.15 K, the error does not vanish even when T_in ~ T.
Related existing issues (referenced, not modified): #34 (CSTR equilibrium getHeatOfRxn signature), #38/#25/#24/#48/#68/#80 (Mixer/crystallizer/drying/extraction enthalpy-reference issues) -- reference only; none address the semibatch convective enthalpy term.
Found by a multi-agent source audit (round 2); confirmed by re-reading the source and cross-checked against all 80 existing open issues. Each defect was verified by an independent code-truth skeptic and a novelty skeptic.