bloc.reactors.tube_furnace#

Tube furnace Lagrangian model, wall profile network, and KPI bridge.

Classes#

PFRWallProfileNet

Stage network driving a TubeFurnace through a prescribed wall profile.

TubeFurnace

Industrial Tube Furnace model.

SootRadiatingTubeFurnace

Tube furnace with soot-augmented grey-gas radiation.

Functions#

compute_tube_furnace_kpis(sim)

Compute tube-furnace engineering KPIs from a solved STONE Simulation.

Module Contents#

class bloc.reactors.tube_furnace.PFRWallProfileNet(reactors, meta=None, *, wall_T_fn=None, total_length=None, n_points=200, rtol=0.0001, atol=1e-12)#

Stage network driving a TubeFurnace through a prescribed wall profile.

Replaces the legacy LagrangianPFRReactor + LagrangianPFRNetwork + DesignTubeFurnaceNet trio with a single driver built on the unified PFRWallProfile engine and the shared march_lagrangian_parcel() marcher.

Physics#

A closed Lagrangian gas parcel is marched from inlet to outlet. At each spatial checkpoint the wall temperature T_wall(x) and the entry-length position x_position = max(x - heating_start, 0) are pushed onto the carrier; the after_eval() hook then injects forced-convection + grey-gas-radiation flux into the energy ODE.

Numerics#

Unlike the retired adaptive net.step loop, this driver uses the fixed-checkpoint net.advance march (n_points default 200), which yields a uniform spatial grid and reproduces the experimentally-validated (Mei 2019) profiles within < 1 %. Spatial resolution is controlled by n_points alone; inner CVODE step size is left to the integrator.

The public surface is duck-typed to Boulder’s CustomStageNetwork (time, states, scalars, advance, advance_to_steady_state) and exposes the tube-furnace diagnostics (E_conv, E_rad, n_steps, h_conv_avg, Fo_D_min and the recorded *_arr profiles) consumed by compute_tube_furnace_kpis(), report_details and yaml_utils.

param reactors:

Iterable containing exactly one TubeFurnace (PFRWallProfile) reactor.

param meta:

Geometry / wall-profile parameters produced by _build_design_tube_furnace() (total_length, T_wall_K, T_ambient_K, entry_leg, exit_leg, entry_zone, plateau_zone, T_wall_profile, diameter, kappa_grey).

type meta:

dict, optional

NETWORK_DIAGRAM_NOTE: str = 'Node temperatures in this diagram reflect the outlet gas state of the Lagrangian simulation...#
reactors#
E_conv: float = 0.0#
E_rad: float = 0.0#
n_steps: int = 0#
h_conv_avg: float#
Fo_D_min: float#
x_arr: numpy.ndarray | None = None#
t_arr: numpy.ndarray | None = None#
T_wall_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[str] | None = None#
Fo_D_arr: numpy.ndarray | None = None#
h_conv_arr: numpy.ndarray | None = None#
alpha_arr: numpy.ndarray | None = None#
u_arr: numpy.ndarray | None = None#
k_arr: numpy.ndarray | None = None#
Re_arr: numpy.ndarray | None = None#
Pr_arr: numpy.ndarray | None = None#
property reactor: bloc.reactors.plug_flow.PFRWallProfile#

The single PFRWallProfile/TubeFurnace 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 backward compatibility with diagnostics readers.

property time: float#

Residence time [s] of the Lagrangian march (0 before advance).

property preconditioner#

Preconditioner is managed inside march_lagrangian_parcel; exposed for symmetry.

solve_steady()#

Delegate to advance_to_steady_state() for Boulder solve_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 from inlet to outlet.

The full axial cantera.SolutionArray is attached to the reactor as _states (consumed by Boulder’s stage-state collector and spatial_series_fn). 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]#

Tube-furnace scalars (wall energy budget, residence time, meta).

draw(title='Tube Furnace Wall Temperature Profile', n_points=200)#

Return a schematic matplotlib Figure of the tube-furnace geometry.

Upper panel: colour-coded tube rectangle (cold→hot→cold). Lower panel: wall (and, post-advance, gas) temperature profile. Does not require advance() — relies only on wall_T_fn/total_length.

plot_temperature_profile(title='Temperature Profile Tube Furnace')#

Plot gas + wall temperature vs position with a residence-time axis.

Requires advance_to_steady_state() to have been called.

plot_species_profiles(species=None, title='Species Profile Tube Furnace')#

Plot mole-fraction profiles vs position with a residence-time axis.

Requires advance_to_steady_state() to have been called. When species is None, the six species with the highest peak mole fraction (≥ 0.1 %) are selected automatically.

bloc.reactors.tube_furnace.compute_tube_furnace_kpis(sim)#

