bloc.reactors.pfr_networks#
Homogeneous-shell PFR network, marching helpers, and RefractoryReactor.
Attributes#
Classes#
ReactorNet subclass implementing Forward-Backward Sweep for a PFR stage. |
|
Industrial Carbon Growth Reactor (CGR) / refractory-lined vessel. |
|
Single-pass PFR network for the thin-shell hypothesis. |
|
Industrial quartz-tube / lab-tube reactor. |
|
Stage network driving a |
Functions#
|
Serialize a closed CSTR residence-time profile for the Plots tab. |
|
Serialize a spatial |
|
Return True when kind is a registered STONE kind for any PFR/CGR profile reactor. |
Module Contents#
- bloc.reactors.pfr_networks.HeatFluxFactory#
- bloc.reactors.pfr_networks.residence_states_to_series(states)#
Serialize a closed CSTR residence-time profile for the Plots tab.
- Parameters:
states – Profile with extra
t[s] (physical residence time, not axial position).- Returns:
Keys:
t,T,P,X,Y,is_residence. Arrays are plain Python lists for JSON safety.is_spatialis intentionally absent so Boulder does not label the axis as position [m].- Return type:
dict
- bloc.reactors.pfr_networks.states_to_series(states, fbs_convergence=None)#
Serialize a spatial
SolutionArrayprofile to a JSON-compatible dict.- Parameters:
states – Converged spatial profile with custom
x(position, m) andt(residence time, s) extra columns set by_march_pfr_to_length().fbs_convergence – Per-FBS-iteration list of
Phi_kWvalues, orNone.
- Returns:
Keys:
x,t,T,P,X,Y,is_spatial,fbs_convergence. All arrays are plain Python lists for JSON safety.- Return type:
dict
- class bloc.reactors.pfr_networks.PFRHomogeneousShellNet(reactors, meta=None)#
Bases:
cantera.ReactorNetReactorNet subclass implementing Forward-Backward Sweep for a PFR stage.
Overrides
advance()to run the FBS heat-loss convergence loop. The spatial integration is performed by_spatial_ode_pass(), which uses thePFRHomogeneousShellreactor directly as the ODE carrier — no auxiliary gas or reactor objects are created. For each pass, a freshReactorNetwraps thePFRHomogeneousShellso CVODE always starts from the correct (heat-loss-corrected) inlet state. The converged spatial profile is stored on the reactor as_statesfor downstream trajectory collection.- Parameters:
reactors – List of reactors to integrate. Must contain exactly one
PFRHomogeneousShell.meta (
dict, optional) – Geometry and insulation parameters for the FBS loop, as produced by_build_pfr_homogeneous_shell().
- MAX_ITER: int = 10#
- CONVERGENCE_TOL: float = 0.01#
- role: ClassVar[str] = 'reactor'#
- advance_to_steady_state()#
Advance to the tube outlet (one nominal time unit).
- solve_steady()#
Delegate to
advance_to_steady_state()for Bouldersolve_steadykind.Cantera’s default would use the empty reactor list from
super().__init__and fail.
- advance(time)#
Run Forward-Backward Sweep and update the PFR reactor state.
Reads the inlet state from
self._pfr_reactor.phase(set by the staged solver before this call), then iterates_spatial_ode_pass()with updated heat-loss estimates until convergence orMAX_ITERis reached. In the adiabatic branch a single pass with zero heat flux is performed.After convergence the wall flux is pinned to the converged scalar value so a downstream visualization network sees the actual radial loss. The spatial profile is written to
reactor._statesand the scalar toreactor._heat_loss_kW.- Parameters:
time – Nominal advance time [s]. Not used by the length-terminated PFR integration; kept for API compatibility with
ReactorNet.
- property states: cantera.SolutionArray | None#
Converged FBS spatial profile (satisfies
CustomStageNetwork).
- property states_as_series: dict | None#
Return the spatial profile as a JSON-serializable dict for the frontend.
- class bloc.reactors.pfr_networks.RefractoryReactor(gas, *args, **kwargs)#
Bases:
bloc.reactors.plug_flow.PFRHomogeneousShellIndustrial Carbon Growth Reactor (CGR) / refractory-lined vessel.
A plug-flow reactor with homogeneous-shell radial heat loss through an insulation resistance stack, converged by Forward-Backward Sweep (see
PFRHomogeneousShell).STONE kind:
RefractoryReactor. Node id in SPRING YAML:cgr(the CGR in SPRING A3/A4).Use this kind for thick-walled insulated industrial reactors where axial wall conduction smears temperature gradients.
See also
PFRHomogeneousShellunderlying numerical engine.
QuartzTubeReactorthin-shell variant for lab reactors.
- NETWORK_CLASS: ClassVar[type | None] = None#
- mass_and_power(qm_torch, T_torch_input_C, X_torch, qm_2nd_inj, T_2nd_inj_C, X_2nd_inj, P_bar, T_amb_C, gas)#
Compute preheat recovery and residual heat based on reactor states.
Industrial-design helper for SPRING thermal-recovery KPIs (consumed by
bloc.spring_kpi.compute_spring_kpis()).
- SOLVER_MODE: ClassVar[str] = 'fixed_checkpoint'#
- thermal_resistance_stack()#
Build the radial-conduction + external-convection resistance list.
Uses
_metageometry and insulation layers. Returns a list of thermal resistances [K/W] from inner wall to ambient, ordered from innermost insulation layer to external convection/radiation.
- wall_thermal_report(T_mean_C)#
Return the wall heat-transfer breakdown at a mean gas temperature.
Single source of truth for the SPRING wall KPIs: the external film coefficients (
h_CC,h_rad,h_eff[W/m²/K]), the external wall temperature (T_wall_ext[°C]) and the resulting wall heat loss (heat_loss_kW, includingheat_loss_corr_factor). When_meta["adiabatic"]is set the loss is zero and the wall sits at ambient.- Parameters:
T_mean_C – Spatial-mean gas temperature in °C.
- Returns:
{"h_CC", "h_rad", "h_eff", "T_wall_ext", "heat_loss_kW"}.- Return type:
dict
- spatial_mean_temperature(states)#
Compute the spatial-mean gas temperature [°C] from a PFR profile.
Integrates T over the axial position recorded by
_march_pfr_to_lengthin thexextra column, using the trapezoid rule (trapezoid(states.T, states.x) / states.x[-1]) so the FBS heat-loss estimate is identical between the staged and standalone paths.- Parameters:
states – SolutionArray with an
xextra column (axial position [m]).- Returns:
Length-weighted mean temperature in °C. Falls back to the unweighted mean only if
states.xis missing or zero.- Return type:
float
- heat_loss(T_mean_C)#
Compute total wall heat loss [kW] for a given mean gas temperature.
Uses the linearized thermal resistance stack from
thermal_resistance_stack()and multiplies by_meta["heat_loss_corr_factor"](default 1.0) to account for thermal bridges and other unmodelled loss paths. Returns 0 when_meta["adiabatic"]is True.- Parameters:
T_mean_C – Spatial-mean gas temperature in °C.
- Returns:
Heat loss in kW (positive = loss to ambient).
- Return type:
float
- solve_forward(Phi_kW)#
Integrate the PFR with a fixed heat-loss power and return the spatial profile.
Builds a
PFRHomogeneousShellNetand delegates to its_spatial_ode_pass. This is the single-shot entry point for standalone use and tests; the FBS convergence loop inPFRHomogeneousShellNet.advancecalls_spatial_ode_passdirectly.- Parameters:
Phi_kW – Total wall heat loss to subtract from the inlet enthalpy [kW]. Positive value = heat removed from the gas.
- Returns:
Spatial profile with extra columns
t(residence time [s]) andx(axial position [m]).- Return type:
ct.SolutionArray
- before_update_state(y)#
Inject a pending initial state into CVODE’s
ybefore the first eval.
- heat_flux_factory(carrier)#
Return a heat-flux callable
Q(t) [W/m²]for this wall model.Override in subclasses to provide the wall heat-transfer law. Return
Nonefor an adiabatic parcel.- Parameters:
carrier – The fresh closed-carrier instance created by
build_closed_carrier_net(). Subclasses may read carrier attributes (diameter,phase,_meta, …) to build the closure.
- bloc.reactors.pfr_networks.is_pfr_profile_kind(kind)#
Return True when kind is a registered STONE kind for any PFR/CGR profile reactor.
“Any PFR/CGR profile reactor” means
PFRHomogeneousShellor a subclass — e.g. the SPRINGRefractoryReactor(CGR) kind. Resolved via Boulder’s schema registry (reactor_classpassed toregister_reactor_builder), the same mechanismis_torch_reactor_kind()uses — so a new homogeneous-shell PFR subclass is recognized automatically; no hardcoded kind-name list to maintain.
- class bloc.reactors.pfr_networks.PFRThinShellNet(reactors, meta=None)#
Bases:
cantera.ReactorNetSingle-pass PFR network for the thin-shell hypothesis.
Heat loss depends on the local gas temperature
T(z)so a single forward pass is sufficient — there is no Forward-Backward Sweep. The radial loss enters the ODE through the build-timect.Wall, whoseheat_fluxis wired to a callable that readsreactor.phase.Teach CVODE eval.After
advance()the wall flux is pinned to the integrated scalarPhi_kWso the post-solve visualization network shows a Wall carrying the actual radial loss.- Parameters:
reactors – Stage reactors; must contain exactly one
PFRThinShell.meta (
dict, optional) – Geometry and thermal parameters (length,diameter,insulation,T_amb…) as produced by_build_pfr_thin_shell().
- advance_to_steady_state()#
Advance through the single-pass thin-shell solve.
- solve_steady()#
Delegate to
advance_to_steady_state()(same pattern asPFRHomogeneousShellNet).
- advance(time)#
Run a single-pass thin-shell solve and update the reactor state.
- Parameters:
time – Nominal advance time [s]. Not used by the length-terminated integration; kept for API compatibility with
ReactorNet.
- property states: cantera.SolutionArray | None#
Spatial profile (satisfies
CustomStageNetwork).
- property states_as_series: dict | None#
Return the spatial profile as a JSON-serializable dict for the frontend.
- class bloc.reactors.pfr_networks.QuartzTubeReactor(gas, *args, **kwargs)#
Bases:
bloc.reactors.plug_flow.PFRThinShellIndustrial quartz-tube / lab-tube reactor.
A plug-flow reactor with thin-shell local-temperature radial heat loss (see
PFRThinShell). Single forward pass; no Forward-Backward Sweep.STONE kind:
QuartzTubeReactor.Use this kind for quartz, fused-silica, or other thin-walled lab reactors where axial wall conduction is negligible.
See also
PFRThinShellunderlying numerical engine.
RefractoryReactorthick-shell variant for industrial vessels.
- NETWORK_CLASS: ClassVar[type | None] = None#
- SOLVER_MODE: ClassVar[str] = 'fixed_checkpoint'#
- thermal_resistance_stack#
- wall_thermal_report#
- spatial_mean_temperature#
- heat_loss#
- solve_forward()#
Integrate the PFR with the local-T heat loss and return the spatial profile.
Single-shot entry point for standalone use and tests. Builds a
PFRThinShellNetand runs oneadvancepass.- Returns:
Spatial profile with extra columns
tandx.- Return type:
ct.SolutionArray
- before_update_state(y)#
Inject a pending initial state into CVODE’s
ybefore the first eval.
- heat_flux_factory(carrier)#
Return a heat-flux callable
Q(t) [W/m²]for this wall model.Override in subclasses to provide the wall heat-transfer law. Return
Nonefor an adiabatic parcel.- Parameters:
carrier – The fresh closed-carrier instance created by
build_closed_carrier_net(). Subclasses may read carrier attributes (diameter,phase,_meta, …) to build the closure.
- class bloc.reactors.pfr_networks.PFRGasTemperatureProfileNet(reactors, meta=None, *, T_gas_fn=None, total_length=None, n_points=200, rtol=0.0001, atol=1e-12)#
Stage network driving a
PFRGasTemperatureProfile.Imposes a prescribed gas temperature profile
T_gas(x)on a closed Lagrangian parcel: the energy equation is disabled and the temperature is reset toT_gas(x)at every spatial checkpoint, so only the kinetics evolve. This is the Dirichlet-on-gas counterpart of the wall-drivenPFRWallProfileNet.The public surface is duck-typed to Boulder’s
CustomStageNetwork(time,states,scalars,advance,advance_to_steady_state) and records the axial temperature and species profiles consumed by the calculation note and the plot helpers.- Parameters:
reactors – Iterable containing exactly one
PFRGasTemperatureProfilereactor.meta – Geometry/profile meta dict (populated by
_build_pfr_gas_temperature_profile()). Must containtotal_lengthand the trapezoidal-profile keys (T_gas_K,T_ambient_K,entry_leg,exit_leg,entry_zone,plateau_zone) or an explicitT_gas_profiledict.T_gas_fn – Standalone API: pass an explicit
T_gas(x)callable and tube length instead of the STONE meta dict (used by examples and tests).total_length – Standalone API: pass an explicit
T_gas(x)callable and tube length instead of the STONE meta dict (used by examples and tests).n_points – Standalone API: pass an explicit
T_gas(x)callable and tube length instead of the STONE meta dict (used by examples and tests).rtol – Integrator tolerances forwarded to
march_lagrangian_parcel().atol – Integrator tolerances forwarded to
march_lagrangian_parcel().
- reactors#
- x_arr: numpy.ndarray | None = None#
- t_arr: numpy.ndarray | None = None#
- T_gas_arr: numpy.ndarray | None = None#
- Y_Cs_arr: numpy.ndarray | None = None#
- X_arr: numpy.ndarray | None = None#
- species_names: list | None = None#
- property reactor: bloc.reactors.plug_flow.PFRGasTemperatureProfile#
The single PFRGasTemperatureProfile reactor (used by plot helpers).
- property mass_flow_rate: float#
Mass flow rate [kg/s] of the driven reactor.
- property network#
Self-reference kept for symmetry with PFRWallProfileNet readers.
- property time: float#
Residence time [s] of the Lagrangian march (0 before advance).
- property preconditioner#
Preconditioner is managed inside march_lagrangian_parcel.
- solve_steady()#
Delegate to
advance_to_steady_state()for Bouldersolve_steady.
- advance(t=1.0)#
Advance to
t; for a Lagrangian tube this runs to the outlet.
- advance_to_steady_state()#
Run the fixed-checkpoint parcel march with the gas temperature imposed.
Idempotent: a second call is a no-op.
- property states: cantera.SolutionArray | None#
Axial Lagrangian profile (satisfies Boulder’s stage-state collector).
- property scalars: Dict[str, Any]#
Imposed-gas-T scalars (residence time + meta).
- plot_temperature_profile(title='Imposed Gas Temperature Profile')#
Plot the imposed gas temperature
T_gas(x)vs position [degC].
- plot_species_profiles(species=None, title='Species Profiles (imposed gas T)')#
Plot mole-fraction profiles vs position with a residence-time axis.
When
speciesisNone, the six species with the highest peak mole fraction (≥ 0.1 %) are selected automatically.