rizer.models.nrp.isomass_2T_isobaric_reactor#
Attributes#
Classes#
Two-temperature 0D plasma reactor: constant mass, constant (total and partial) pressure. |
Module Contents#
- rizer.models.nrp.isomass_2T_isobaric_reactor.logger#
- class rizer.models.nrp.isomass_2T_isobaric_reactor.Isomass2TIsobaricReactor(plasma: cantera.Solution, momentum_transfer_collision_frequencies_list: list[rizer.transport.collision_frequency.MomentumTransferCollisionFrequencyModel], electric_circuit: rizer.electrical_model.circuit.base_circuit.PlasmaVoltageCircuit | None = None, gap: float | None = None, initial_radius: float | None = None, mass: float | None = None, compute_chemistry: bool = True, compute_Te: bool = False, compute_Tg: bool = True, single_temperature: bool = False, T_wall: float | None = None, **kwargs)#
Bases:
cantera.ExtensibleReactorTwo-temperature 0D plasma reactor: constant mass, constant (total and partial) pressure.
Driven by
cantera.ReactorNet, mirroring the organization ofIsomass2TVolumeReactor.Teis solved for, not prescribed.This is a full
replace_get_state/replace_update_state/replace_evalport, not anafter_evaladdition onto a stockIdealGasConstPressureReactor. Confirmed by testing a plain, unmodifiedct.IdealGasConstPressureReactoron one of this project’sPlasmaPhaseobjects: its native energy equation unconditionally callsPlasmaPhase::intrinsicHeating()(native Joule heating,sigma = e n_e mu_e), which callselectronMobility(), which raisesNotImplementedErrorfor any electron-energy-distribution type other than"Boltzmann-two-term"– every mechanism in this repo (checked:simple.yaml,air_plasma_Laux2000.yaml,Goutier2025/CH4_to_C2H2.yaml) uses"isotropic", so the native energy equation cannot be used at all with these plasma phases, regardless ofafter_eval. A full replace bypasses the nativeeval()entirely, so this native-only code path never runs.The following assumptions are made:
Constant mass plasma (no mass flow).
Homogeneous plasma (0D reactor).
Isobaric: the total pressure is constant, and (see Notes) the electron and heavy-species partial pressures are each assumed constant too, so the electron-/gas-energy balances below drop their pressure-derivative terms entirely.
Cylindrical geometry between two electrodes – only needed when
compute_Teis enabled, to compute the electric field for Joule heating.No heat loss to the surroundings unless
T_wallis given (conductive loss to a wall atT_wallthrough the column radius,conductive_heat_loss()).Multi-temperature ideal gas equation of state (Maxwellian distribution for each species, with different temperatures for electrons and heavy species).
Reflections of the generator voltage wave in the electric circuit are considered – only when
compute_Teis enabled.No surface chemistry.
- Parameters:
plasma (
cantera.Solution) – Cantera plasma object. Passed withclone=False, and stored asself.plasma(not read back viaself.phase):self.phasere-wraps the underlying C++ phase fresh on every access, and that fresh wrapper does not carry the Python-side_enable_plasmaflag, so plasma-only setters (.Te =) raiseThermoModelMethodErroron it even though getters and genericThermoPhaseproperties work fine. Storing the constructor argument directly sidesteps this;clone=Falseguarantees it shares the same underlying state.momentum_transfer_collision_frequencies_list (
listofMomentumTransferCollisionFrequencyModel) – List of momentum transfer collision frequency models for each species in the plasma object. Forwarded toMixtureCollisionFrequencies.electric_circuit (
PlasmaVoltageCircuit, optional) – Electric circuit object – any of TransmissionLineResistiveCircuit, TransmissionLineRCLoadCircuit, DirectResistiveCircuit, DirectRCLoadCircuit, GeneratorVoltageCircuit (seePlasmaVoltageCircuit). Required (and used to compute the Joule term) only ifcompute_Te.gap (
float, optional) – Gap between the two electrodes, in m. Used to compute the electric field from the plasma voltage. Required only ifcompute_Te.initial_radius (
float, optional) – Initial radius of the plasma, in m – only used to seedself.plasma_radiusbefore the first RHS evaluation (the radius itself is then re-derived each step from the current density andmass, since there is no integrated volume state here). Required only ifcompute_Te.mass (
float, optional) – Mass of the plasma, in kg. Assumed constant. Used (with the current density) to derive the plasma volume/radius for the Joule term. Required only ifcompute_Te.compute_chemistry (
bool, optional) – Independently zero out a term’s RHS contribution without changing the state-vector layout (n_varsstays2 + nspregardless).compute_chemistryandcompute_TgdefaultTrue;compute_TedefaultsFalse(Testays externally prescribed, matching this reactor’s original single-temperature behavior, unless explicitly enabled).compute_Te (
bool, optional) – Independently zero out a term’s RHS contribution without changing the state-vector layout (n_varsstays2 + nspregardless).compute_chemistryandcompute_TgdefaultTrue;compute_TedefaultsFalse(Testays externally prescribed, matching this reactor’s original single-temperature behavior, unless explicitly enabled).compute_Tg (
bool, optional) – Independently zero out a term’s RHS contribution without changing the state-vector layout (n_varsstays2 + nspregardless).compute_chemistryandcompute_TgdefaultTrue;compute_TedefaultsFalse(Testays externally prescribed, matching this reactor’s original single-temperature behavior, unless explicitly enabled).single_temperature (
bool, optional) – TieTetoTg(one temperature for the whole mixture): the electron-heavy exchange terms are internal to the mixture and drop out, and the gas-temperature equation becomes the mixture’s enthalpy balance (mixturecpincluding the electrons, every species’ enthalpy in the chemical term).dTe/dt = dTg/dtkeeps the state vector layout unchanged. Cannot be combined withcompute_Te. DefaultFalse.T_wall (
float, optional) – Wall temperature [K]. When given, the conductive wall lossconductive_heat_loss()at the live column radius (frommass, the density andgap, which are then both required) is subtracted from the gas-temperature equation. DefaultNone: adiabatic.
- Raises:
ValueError – If
compute_Te=Trueandelectric_circuit,gap,initial_radiusormassis not provided; ifsingle_temperature=Trueandcompute_Te=Trueorcompute_Tg=False; or ifT_wallis given withoutmassandgap.
Notes
Equations solved implies constant mass and homogeneous quantities only. The equations solved are based on [Aurora] and [Mitchner1973], adapted to constant pressure (enthalpy-based) rather than constant volume (internal-energy-based, see
Isomass2TVolumeReactor).Equation of state:
The equation of state chosen is the multi-temperature ideal gas law, like in [Chemkin]:
\[P = \sum_k [X_k] R T_k\]where:
\(P\) is the pressure, in Pa,
\(X_k\) is the mole fraction of species \(k\),
\(R\) is the ideal gas constant, in J/mol/K,
\(T_k\) is the temperature of species \(k\), in K (\(T_e\) for electrons, \(T_g\) for heavy species).
Conservation of mass:
Since the system is assumed to be closed, the mass is constant:
\[\frac{dm}{dt} = 0\]Isobaric assumption:
The total pressure \(P\) is held fixed. The electron and heavy-species partial pressures \(P_e\), \(P_g\) are each assumed constant too:
\[\frac{dP_e}{dt} = \frac{dP_g}{dt} = 0\]which drops the pressure-derivative term from both energy equations below entirely (rather than solving for it) – see
polytropic_volume_rate()’s own docstring note that a genuine isobaric closure needs “a different closure … enthalpy-based energy balance” than the polytropic volume-relaxation law used byIsomass2TVolumeReactor.Balance equation for species mass fractions:
\[\frac{dY_k}{dt} = \frac{W_k \dot{\omega_k}}{\rho}\]where:
\(Y_k\) the mass fraction of species \(k\),
\(W_k\) the molecular weight of species \(k\), in kg/kmol,
\(\omega_k\) the production rate of species \(k\), in kmol/m^3/s,
\(\rho\) the density, in kg/m^3.
Balance equation for the electron energy:
\[\rho Y_e c_{p, e} \frac{dT_e}{dt} = \vec{j} \cdot \vec{E} - \dot{\omega_e} M_e c_{p, e} T_e - \dot{Q}_{elas} - \dot{Q}_{inel}\]where:
\(c_{p, e}\) the specific heat at constant pressure of the electrons, in J/kg/K,
\(Y_e\) the mass fraction of electrons,
\(T_e\) the electron temperature, in K,
\(\vec{j}\) the current density, in A/m^2,
\(\vec{E}\) the electric field, in V/m,
\(\omega_k\) the production rate of electron \(k\), in kmol/m^3/s,
\(M_e\) the molecular weight of the electron, in kg/kmol,
\(\dot{Q}_{elas}\) the heat production rate due to elastic collisions, in W/m^3,
\(\dot{Q}_{inel}\) the heat production rate due to inelastic collisions, in W/m^3.
Balance equation for the gas (heavy species) energy:
\[\rho \bar{c_p} \frac{dT_g}{dt} = - \sum_{k \neq e} W_k h_k \dot{\omega_k} + \dot{Q}_{elas} + \dot{Q}_{inel}\]where:
\(\bar{c_p}=\sum_{k \neq e} c_{p, k} Y_k\) the mean specific heat at constant pressure of heavies species in the gas, in J/kg/K,
\(h_k\) the enthalpy of species \(k\), in J/kg.
See also
- plasma#
- n_vars#
- P#
Fixed pressure of the reactor [Pa].
- compute_chemistry = True#
- compute_Te = False#
- compute_Tg = True#
- single_temperature = False#
- T_wall = None#
adiabatic).
- Type:
Wall temperature [K] of the conductive loss term (
None
- electric_circuit = None#
Electric circuit object (
Noneunlesscompute_Te).
- gap = None#
Gap between the electrodes [m] (
Noneunlesscompute_Te).
- plasma_mass = None#
Mass of the plasma [kg]. Assumed constant (
Noneunlesscompute_Te).
- plasma_voltage = 0.0#
Stored plasma voltage [V] (updated only if
compute_Te).
- plasma_resistance = 0.0#
Stored plasma resistance [Ohm] (updated only if
compute_Te).
- plasma_radius#
Stored plasma radius [m] (updated only if
compute_Te).
- P_elastic = 0.0#
Stored elastic power [W/m^3].
- P_inelastic = 0.0#
Stored inelastic power [W/m^3].
- P_chemical = 0.0#
Stored chemical power due to heavy species production/consumption [W/m^3].
- P_chemical_e = 0.0#
Stored chemical power due to electron production/consumption [W/m^3].
- P_Joule = 0.0#
Stored Joule power [W/m^3] (updated only if
compute_Te).
- nu_eH = 0.0#
Stored electron-heavy collision frequency [s^-1].
- nu_ee = 0.0#
Stored electron-electron collision frequency [s^-1].
- nu_eI = 0.0#
Stored electron-ion collision frequency [s^-1].
- replace_get_state(y: numpy.ndarray) None#
Populate the initial state vector.
State vector is
y = [Tg, Te, Y_1, ..., Y_K].
- replace_update_state(y: numpy.ndarray) None#
Set the state of the plasma object from the state vector
y.Split out because Cantera calls
update_state(y)andeval(t, LHS, RHS)as two separate steps (update_statealways runs first), so by the timereplace_evalbelow runs,self.plasmaalready reflects thisy.
- replace_eval(t: float, LHS: numpy.ndarray, RHS: numpy.ndarray) None#
Compute the RHS of the ODE system.
LHS[:] = 1throughout: every equation already divides through by its own left-hand-side coefficient (heat capacity, etc.) below, soRHSdirectly holdsdy/dt.