rizer.models.nrp.isomass_2T_isobaric_reactor#

Attributes#

Classes#

Isomass2TIsobaricReactor

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.ExtensibleReactor

Two-temperature 0D plasma reactor: constant mass, constant (total and partial) pressure.

Driven by cantera.ReactorNet, mirroring the organization of Isomass2TVolumeReactor. Te is solved for, not prescribed.

This is a full replace_get_state/replace_update_state/replace_eval port, not an after_eval addition onto a stock IdealGasConstPressureReactor. Confirmed by testing a plain, unmodified ct.IdealGasConstPressureReactor on one of this project’s PlasmaPhase objects: its native energy equation unconditionally calls PlasmaPhase::intrinsicHeating() (native Joule heating, sigma = e n_e mu_e), which calls electronMobility(), which raises NotImplementedError for 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 of after_eval. A full replace bypasses the native eval() 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_Te is enabled, to compute the electric field for Joule heating.

  • No heat loss to the surroundings unless T_wall is given (conductive loss to a wall at T_wall through 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_Te is enabled.

  • No surface chemistry.

Parameters:
  • plasma (cantera.Solution) – Cantera plasma object. Passed with clone=False, and stored as self.plasma (not read back via self.phase): self.phase re-wraps the underlying C++ phase fresh on every access, and that fresh wrapper does not carry the Python-side _enable_plasma flag, so plasma-only setters (.Te =) raise ThermoModelMethodError on it even though getters and generic ThermoPhase properties work fine. Storing the constructor argument directly sidesteps this; clone=False guarantees it shares the same underlying state.

  • momentum_transfer_collision_frequencies_list (list of MomentumTransferCollisionFrequencyModel) – List of momentum transfer collision frequency models for each species in the plasma object. Forwarded to MixtureCollisionFrequencies.

  • electric_circuit (PlasmaVoltageCircuit, optional) – Electric circuit object – any of TransmissionLineResistiveCircuit, TransmissionLineRCLoadCircuit, DirectResistiveCircuit, DirectRCLoadCircuit, GeneratorVoltageCircuit (see PlasmaVoltageCircuit). Required (and used to compute the Joule term) only if compute_Te.

  • gap (float, optional) – Gap between the two electrodes, in m. Used to compute the electric field from the plasma voltage. Required only if compute_Te.

  • initial_radius (float, optional) – Initial radius of the plasma, in m – only used to seed self.plasma_radius before the first RHS evaluation (the radius itself is then re-derived each step from the current density and mass, since there is no integrated volume state here). Required only if compute_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 if compute_Te.

  • compute_chemistry (bool, optional) – Independently zero out a term’s RHS contribution without changing the state-vector layout (n_vars stays 2 + nsp regardless). compute_chemistry and compute_Tg default True; compute_Te defaults False (Te stays 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_vars stays 2 + nsp regardless). compute_chemistry and compute_Tg default True; compute_Te defaults False (Te stays 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_vars stays 2 + nsp regardless). compute_chemistry and compute_Tg default True; compute_Te defaults False (Te stays externally prescribed, matching this reactor’s original single-temperature behavior, unless explicitly enabled).

  • single_temperature (bool, optional) – Tie Te to Tg (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 (mixture cp including the electrons, every species’ enthalpy in the chemical term). dTe/dt = dTg/dt keeps the state vector layout unchanged. Cannot be combined with compute_Te. Default False.

  • T_wall (float, optional) – Wall temperature [K]. When given, the conductive wall loss conductive_heat_loss() at the live column radius (from mass, the density and gap, which are then both required) is subtracted from the gas-temperature equation. Default None: adiabatic.

Raises:

ValueError – If compute_Te=True and electric_circuit, gap, initial_radius or mass is not provided; if single_temperature=True and compute_Te=True or compute_Tg=False; or if T_wall is given without mass and gap.

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 by Isomass2TVolumeReactor.

  • 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.

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 (None unless compute_Te).

gap = None#

Gap between the electrodes [m] (None unless compute_Te).

plasma_mass = None#

Mass of the plasma [kg]. Assumed constant (None unless compute_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) and eval(t, LHS, RHS) as two separate steps (update_state always runs first), so by the time replace_eval below runs, self.plasma already reflects this y.

replace_eval(t: float, LHS: numpy.ndarray, RHS: numpy.ndarray) → None#

Compute the RHS of the ODE system.

LHS[:] = 1 throughout: every equation already divides through by its own left-hand-side coefficient (heat capacity, etc.) below, so RHS directly holds dy/dt.

replace_component_name(i: int) → str#

Name the state-vector components for component_name/component_index.

replace_component_index(name: str) → int | None#

Symmetric with replace_component_name.