rizer.models.nrp.isomass_2T_volume_reactor#
Attributes#
Classes#
Two-temperature 0D plasma reactor: constant mass, polytropic volume, NRP circuit. |
Module Contents#
- rizer.models.nrp.isomass_2T_volume_reactor.logger#
- class rizer.models.nrp.isomass_2T_volume_reactor.Isomass2TVolumeReactor(plasma: cantera.Solution, momentum_transfer_collision_frequencies_list: list[rizer.transport.collision_frequency.MomentumTransferCollisionFrequencyModel], mass: float, initial_radius: float, gap: float, electric_circuit: rizer.electrical_model.circuit.base_circuit.PlasmaVoltageCircuit, polytropic_index: float | str, p_ext: float | str, compute_chemistry: bool = True, compute_Te: bool = True, compute_Tg: bool = True, **kwargs)#
Bases:
cantera.ExtensibleReactorTwo-temperature 0D plasma reactor: constant mass, polytropic volume, NRP circuit.
Driven by
cantera.ReactorNet.The following assumptions are made:
Constant mass plasma (no mass flow).
Homogeneous plasma (0D reactor).
Cylindrical geometry between two electrodes.
Polytropic expansion of the plasma.
Pressure relaxation towards atmospheric pressure.
No heat losses to the surroundings.
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.
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.mass (
float) – Mass of the plasma, in kg. Assumed constant.initial_radius (
float) – Initial radius of the plasma, in m. Used to compute the initial volume. Can be updated during the simulation, if the polytropic index is not infinite.gap (
float) – Gap between the two electrodes, in m. Used to compute the volume of the plasma. Assumed constant.electric_circuit (
PlasmaVoltageCircuit) – Electric circuit object – any of TransmissionLineResistiveCircuit, TransmissionLineRCLoadCircuit, DirectResistiveCircuit, DirectRCLoadCircuit, GeneratorVoltageCircuit (seePlasmaVoltageCircuit).polytropic_index (
floatorstr) – Polytropic index of the plasma expansion. If np.inf, the volume is constant. if “gamma”, the process is isentropic. if 1, the temperature is constant. Must not be 0.0 (isobaric) – seepolytropic_volume_rate().p_ext (
floatorstr) – External pressure, in Pa. If “atmospheric” or “atm”, the atmospheric pressure is used.compute_chemistry (
bool, optional) – Independently zero out a term’s RHS contribution without changing the state-vector layout (n_varsstays3 + nspregardless). DefaultTrue(matches the original behavior exactly when left untouched). Volume already has an equivalent toggle viapolytropic_index == np.inf, so there is no separatecompute_volume.compute_Te (
bool, optional) – Independently zero out a term’s RHS contribution without changing the state-vector layout (n_varsstays3 + nspregardless). DefaultTrue(matches the original behavior exactly when left untouched). Volume already has an equivalent toggle viapolytropic_index == np.inf, so there is no separatecompute_volume.compute_Tg (
bool, optional) – Independently zero out a term’s RHS contribution without changing the state-vector layout (n_varsstays3 + nspregardless). DefaultTrue(matches the original behavior exactly when left untouched). Volume already has an equivalent toggle viapolytropic_index == np.inf, so there is no separatecompute_volume.
Notes
Equations solved implies constant mass and homogeneous quantities only. The equations solved are based on [Aurora] and [Mitchner1973].
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\]Balance equation for volume:
For a polytropic process, the volume is related to the pressure by:
\[P V^k = \text{constant}\]Differentiating this equation with respect to time gives the following relation between the volume and pressure derivatives, where the pressure is assumed to relax towards the external pressure with a time scale \(\tau_{rarefaction}\):
\[\frac{dV}{dt} = - \frac{V}{k P} \frac{dP}{dt} = \frac{V}{k P} \frac{P - P_{ext}}{\tau_{rarefaction}}\]where:
\(k\) is the polytropic index,
\(P_{ext}\) is the external pressure, in Pa,
\(\tau_{rarefaction}\) is the rarefaction time scale, in s.
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_{v, e} \frac{dT_e}{dt} = - \dot{\omega_e} M_e c_{v, e} T_e + \vec{j} \cdot \vec{E} - \dot{Q}_{elas} - \dot{Q}_{inel} - \frac{P_e}{V} \frac{dV}{dt}\]where:
\(c_{v, e}\) the specific heat at constant volume of the electrons, in J/kg/K,
\(Y_e\) the mass fraction of electrons,
\(T_e\) the electron temperature, in K,
\(\omega_k\) the production rate of electron \(k\), in kmol/m^3/s,
\(M_e\) the molecular weight of the electron, in kg/kmol,
\(\vec{j}\) the current density, in A/m^2,
\(\vec{E}\) the electric field, in V/m,
\(\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,
\(P_e\) the electron partial pressure, in Pa,
\(V\) the plasma volume, in m^3.
Balance equation for the gas (heavy species) energy:
\[\rho \bar{c_v} \frac{dT_g}{dt} = - \sum_{k \neq e} W_k u_k \dot{\omega_k} + \dot{Q}_{elas} + \dot{Q}_{inel} - \frac{P_g}{V} \frac{dV}{dt}\]where:
\(\bar{c_v}=\sum_{k \neq e} c_{v, k} Y_k\) the mean specific heat at constant volume of heavies species in the gas, in J/kg/K,
\(u_k\) the internal energy of species \(k\), in J/kg,
\(P_g\) the partial pressure of the gas (heavy species), in Pa.
- plasma#
- compute_chemistry = True#
- compute_Te = True#
- compute_Tg = True#
- plasma_mass#
Mass of the plasma [kg]. Assumed constant.
- gap#
Gap between the electrodes [m].
- initial_radius#
Initial radius of the plasma [m].
- initial_base_area#
Initial base area of the plasma [m^2].
- initial_volume#
Initial volume of the plasma [m^3].
- volume#
- electric_circuit#
Electric circuit object.
- polytropic_index#
Polytropic index of the plasma expansion.
If infinite, the volume is constant.
If 1, the temperature is constant.
If equals to the adiabatic index, the process is isentropic.
- plasma_voltage = 0.0#
Stored plasma voltage [V].
- plasma_resistance = 0.0#
Stored plasma resistance [Ohm].
- plasma_radius#
Stored plasma radius [m].
- k#
Stored polytropic index.
- 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].
- 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, V, Y_1, Y_2, ..., Y_K], same layout as the originalConstantMassPlasmaReactorOde. New plumbing – the original driver builty0by hand externally before callingscipy.integrate.ode.set_initial_value; Cantera calls this once, before integration starts, instead.
- replace_update_state(y: numpy.ndarray) None#
Set the state of the plasma object from the state vector
y.Top half of the original
__call__(through “State definition”). Split out because Cantera callsupdate_state(y)andeval(t, LHS, RHS)as two separate steps (update_statealways runs first, confirmed againstReactorNet.cpp), so by the timereplace_evalbelow runs,self.plasma/self.volumealready reflect thisy.
- replace_eval(t: float, LHS: numpy.ndarray, RHS: numpy.ndarray) None#
Compute the RHS of the ODE system.
Bottom half of the original
__call__(from “Geometry evolution” onward).Tg/Te/Vread back fromself.plasma/self.volume(already set byreplace_update_state) rather than re-derived fromy.LHS[:] = 1throughout: every equation already divides through by its own left-hand-side coefficient (heat capacity, etc.) below, exactly as the original did, soRHSdirectly holdsdy/dt.