Compute tube-furnace engineering KPIs from a solved STONE Simulation.

Bridges the STONE/Boulder path to the same output key set as bloc.yaml_utils._tf_kpi_extractor() (the ctwrap path), so that run_yaml_scenarios.py and the legacy ctwrap runner produce the same Calculation Note Excel.

Looks for a PFRWallProfileNet in sim.network.networks (the stage solver mapping). All scalars are read from that network, which is populated during advance_to_steady_state.

Parameters:

sim (bloc.simulation_builder.Simulation) – Solved STONE simulation returned by bloc.simulation_builder.build_simulation_from_yaml().

Returns:

Flat scalar dict with keys matching bloc.yaml_utils.TF_OUTPUT_VARIABLE_MAP (T_outlet_C, E_conv_J, E_rad_J, P_conv_avg_W, P_rad_avg_W, SEO_MJ_kg, n_steps, h_conv_avg_W_m2_K, Fo_D_min, diameter_mm, t_res_s) plus per-species mole (X_*) and mass (Y_*) fractions. Returns an empty dict when no PFRWallProfileNet is found in sim.network.networks.

Return type:

dict

class bloc.reactors.tube_furnace.TubeFurnace(gas, *args, clone=False, diameter=0.1, kappa_grey=0.0, mass_flow_rate=0.0, **kwargs)#

Bases: bloc.reactors.plug_flow.PFRWallProfile

Industrial Tube Furnace model.

A plug-flow reactor heated by an externally prescribed wall-temperature profile T_wall(x) using forced convection and grey-gas radiation (see PFRWallProfile).

STONE kind: TubeFurnace. For the STONE YAML schema see TubeFurnaceSchema.

Use this kind for any electrically or indirectly heated tube where the wall temperature profile is known or measured. The Carbon-Black tube furnace (Mei-2019 validation) is the canonical example.

See also

PFRWallProfile

underlying numerical engine.

RefractoryReactor

insulated thick-shell reactor (SPRING CGR).

NETWORK_CLASS: ClassVar[type | None] = None#
SOLVER_MODE: ClassVar[str] = 'adaptive'#
diameter = 0.1#
kappa_grey = 0.0#
mass_flow_rate = 0.0#
T_wall_K: float | None = None#
x_position: float = 0.0#
after_eval(t, LHS, RHS)#

Inject wall convection + radiation into the energy ODE RHS.

before_update_state(y)#

Inject a pending initial state into CVODE’s y before 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 None for 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.tube_furnace.SootRadiatingTubeFurnace(gas, *args, clone=False, diameter=0.1, kappa_grey=0.0, mass_flow_rate=0.0, soot_density=1800.0, n_C_min=None, **kwargs)#

Bases: TubeFurnace

Tube furnace with soot-augmented grey-gas radiation.

Overrides the energy-balance hook so the radiative flux uses an effective absorption coefficient kappa = kappa_grey + kappa_soot evaluated from the local gas state, instead of the fixed self.kappa_grey used by the base class. kappa_grey therefore carries the clean-gas baseline.

Soot contribution uses the Planck-mean grey-gas correlation (Rodrigues):

\[\kappa_{soot} = 3.83\,\frac{C_0}{C_2}\,f_v\,T\]

where:

  • \(f_v = Y_{soot}\,\rho_{gas}/\rho_{soot}\) is the local soot volume fraction, with \(Y_{soot}\) the summed solid-carbon mass fraction, \(\rho_{gas}\) the gas density, and \(\rho_{soot}\) the soot particle density (soot_density, default 1800 kg/m³).

  • \(C_0 = 6\pi\,E(m)\) is the soot optical constant, with \(E(m) \approx 0.260\) the soot absorption function (dimensionless). Implemented as _SOOT_C0 = 6 * pi * 0.260.

  • \(C_2 = hc/k_B\) is the second radiation constant (Planck law), \(C_2 \approx 0.014388\) m·K. Implemented as _SOOT_C2.

The prefactor 3.83 and the \(C_0/C_2\) grouping are folded into _SOOT_KAPPA_COEFF in code.

References

Rodrigues, P. Modélisation multiphysique de flammes turbulentes suitées avec la prise en compte des transferts radiatifs et des transferts de chaleur pariétaux.

soot_density#
n_C_min = None#
after_eval(t, LHS, RHS)#

Inject wall convection + soot-augmented grey-gas radiation.

NETWORK_CLASS: ClassVar[type | None] = None#
SOLVER_MODE: ClassVar[str] = 'adaptive'#
diameter = 0.1#
kappa_grey = 0.0#
mass_flow_rate = 0.0#
T_wall_K: float | None = None#
x_position: float = 0.0#
before_update_state(y)#

Inject a pending initial state into CVODE’s y before 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 None for 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.