Skip to content

High: [Reactors] Coil heat transfer, sensitivity estimation, and steady-state PFR modes crash #70

Description

@sergey-gusev94

Maintainer triage (June 29, 2026)

  • Status: Verified bug against the current master source in this fork.
  • Severity: High.
  • Area labels: area:reactors.
  • Tackle batch: P3 - documented-mode crashes and tooling breakages.

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 / Medium · Category: crash (control-flow + API misuse) · Part of #67

Three Reactors.py defects, each of which makes a documented reactor configuration crash. Grouped as one "make the reactor module runnable in all advertised modes" fix.


1. (High) PlugFlowReactor.solve_steady reads non-existent Inlet.concentr

Location: PharmaPy/Reactors.py:1604-1607

c_inlet = self.Inlet.concentr (1604), then indexed. No phase/stream stores concentr: LiquidPhase.__set_amounts sets only mole_conc/mass_conc/mole_frac/mass_frac; LiquidStream.updatePhase maps its concentr argument positionally onto the base mole_conc. There is no concentr property anywhere.

  • Trigger: build a PFR, assign a LiquidStream inlet, call reactor.solve_steady(vol_rxn) (also feeds plot_steady/concProfSteady/tempProfSteady).
  • Wrong result: AttributeError: 'LiquidStream' object has no attribute 'concentr'; the entire steady-state PFR solver and plot_steady are unrunnable.
  • Fix: use self.Inlet.mole_conc (the dynamic path already uses self.Liquid_1.mole_conc).

2. (Medium) CSTR / SemibatchReactor solve_unit(eval_sens=True) leaves problem undefined

Location: PharmaPy/Reactors.py:1134-1144 (and 1326-1336)

if eval_sens: pass (1134-1135) never builds problem; only the else branch creates Explicit_Problem. Execution then unconditionally reaches solver = CVode(problem) (1144). paramest_wrapper calls solve_unit(eval_sens=True) whenever self.return_sens is True, which defaults True in the CSTR/Semibatch constructors.

  • Trigger: sensitivity-based parameter estimation on a CSTR/SemibatchReactor with default return_sens=True.
  • Wrong result: NameError: name 'problem' is not defined; CSTR/Semibatch parameter estimation crashes immediately.
  • Fix: implement the eval_sens problem setup (mirror BatchReactor.solve_unit 800-813 with get_sundials_callable, problem.jac, problem.rhs_sens), or raise NotImplementedError instead of pass.

3. (Medium) heat_transfer ht_mode='coil' leaves heat_transf undefined

Location: PharmaPy/Reactors.py:294-302

if self.ht_mode == 'coil': pass (296-297) never assigns heat_transf, yet return heat_transf (302) is reached unconditionally. The tank reactors' energy balances call self.heat_transfer(...) for any non-isothermal run (BatchReactor 711; CSTR 1060/1066). 'coil' is an advertised ht_mode (docstring 603-605).

  • Trigger: BatchReactor(isothermal=False, ht_mode='coil') (or CSTR), solve_unit.
  • Wrong result: UnboundLocalError: local variable 'heat_transf' referenced before assignment on the first RHS evaluation.
  • Fix: implement coil-mode area/duty, or raise NotImplementedError for ht_mode=='coil' rather than falling through.

Related (not duplicates): #55 (sensitivity Jacobian block sizing), #54 (temp_ht metadata), #33 (PFR specific area diam/4) are distinct defects.

Metadata

Metadata

Assignees

Labels

area:reactorsBatch, CSTR, semibatch, and plug-flow reactor modelsbugSomething isn't workingcorrectnessModel/numerical correctness defectseverity:highConfirmed bug with major correctness impact or broken documented workflowstatus:verifiedSource-reviewed against the current codebase

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions