bloc.reactors.tube_furnace#
Tube furnace Lagrangian model, wall profile network, and KPI bridge.
Classes#
Stage network driving a |
|
Industrial Tube Furnace model. |
|
Tube furnace with soot-augmented grey-gas radiation. |
Functions#
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)#
Bases:
bloc.reactors.pfr_networks._LagrangianDuckTypedNetMixinStage network driving a
TubeFurnacethrough a prescribed wall profile.Replaces the legacy
LagrangianPFRReactor+LagrangianPFRNetwork+DesignTubeFurnaceNettrio with a single driver built on the unifiedPFRWallProfileengine and the sharedmarch_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 positionx_position = max(x - heating_start, 0)are pushed onto the carrier; theafter_eval()hook then injects forced-convection + grey-gas-radiation flux into the energy ODE.Numerics#
Unlike the retired adaptive
net.steploop, this driver uses the fixed-checkpointnet.advancemarch (n_pointsdefault 200), which yields a uniform spatial grid and reproduces the experimentally-validated (Mei 2019) profiles within < 1 %. Spatial resolution is controlled byn_pointsalone; 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_minand the recorded*_arrprofiles) consumed bycompute_tube_furnace_kpis(),report_detailsandyaml_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
- role: ClassVar[str] = 'furnace'#
- report_states: ClassVar[bool] = False#
- FO_PROFILE_KEYS: ClassVar[tuple[str, ...]] = ('x_arr', 'T_wall_arr', 'T_gas_arr', 'alpha_arr', 'k_arr', 'u_arr', 'Re_arr', 'Pr_arr',...#
- NETWORK_DIAGRAM_NOTE: str = 'Node temperatures in this diagram reflect the outlet gas state of the Lagrangian simulation...#
- model_notes()#
Return the physical models and numerics this stage used, one line each.
Consumed by the calculation note’s Notes sheet (see
bloc.reporting.orchestrator_stone._stone_model_notes_from_sim()). States what was actually used: the convection correlations are the ones the march recorded checkpoint by checkpoint, with the Reynolds range over which each applied, not a static description.
- fo_profile()#
Return the axial thermal-homogeneity profile as plain float lists.
JSON-safe, so the profile survives the Calculation Note’s cached bundle. The Excel table used to be rendered straight off a live network object, which only the retired ctwrap path ever provided, so it never appeared in a STONE export.
Returns None before the march has run.
- reactors#
- E_conv: float = 0.0#
- E_rad: float = 0.0#
- E_total: 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).
- advance_to_steady_state()#
Run the fixed-checkpoint parcel march from inlet to outlet.
The full axial
cantera.SolutionArrayis attached to the reactor as_states(consumed by Boulder’s stage-state collector andspatial_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).
- export_cfd_conditions()#
Export the tube-furnace trajectory as CFD initial/boundary conditions.
Returns a dict with all the state arrays and scalars needed by Avalanche to render the OpenFOAM case: inlet T, p, composition, mass flow rate, wall T profile (x, T_wall), axial velocity, Re, residence time, diameter, and length.
The node must already have been solved (via
advance_to_steady_state()orbuild_simulation_from_yaml()). This method does not re-run the 1-D solve; it only reads the cached trajectory arrays.- Returns:
CFD-relevant state from the solved tube-furnace trajectory.
- Return type:
dict
- 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 onwall_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_reynolds_profile(title='Reynolds Number — Tube Furnace')#
Plot the local Reynolds number vs position, with the laminar limit.
Re = mdot D / (A mu), evaluated at the local gas state along the march, so it tracks the viscosity rise as the gas heats. Re = 2300 is drawn for reference: below it the flow is laminar and the convection correlation falls back to a constant Nusselt number.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. WhenspeciesisNone, the six species with the highest peak mole fraction (≥ 0.1 %) are selected automatically.
- 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 Bouldersolve_steady.
- advance(t=1.0)#
Advance to
t; for a Lagrangian tube this runs to the outlet.
- 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 thatrun_yaml_scenarios.pyand the legacy ctwrap runner produce the same Calculation Note Excel.Looks for a
PFRWallProfileNetinsim.network.networks(the stage solver mapping). All scalars are read from that network, which is populated duringadvance_to_steady_state.- Parameters:
sim (
bloc.simulation_builder.Simulation) – Solved STONE simulation returned bybloc.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 gas-phase mole (X_*) and mass (Y_*) fractions (solid carbon excluded and renormalised, reported separately asX_C(s)/Y_C(s)) and, when the feed carries H or C, the performance KPIs shared with the SPRING calc note (H2_yield,C(s)_yield,CH4_conversion,H2_production,C(s)_production,Ecost_H2 (kWh/kgH2)). With a torch stage upstream the performance KPIs are referenced to the process feed and the torch energy rows are added (G_PW_IN (kW),TP_PW_OUT (kW),SEI_torch (MJ/kg),SEO_torch (MJ/kg));Ecost_H2then uses the generator electric power as in the SPRING calc note. Returns an empty dict when noPFRWallProfileNetis found insim.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.PFRWallProfileIndustrial 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 (seePFRWallProfile).STONE kind:
TubeFurnace. For the STONE YAML schema seeTubeFurnaceSchema.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
PFRWallProfileunderlying numerical engine.
RefractoryReactorinsulated 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#
- wall_heat_terms()#
Return
(Q_conv, Q_rad, h_conv, kappa)for the current phase state.after_evalis an ODE right-hand-side hook, so the solver also calls it for trial steps it later rejects and for every finite-difference Jacobian column._last_Q_convtherefore holds whatever perturbed state was evaluated last, which is not the accepted solution and is not reproducible across machines. Anything reporting these terms must recompute them from the accepted state by calling this.
- 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
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.
- add_energy_stream(stream)#
Attach an
EnergyStreamrecord to this reactor.
- property energy_inlets: list[EnergyStream]#
Energy streams currently flowing into this reactor (power_w > 0).
- property energy_outlets: list[EnergyStream]#
Energy streams currently flowing out of this reactor (power_w < 0).
- 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:
TubeFurnaceTube 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_sootevaluated from the local gas state, instead of the fixedself.kappa_greyused by the base class.kappa_greytherefore 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_COEFFin 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#
- wall_heat_terms()#
Return
(Q_conv, Q_rad, h_conv, kappa_eff)for the current state.See
PFRWallProfile.wall_heat_terms():after_evalruns inside the solver’s right-hand-side evaluations, so_last_Q_convis whichever trial or Jacobian-perturbation state came last. Reporting code must call this instead.
- 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
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.
- add_energy_stream(stream)#
Attach an
EnergyStreamrecord to this reactor.
- property energy_inlets: list[EnergyStream]#
Energy streams currently flowing into this reactor (power_w > 0).
- property energy_outlets: list[EnergyStream]#
Energy streams currently flowing out of this reactor (power_w < 0).