|
rizer.cantera_ext
C++ Cantera 1-D plasma extension (custom Domain1D models and solvers)
|
Namespaces | |
| namespace | numeric |
| namespace | units |
Classes | |
| class | CanteraThermo |
| ThermoAccessor backed by a PlasmaPhase. More... | |
| class | ChannelCircuit |
| The channel side of the circuit coupling. More... | |
| struct | ChannelHistory |
| struct | ChannelOptions |
| struct | CircuitSample |
| The circuit columns of one recorded frame. More... | |
| class | CollisionModel |
| Composition-resolved electron-heavy momentum-transfer collision model. More... | |
| struct | ColumnOptions |
| Solver configuration. All fields have defaults matching a typical H2 arc. More... | |
| struct | ColumnResult |
| Output of a completed column solve. More... | |
| class | DruyvesteynRate |
| struct | ElectronReactionIndex |
| The per-reaction data the electron pool's inelastic power needs. More... | |
| struct | ElectronTemperatureData |
| Shared data carrying the electron temperature (mirrors Cantera's own TwoTempPlasmaData but only needs Te). More... | |
| class | GammaLawThermo |
| Calorically perfect ideal-gas accessor: one constant \(\gamma_\mathrm{H}\) for the heavy pool, ElectronGamma for the electron pool. More... | |
| struct | HydroStepConfig |
| Geometry, boundary treatment and stepping controls for one call. More... | |
| struct | HydroStepResult |
| Diagnostics from one call, enough to assert NUMERICS.md section "Positivity under a strong rarefaction", case 19, without re-deriving the sub-cycling in the test. More... | |
| struct | HydroStepState |
| Per-node primitive state, advanced in place. More... | |
| class | JanevDissociativeRecombinationC2HyRate |
| struct | NodeState |
| Primitive state at one radial node, as the ghost-state callback sees it and returns it. More... | |
| class | PlasmaCell |
| Shared single-cell two-temperature reacting-plasma RHS (one physics source). More... | |
| struct | PlasmaCellConfig |
| class | PlasmaChannel1D |
| Transient, two-temperature (Te != Tg), finite-rate reacting 1-D radial plasma channel (custom Cantera Domain1D). More... | |
| struct | PlasmaChannelConfig |
| Everything PlasmaChannel1D needs to build itself. More... | |
| class | PlasmaReactor0D |
| Native C++ two-temperature 0D plasma reactor (stateless per-eval evaluator). More... | |
| struct | PlasmaReactor0DConfig |
| class | PrescribedPressureThermo |
| Pressure prescribed as a function of (r, t), every other property delegated to a GammaLawThermo. More... | |
| class | PropertyTable |
| struct | RadialDiffusionCoefficients |
| Everything the diffusion block needs that the grid and the state do not carry: the transport coefficients, the wall ghost, and the per-species properties the two energy terms close with. More... | |
| struct | ReverseTwoTempData |
| Shared data for all reverse-two-temperature-plasma reactions. More... | |
| class | ReverseTwoTemperaturePlasmaRate |
| Reverse of a forward two-temperature-plasma reaction: More... | |
| struct | StateProperties |
| Every state function hydroStep() reads off one primitive state when it builds the conservative variables, returned together by ThermoAccessor::stateProperties(). More... | |
| class | ThermalPlasmaColumn1D |
| Steady radial LTE Elenbaas-Heller arc column (custom Cantera Domain1D). More... | |
| class | ThermoAccessor |
| Equation-of-state and caloric accessor injected into hydroStep(). More... | |
| class | TrialStateError |
| A state the closures cannot evaluate: a temperature outside the fits, an undefined Coulomb logarithm, or a non-finite rate. More... | |
| struct | TwoTemperatureState |
| The two-temperature equation of state at the state currently set on a phase, PHYSICS.md (G6). More... | |
| struct | WallEnergyOutflow |
| Energy leaving through the wall ghost face per unit time, per unit axial length and per radian [W/m] – the convention of V_cell and of HydroStepResult::boundary_total_energy_out. More... | |
Typedefs | |
| using | GhostStateFn |
| Fill the outer ghost cell from a closed-form solution, a fixed end state, or a mirror of the interior. | |
Enumerations | |
| enum class | OuterBc { AmbientGhost , PressureOutlet } |
| Outer-boundary treatment (NUMERICS.md section 7). More... | |
Functions | |
| bool | equationHasElectron (const std::string &equation, const std::string &electron) |
| Test whether the electron participates in a reaction equation as a standalone token. | |
| ElectronReactionIndex | buildElectronReactionIndex (Cantera::Kinetics &kinetics, const std::string &electron, const std::vector< double > &species_h0k, std::size_t n_species, bool reacting) |
| Build the index for one mechanism. | |
| std::shared_ptr< Cantera::Solution > | loadMechanism (const std::string &mech, const std::string &phase) |
| Load a mechanism with rizer's custom rate types registered first. | |
| void | registerPlasmaRates () |
| Register the custom plasma reaction rates with Cantera's ReactionRateFactory. | |
| OuterBc | parseOuterBc (const std::string &mode) |
| Map an outer_bc_mode config string onto the enum. | |
| HydroStepResult | hydroStep (const HydroStepConfig &cfg, HydroStepState &state) |
| Advance state over one Strang half-step of cfg.dt_total. | |
| ChannelHistory | solveChannelTransient (const ChannelOptions &opts) |
| Build a PlasmaChannel1D from opts.cfg, advance it from t=0 to \(t = \mathtt{opts.dt} \cdot \mathtt{opts.n\_steps}\) [s] with the stiff BDF backend, and return the recorded radial history. | |
| void | addRadialDiffusion (const PlasmaChannel1D &domain, Cantera::span< const double > x, const RadialDiffusionCoefficients &c, std::size_t j, double lhsTg, double lhsTe, double &dTg, double &dTe, double *dYdt, double *scratch) |
| Add one node's diffusive contributions to the rates the caller holds. | |
| WallEnergyOutflow | wallEnergyOutflow (const PlasmaChannel1D &domain, Cantera::span< const double > x, const RadialDiffusionCoefficients &c, const double *species_enthalpy) |
| What conduction and species diffusion move through the wall face at the state x. | |
| ColumnResult | solveColumn (double R, double electric_field, double T_wall, const PropertyTable &sigma, const PropertyTable &kappa, const PropertyTable &p_rad, const ColumnOptions &opts) |
| Build, solve, and extract the radial Elenbaas-Heller column. | |
| std::string | significant (double value) |
value to 6 significant digits, for exception messages. | |
| void | throwOutsideTable (const PropertyTable &table, double x, const char *procedure, const std::string &what, const char *unit, const char *remedy) |
Throw the TrialStateError for x outside table. | |
| double | evalAtState (const PropertyTable &table, double x, const char *procedure, const char *what, const char *unit, const char *remedy) |
Value of table at x, refused outside its tabulated range. | |
| double | monatomicElectronCv (double electron_molecular_weight) |
| Electron specific heat at constant volume, per kg of ELECTRONS, \(c_{v,\mathrm{e}}=\tfrac32 R/W_\mathrm{e}\). | |
| TwoTemperatureState | readTwoTemperatureState (const Cantera::PlasmaPhase &phase) |
| Read the two-temperature EOS back from a phase whose state is set. | |
Variables | |
| constexpr double | TemperatureFloor = 200.0 |
| Lower limit of the mechanism's NASA polynomials [K]. | |
| constexpr double | TemperatureCeiling = 1.0e5 |
| Upper limit of the physically meaningful range [K]. | |
| constexpr double | GasConstant = units::R_kmol |
| Universal gas constant [J/kmol/K] and Boltzmann's constant [J/K], from units.h rather than Cantera's CODATA-2018 values, to match the Python reactor reference this extension is a port of. | |
| constexpr double | Boltzmann = units::k_b |
| constexpr double | ElectronGamma = 5.0 / 3.0 |
| Ratio of specific heats of the electron pool [-]. | |
| using rizer::GhostStateFn |
Fill the outer ghost cell from a closed-form solution, a fixed end state, or a mirror of the interior.
TEST-ONLY, unset in production, and overriding outer_bc_mode when set.
It takes the adjacent interior state as well as the ghost radius and the time because the validation cases need three different things from it and only the first is a closed-form field (NUMERICS.md section 7).
r_ghost is the GHOST CELL's own node radius – the adjacent interior node reflected across the boundary – and not the face radius. A closed-form field sampled at the face would land half a cell inside the ghost it fills, which is an O(1) error in the boundary cell that refinement does not remove (NUMERICS.md section 7.6). hydroStep() hands the same radius to the thermo accessor for that ghost, so a prescribed pressure and a prescribed state are sampled at one consistent place.
is_inner_face distinguishes the two ends. NUMERICS.md section 7 gives the signature as (r, t, W_interior), which is enough in cylindrical mode where the inner face has zero area and is never consulted – but the planar entry point of section "Full system, planar - Sod shock tube" has two real boundaries at the same face radius (r_face = 1 everywhere), and cases 14 and 15 need a different end state at each. The inner face is consulted only when r_face[0] > 0, i.e. exactly when it has nonzero area.
Definition at line 89 of file BoundaryConditions.h.
|
strong |
Outer-boundary treatment (NUMERICS.md section 7).
Two values only: the closed-form boundary the validation cases need arrives through HydroStepConfig::ghost_state, deliberately not as a third enum value a production config could select.
Definition at line 37 of file BoundaryConditions.h.
| void rizer::addRadialDiffusion | ( | const PlasmaChannel1D & | domain, |
| Cantera::span< const double > | x, | ||
| const RadialDiffusionCoefficients & | c, | ||
| std::size_t | j, | ||
| double | lhsTg, | ||
| double | lhsTe, | ||
| double & | dTg, | ||
| double & | dTe, | ||
| double * | dYdt, | ||
| double * | scratch ) |
Add one node's diffusive contributions to the rates the caller holds.
Reads the state at \(j-1\), \(j\) and \(j+1\), so it reaches outside the [jmin, jmax] window its caller loops over – the stencil is what makes the Jacobian banded, and the neighbours are read, never written.
| [in] | domain | Grid and state layout: z(), faceRadius(), faceSpacing(), index() and the per-node density |
| [in] | x | This domain's state vector |
| [in] | c | Coefficients and ghosts, see above |
| [in] | j | Node to evaluate [-] |
| [in] | lhsTg | Heavy-pool capacitance [J/m^3/K] |
| [in] | lhsTe | Electron capacitance [J/m^3/K] |
| [in,out] | dTg | Heavy-pool rate, added to [K/s] |
| [in,out] | dTe | Electron rate, added to [K/s] |
| [in,out] | dYdt | Species rates, added to [1/s], length K |
| [out] | scratch | Caller-owned workspace, length K; holds \(\nabla\cdot(\rho D\nabla Y_s)\) on return |
Definition at line 149 of file RadialDiffusion.cpp.
| ElectronReactionIndex rizer::buildElectronReactionIndex | ( | Cantera::Kinetics & | kinetics, |
| const std::string & | electron, | ||
| const std::vector< double > & | species_h0k, | ||
| std::size_t | n_species, | ||
| bool | reacting ) |
Build the index for one mechanism.
species_h0k is required only when the mechanism has an electron-impact reaction and chemistry is live: without it the inelastic power would be silently zero, which is why this raises rather than defaulting.
| [in] | kinetics | The mechanism's kinetics |
| [in] | electron | Electron species name |
| [in] | species_h0k | Per-species formation enthalpy at 0 K [J/kmol], length nSpecies(), or empty when reacting is false |
| [in] | n_species | Expected length of species_h0k [-] |
| [in] | reacting | Whether finite-rate chemistry is live [-] |
| std::invalid_argument | if species_h0k is missing or the wrong length while an electron-impact reaction is live |
Definition at line 36 of file ElectronReactions.cpp.
| bool rizer::equationHasElectron | ( | const std::string & | equation, |
| const std::string & | electron ) |
Test whether the electron participates in a reaction equation as a standalone token.
Replaces the reaction-arrow and stoichiometric-plus characters +, =, <, > with spaces and looks for the electron as a whole token, which is what makes a spectator electron count: Cantera cancels it from the stoichiometry, but it is still an electron-impact reaction.
| [in] | equation | Reaction equation, e.g. "CH4 + e- => CH3 + H + e-" |
| [in] | electron | Electron species name as the mechanism spells it |
Definition at line 17 of file ElectronReactions.cpp.
|
inline |
Value of table at x, refused outside its tabulated range.
| [in] | table | Table to evaluate, not empty |
| [in] | x | State variable to evaluate at [units of the abscissa] |
| [in] | procedure | Function evaluating it, for the exception |
| [in] | what | Name of the tabulated property, for the exception |
| [in] | unit | Unit of the abscissa, for the exception |
| [in] | remedy | What the caller can change to cover the state |
| TrialStateError | if x is outside [table.first(), table.last()] |
Definition at line 50 of file TableLookup.h.
| HydroStepResult rizer::hydroStep | ( | const HydroStepConfig & | cfg, |
| HydroStepState & | state ) |
Advance state over one Strang half-step of cfg.dt_total.
Internally, PER CFL SUB-CYCLE and not once per call: primitive to conservative, Rusanov fluxes plus the cylindrical geometric momentum source, forward Euler, then conservative back to primitive through the energy inversion of NUMERICS.md section 8. The round trip sits inside the sub-cycle loop because every sub-cycle's fluxes and sources need a current p; hoisting it out would freeze the pressure gradient driving the rarefaction, which is the one quantity an explicit acoustic step cannot hold fixed.
| [in] | cfg | Geometry, boundary treatment, stepping controls and the injected thermo accessor |
| [in,out] | state | Primitive per-node state; read as the initial condition and overwritten with the advanced one |
| std::invalid_argument | if the array lengths disagree, thermo is null, or the boundary is not subsonic outflow where OuterBc::PressureOutlet assumes it |
| std::runtime_error | if a sub-cycle leaves a node with a non-positive density, a non-positive electron density while an electron species is present, or non-finite |
Definition at line 138 of file HydroStep.cpp.
| std::shared_ptr< Cantera::Solution > rizer::loadMechanism | ( | const std::string & | mech, |
| const std::string & | phase ) |
Load a mechanism with rizer's custom rate types registered first.
The registration has to happen before the YAML is parsed, or a mechanism naming one of those rates fails to load. Every model in this extension needs the same two calls in the same order, so they live here rather than once per model.
Definition at line 88 of file PlasmaRates.cpp.
|
inline |
Electron specific heat at constant volume, per kg of ELECTRONS, \(c_{v,\mathrm{e}}=\tfrac32 R/W_\mathrm{e}\).
Analytic, not a thermo fit: a free electron gas is monatomic whatever the heavy pool is made of, which is what lets NUMERICS.md section 8 invert the electron temperature in closed form.
This is the closed form itself. ThermoAccessor::electronCv() is the interface a caller holding a state reaches for, and every implementation of it ends up here; the two carry different names so that a call inside one of those implementations means what it reads as.
| [in] | electron_molecular_weight | \(W_\mathrm{e}\) [kg/kmol] |
Definition at line 64 of file PlasmaState.h.
| OuterBc rizer::parseOuterBc | ( | const std::string & | mode | ) |
Map an outer_bc_mode config string onto the enum.
Lives beside the enum rather than in a caller so that whoever takes the config string can reject an unknown one before any work is done, rather than at the first sub-step that happens to need it.
| mode | Config value, "ambient_ghost" or "pressure_outlet" |
| std::invalid_argument | on any other value |
Definition at line 13 of file BoundaryConditions.cpp.
|
inline |
Read the two-temperature EOS back from a phase whose state is set.
| [in] | phase | Phase to read; its state is not modified |
Definition at line 84 of file PlasmaState.h.
| void rizer::registerPlasmaRates | ( | ) |
Register the custom plasma reaction rates with Cantera's ReactionRateFactory.
Idempotent (factory reg replaces silently); safe to call before every newSolution. Call this before loading any mechanism that uses janev-dissociative-recombination-C2Hy, Druyvesteyn, or reverse-two-temperature-plasma.
Definition at line 95 of file PlasmaRates.cpp.
|
inline |
| ChannelHistory rizer::solveChannelTransient | ( | const ChannelOptions & | opts | ) |
Build a PlasmaChannel1D from opts.cfg, advance it from t=0 to \(t = \mathtt{opts.dt} \cdot \mathtt{opts.n\_steps}\) [s] with the stiff BDF backend, and return the recorded radial history.
Throws Cantera::CanteraError if the integrator fails to converge (see solveChannelTransient's own comments for how a CVODE failure is decoded before being re-raised).
| opts | Mechanism/grid/transport config, dt/n_steps/record_every/ and loglevel |
Applied field E(t) [V/m]: the circuit's when one is closed, the prescribed constant or schedule otherwise.
Appends the circuit columns for the frame record has just appended.
< Start in the global state [-]
< Components owned [-]
The one node this system owns, or Cantera::npos when it owns the whole domain. Only the error decoder needs it: a single-node system reports component indices relative to itself, so there is no node number in them to recover.
Definition at line 480 of file PlasmaChannelSolver.cpp.
| ColumnResult rizer::solveColumn | ( | double | R, |
| double | electric_field, | ||
| double | T_wall, | ||
| const PropertyTable & | sigma, | ||
| const PropertyTable & | kappa, | ||
| const PropertyTable & | p_rad, | ||
| const ColumnOptions & | opts ) |
Build, solve, and extract the radial Elenbaas-Heller column.
| R | Outer wall radius [m] |
| electric_field | Axial E field [V/m], held fixed for this solve |
| T_wall | Wall (boundary) temperature [K] at r=R |
| sigma | Electrical conductivity table \(\sigma(T)\) [S/m] vs. T [K] |
| kappa | Thermal conductivity table \(\kappa(T)\) [W/m/K] vs. T [K] |
| p_rad | Volumetric radiative loss table \(P_\text{rad}(T)\) [W/m^3] vs. T [K] |
| opts | Solver configuration (grid, refinement, initial guess, etc.) |
| std::invalid_argument | if only one of opts.init_r / opts.init_T is given, or they differ in length, or have fewer than 2 points. |
| std::runtime_error | if the converged temperature is outside the sigma, kappa or p_rad table. |
Definition at line 22 of file PlasmaColumnSolver.cpp.
|
inline |
Throw the TrialStateError for x outside table.
| [in] | table | Table that does not cover x, not empty |
| [in] | x | State variable it was asked for [units of the abscissa] |
| [in] | procedure | Function evaluating it, for the exception |
| [in] | what | Name of the tabulated property, for the exception |
| [in] | unit | Unit of the abscissa, for the exception |
| [in] | remedy | What the caller can change to cover the state |
| TrialStateError | always |
Definition at line 30 of file TableLookup.h.
| WallEnergyOutflow rizer::wallEnergyOutflow | ( | const PlasmaChannel1D & | domain, |
| Cantera::span< const double > | x, | ||
| const RadialDiffusionCoefficients & | c, | ||
| const double * | species_enthalpy ) |
What conduction and species diffusion move through the wall face at the state x.
The parabolic terms are flux differences, so summed over every cell their interior faces cancel and the wall face is all that is left: this is the term an energy budget over the domain has to carry for them, the way it carries boundary_total_energy_out for the hydro sub-step.
The diffusion term charges each species' face mass flux at species_enthalpy, which is what the Fickian and compressibility terms deposit in the outermost cell between them. The enthalpy-diffusion term is a product of centred gradients, not a face flux, so it has no wall term here; its departure from conservation is a second-order interior remainder, not a boundary flux.
| [in] | domain | Grid and state layout |
| [in] | x | This domain's state vector |
| [in] | c | Coefficients and ghosts, as addRadialDiffusion() |
| [in] | species_enthalpy | Mass-basis enthalpy of each species at the outermost node [J/kg], length K; see PlasmaCell::speciesEnthalpies |
Definition at line 273 of file RadialDiffusion.cpp.
|
constexpr |
Definition at line 49 of file PlasmaState.h.
|
constexpr |
Ratio of specific heats of the electron pool [-].
Analytic, not a thermo fit: a free electron gas is monatomic, so \(\gamma_\mathrm{e}=5/3\) whatever the heavy pool is made of. The frozen sound speed of PHYSICS.md appendix A.4 needs it separately from the heavy pool's gamma because the electron enters the pressure at \(X_\mathrm{e}\) while it enters a mass-weighted gamma at \(Y_\mathrm{e}\), four orders smaller.
Definition at line 22 of file ThermoAccessor.h.
|
constexpr |
Universal gas constant [J/kmol/K] and Boltzmann's constant [J/K], from units.h rather than Cantera's CODATA-2018 values, to match the Python reactor reference this extension is a port of.
Definition at line 48 of file PlasmaState.h.
|
constexpr |
Upper limit of the physically meaningful range [K].
Above it the NASA polynomials are extrapolating and a state is far likelier to be a diverged iterate than a real one: the hottest measured point in this repo is the P4 case's 22.5 kK electron temperature (NUMERICS.md section "Validation ladder"), so this leaves a factor of four. The extrapolation is not benign: the CH4 mechanism's C+, C++ and C+++ fits give cp/R < 1, a negative c_v, from 1.52e5 K.
Definition at line 43 of file PlasmaState.h.
|
constexpr |
Lower limit of the mechanism's NASA polynomials [K].
Cantera has no meaningful thermo below it and an integrator can undershoot into it.
Definition at line 34 of file PlasmaState.h.