Reactor Types#
Bloc organises its reactor implementations into two distinct layers:
Numerical engines — base classes that implement the ODE physics and spatial march algorithms for a given reactor paradigm (PFR, PSR, Tube Furnace).
Industrial models — concrete subclasses that inherit from engines and add domain-specific geometry, heat-transfer assumptions, and KPI extraction.
This page describes the physics of each class, explains when to use which model,
documents the rename from legacy Design* names, and justifies why Cantera’s
built-in FlowReactor is not used in the PFR engine.
Architecture overview#
Cantera ExtensibleIdealGasConstPressureMoleReactor
│
├── PSR ← engine: well-mixed open CSTR
│ ├── ContinuousMixingReactor ← industrial model: TMR / multi-inlet vessel
│ └── InstantaneousMixing ← engine: 0-D HP mix + closed-τ chemistry
│ └── InstantaneousMixingReactor ← industrial model: 0-D+C variant
│
└── PFR ← engine: Lagrangian parcel base
├── PFRWallProfile ← engine: prescribed T_wall profile
│ └── TubeFurnace ← industrial model: tube furnace
│
├── PFRHomogeneousShell ← engine: homogeneous-shell radial loss + FBS
│ └── RefractoryReactor ← industrial model: CGR / insulated vessel
│
├── PFRThinShell ← engine: thin-shell local-T radial loss
│ └── QuartzTubeReactor ← industrial model: quartz-tube / lab reactor
│
└── PFRGasTemperatureProfile ← engine + STONE kind: imposed gas T(x)
(Dirichlet on the gas, energy OFF)
TorchInstantaneousHeating ← engine: instantaneous enthalpy jump (not a PFR)
└── PlasmaTorchInstantaneousHeating ← industrial model: plasma torch
Why not Cantera’s FlowReactor?#
Cantera provides a
FlowReactor
that is integrated as a 1-D PFR. Bloc cannot use it for three reasons:
Spatial DAE, not a time-ODE.
FlowReactoris discretised axially: each spatial step is a time step advancing along z.ReactorNetintegrates it as a differential–algebraic system over axial distance, not time. Mixing aFlowReactorwith time-dependent ODE reactors (PSR,IdealGasReactor) in oneReactorNetis not supported.Adiabatic and frictionless. The built-in
FlowReactorcarries no wall heat-transfer mechanism. Supplying wall loss requiresafter_evalhooks or custom wall objects — at which point the simplicity advantage disappears.No steady-state coupling. A Bloc SPRING network requires a PSR (torch mixing zone) to feed a PFR (growth reactor) in a single staged solve. The
FlowReactoralone in its own spatialReactorNetcannot share state with the upstream PSR at advance-time.
Bloc therefore implements PFRs as closed Lagrangian parcel marches: a single
ExtensibleIdealGasConstPressureMoleReactor is advanced in time along the tube
axis. At each checkpoint the reactor state equals the state of a fluid parcel
that has spent t = z / u(z) seconds in the tube. Wall heat transfer is added
through Cantera’s after_eval hook or ct.Wall objects — both supported in
time-ODE networks.
Numerical engines#
PFR — Plug Flow Reactor (base)#
Physics: Closed Lagrangian parcel at constant pressure. A single fluid
parcel marches from z = 0 to z = L along the tube axis. At each step the
ODE
dT/dt = Q_wall / (m_parcel * cp)
dn_k/dt = V_parcel * omega_k (molar species production)
is integrated by Cantera’s CVODE solver at constant pressure. No mass enters or
leaves during the march: dm/dt = 0.
Common invariants:
ExtensibleIdealGasConstPressureMoleReactorfamily (constant pressure, mole-based state).Geometry stored in
_meta(length,diameter,mass_flow_rate)._pending_init/before_update_statepattern for injecting initial conditions without constructing a new reactor each step.
Subclasses add heat-transfer physics. All share PFRNetwork as driver.
PFRWallProfile — Prescribed Wall Temperature Profile#
Physics: The wall temperature varies along the tube axis according to a
user-supplied profile (e.g., the plateau/ramp profile of an electric tube furnace).
Heat transfer to the fluid parcel has two components evaluated at each after_eval
call:
Forced convection:
Q_conv = h * A_lateral * (T_wall(z) - T_gas), wherehis computed from the Nusselt correlation for internal pipe flow.Grey-gas radiation:
Q_rad = kappa_grey * 4 * sigma * (T_wall(z)⁴ - T_gas⁴) * V_parcel.
SOLVER_MODE = "adaptive" — the network uses net.step() (adaptive step) to
resolve the steep temperature gradients near the ramp boundaries.
When to use: Electrically heated tube furnaces with a known, spatially varying
wall temperature (plateau + cold legs + ramps). Industrial model:
TubeFurnace.
PFRHomogeneousShell — Homogeneous-Shell Radial Heat Loss#
Physics: Thick-walled, heavily insulated vessel where axial wall conduction
smears temperature gradients along the shell. The total wall heat loss Φ [kW]
is evaluated from the spatial-mean gas temperature T_mean using a radial
resistance stack (insulation layers + external natural convection + radiation):
Phi = (T_mean - T_amb) / R_total [kW]
This heat loss is distributed uniformly along the tube in a single forward ODE
pass via a ct.Wall with heat_flux = -Phi / A_lateral. Because T_mean
depends on the solution and the solution depends on Φ, the solver uses a
Forward-Backward Sweep (FBS):
Adiabatic pass →
T_mean_0.Compute Φ from
T_mean_0.Heated forward pass → new
T_mean_1.Iterate until
|Phi_n - Phi_{n-1}| / Phi_0 < CONVERGENCE_TOL(default 1 %).
SOLVER_MODE = "fixed_checkpoint" — uniform checkpoints along the axis.
When to use: SPRING reactors (CGR), insulated refractory-lined vessels, any
reactor where axial wall conduction prevents local temperature gradients from
dominating heat loss. Industrial model: RefractoryReactor.
PFRThinShell — Thin-Shell Local-Temperature Radial Heat Loss#
Physics: Thin-walled reactor (quartz tube, steel tube with negligible axial
conduction) where heat loss at each axial position depends only on the local gas
temperature T(z):
q(z) = (T(z) - T_amb) / R_total [W/m²]
The wall conductance is inserted as a ct.Wall with time-varying heat_flux
pinned to q(z) at each checkpoint. Because q(z) depends only on T(z) (no
FBS needed), the solution requires only a single forward pass.
SOLVER_MODE = "fixed_checkpoint" — uniform checkpoints along the axis, no FBS.
When to use: Quartz-tube lab reactors, thin-wall steel tubes, any reactor
where axial wall conduction is negligible. Industrial model: QuartzTubeReactor.
PFRGasTemperatureProfile — Imposed Gas Temperature Profile#
Physics: The gas temperature itself is prescribed along the axis as a
profile T_gas(x) (Dirichlet on the gas). This is the boundary condition the
other PFR engines do not cover: PFRWallProfile prescribes the wall
temperature and lets the gas lag behind it through a convective + radiative
film, whereas here the gas temperature is imposed and the energy equation is
switched off — only the kinetics evolve:
T_gas(x) = T_prescribed(x) (energy equation disabled)
dn_k/dt = V_parcel * omega_k (kinetics still integrated)
Numerically the closed Lagrangian parcel is marched with
march_lagrangian_parcel(..., energy_off=True); the temperature is re-imposed
before each checkpoint advance, so the stepwise-constant history converges to
the continuous profile as the checkpoint count grows. This is the OO,
closed-parcel counterpart of the procedural
bloc.reactors.solve_fixed_position_temperature_profile_pfr.
SOLVER_MODE = "fixed_checkpoint" — uniform checkpoints along the axis, energy
off, no FBS.
When to use: Kinetics validation against a measured in-stream gas temperature (thermocouple trace), or any study where you want predicted species under a known thermal history rather than a predicted temperature.
STONE kind: PFRGasTemperatureProfile. Exceptionally, this numerical
engine is registered directly as a STONE kind (no separate industrial-model
wrapper): the imposed-gas-temperature march is itself the modelled object.
Driven by PFRGasTemperatureProfileNet.
Key YAML fields: diameter, total_length, T_gas_K, T_ambient_K,
entry_leg, exit_leg, entry_zone, plateau_zone, optional T_gas_profile.
PSR — Perfectly Stirred Reactor (base)#
Physics: Well-mixed control volume at constant pressure. In an open stage
network (SPRING ContinuousMixingReactor), Cantera integrates:
dT/dt = (sum_k h_k * V * omega_k - mdot * (h_out - h_in)) / (m * cp)
dn_k/dt = V * omega_k + mdot * (X_k,in - X_k)
with continuous inlet/outlet mass flows until steady state
(advance_to_steady_state).
Network topology:
Stage YAML: OPEN — MFC in, PC/MFC out.
Inner physics: OPEN CSTR (not a closed parcel like the torch).
Common invariants:
ExtensibleIdealGasConstPressureMoleReactorfamily.Design residence time
t_res_ssizes volume:V = t_res_s * mdot / rhovia Bloc post-build (_post_build_design_volumes).
When to use: Continuously-fed well-mixed reactor zones (torch outlet mixing
tee, multi-inlet vessel). Industrial model: ContinuousMixingReactor.
InstantaneousMixing — 0-D HP Mix + Closed Residence-Time Chemistry#
Physics: Two inlet streams are combined via constant-H, constant-P algebraic
mixing (mix_two_streams), then a closed parcel integrates ODE chemistry
from t = 0 to t = t_res_s with no mass exchange during integration.
The two steps implement the Da_mix ≫ 1 assumption: turbulent mixing time is much shorter than the chemical relaxation time, so mixing can be treated as instantaneous before chemistry begins.
Step 1: gas_mix = HP_mix(gas_1, qm_1, gas_2, qm_2) # algebraic, 0-D
Step 2: advance closed parcel 0 → t_res_s # CVODE, no MFC flux
Network topology:
Stage YAML: OPEN — two inlet MFCs (source reservoirs or upstream outlets), outlet MFC/PC for downstream handoff.
Inner physics: CLOSED parcel (no flux during CVODE integration). MFC rates are used only to identify the two inlet streams and their
mass_flow_rate.
When to use: Feedforward one-shot mixing scenarios where the inlets arrive at
distinct conditions (temperature, composition) and the mixing timescale is much
faster than chemistry. For a continuously-fed CSTR, use ContinuousMixingReactor instead.
Industrial model: InstantaneousMixingReactor.
Industrial Models#
Industrial models are thin concrete subclasses of the engine classes. They add domain-specific parameter names, default values, KPI extractors, and documentation. They do not change the underlying physics.
TubeFurnace ← PFRWallProfile#
Electric tube furnace with a spatially varying internal wall temperature
(plateau + entry/exit ramps + unheated cold legs). Uses forced convection and
grey-gas radiation from the LagrangianPFRReactor engine.
STONE kind: TubeFurnace
Key YAML fields: diameter, total_length, T_wall_K, T_ambient_K,
entry_leg, exit_leg, entry_zone, plateau_zone, kappa_grey,
mass_flow_rate.
KPI function: bloc.reactor_models:compute_tube_furnace_kpis
RefractoryReactor ← PFRHomogeneousShell#
Insulated refractory-lined growth reactor (CGR in SPRING). Uses the homogeneous-shell heat-loss model with Forward-Backward Sweep.
STONE kind: RefractoryReactor (YAML node id CGR is a user convention)
Key YAML fields: length, diameter, mass_flow_rate, eps_wall,
T_wall_hyp, T_amb, insulation, adiabatic, heat_loss_corr_factor.
QuartzTubeReactor ← PFRThinShell#
Quartz-tube or thin-wall lab reactor. Uses the thin-shell local-T heat-loss model.
STONE kind: QuartzTubeReactor
Key YAML fields: same as RefractoryReactor.
ContinuousMixingReactor ← PSR#
Multi-inlet well-mixed open CSTR (TMR in SPRING). Accepts multiple inlet: ports.
Volume is sized by Bloc post-build using V = t_res_s * mdot / rho.
STONE kind: ContinuousMixingReactor (YAML node id TMR is a user convention)
Key YAML fields: t_res_s, temperature, pressure, composition.
Mixing model: Da_mix ≫ 1 assumed. Inlet streams are stirred by Cantera’s MFC
topology inside the open CSTR until advance_to_steady_state. This is appropriate
when the mixing and chemistry occur simultaneously in a continuously-fed vessel.
InstantaneousMixingReactor ← InstantaneousMixing ← PSR#
Two-inlet reactor that combines algebraic HP mixing with closed-parcel chemistry.
STONE kind: InstantaneousMixingReactor
Key YAML fields: t_res_s, temperature, pressure, composition.
Requires exactly two inlet MassFlowController connections. Bloc post-build
(_post_build_design_volumes) gathers both inlet states and mass flow rates, calls
InstantaneousMixing.solve_premixed, and writes the outlet back to reactor.phase
syncState().
When to choose over ContinuousMixingReactor:
Criterion |
|
|
|---|---|---|
Feed mode |
Continuously fed |
One-shot feedforward |
Chemistry |
CSTR (open, steady-state) |
Closed parcel (no MFC flux) |
Mixing |
In-vessel MFC stirring |
Algebraic HP mix before chemistry |
Da_mix assumption |
Implicit (well-mixed vessel) |
Explicit (Da_mix ≫ 1) |
|
Sizes volume via |
CVODE integration horizon |
|
True |
False |
PlasmaTorchInstantaneousHeating ← TorchInstantaneousHeating#
Plasma torch modelled as an instantaneous enthalpy injection followed by
chemical equilibration. Not a PFR. The InstantaneousHeating suffix
reserves the namespace for future torch models with different heating physics.
STONE kind: PlasmaTorchInstantaneousHeating
Key YAML fields: torch_eff, gen_eff, t_res_s, temperature, pressure,
composition.
Kind rename map#
The table below maps the legacy Design* YAML kinds to the current names.
Legacy kinds are no longer registered — new and existing YAML files should use
the current names.
Legacy kind |
Current kind |
Engine base |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
See the migration guide to update YAML files from legacy kinds to the current names.
PFRNetwork — Unified network driver#
PFRNetwork is the single network driver for all PFR subclasses. It
dispatches on SOLVER_MODE:
"adaptive"— uses Cantera’snet.step()for each spatial checkpoint. Used byPFRWallProfile/TubeFurnace."fixed_checkpoint"— advances to each checkpoint withnet.advance(t_check). May iterate (FBS) whenPFRHomogeneousShellis used. Single-pass forPFRThinShell.
All PFR subclasses set NETWORK_CLASS = PFRNetwork.