rizer.cantera_ext
C++ Cantera 1-D plasma extension (custom Domain1D models and solvers)
Loading...
Searching...
No Matches
rizer Namespace Reference

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 [-].

Typedef Documentation

◆ GhostStateFn

Initial value:
std::function<NodeState(
double r_ghost, double t, bool is_inner_face, const NodeState &interior)>
Primitive state at one radial node, as the ghost-state callback sees it and returns it.

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.

Enumeration Type Documentation

◆ OuterBc

enum class rizer::OuterBc
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.

Enumerator
AmbientGhost 

Fix rho, u_r, p, T and Y_s to ambient.

The DEFAULT, and the accurate choice whenever R_max is placed beyond the front so that the far field genuinely IS the ambient state: the characteristic count says only one quantity MAY be imposed when the others are unknown, and imposing values that happen to be the true ones costs nothing. It both transmits an outgoing wave and anchors the domain to ambient, which nothing else here does (NUMERICS.md sections 7 and 11.8).

PressureOutlet 

Hold p = p_amb at the boundary face, extrapolate u_r/Tg/Te/Y_s with zero gradient, and close rho from the equation of state at that p_amb.

Exactly one quantity imposed – and REFLECTING for all that, because pinning p is a pressure-release surface. Measured at 0.33 to 0.62 of an incident wave against AmbientGhost's 0.013 to 0.024, and it rings instead of settling. Kept as a documented comparison point, not as a treatment to reach for.

Definition at line 37 of file BoundaryConditions.h.

Function Documentation

◆ addRadialDiffusion()

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.

Parameters
[in]domainGrid and state layout: z(), faceRadius(), faceSpacing(), index() and the per-node density
[in]xThis domain's state vector
[in]cCoefficients and ghosts, see above
[in]jNode to evaluate [-]
[in]lhsTgHeavy-pool capacitance [J/m^3/K]
[in]lhsTeElectron capacitance [J/m^3/K]
[in,out]dTgHeavy-pool rate, added to [K/s]
[in,out]dTeElectron rate, added to [K/s]
[in,out]dYdtSpecies rates, added to [1/s], length K
[out]scratchCaller-owned workspace, length K; holds \(\nabla\cdot(\rho D\nabla Y_s)\) on return

Definition at line 149 of file RadialDiffusion.cpp.

◆ buildElectronReactionIndex()

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.

Parameters
[in]kineticsThe mechanism's kinetics
[in]electronElectron species name
[in]species_h0kPer-species formation enthalpy at 0 K [J/kmol], length nSpecies(), or empty when reacting is false
[in]n_speciesExpected length of species_h0k [-]
[in]reactingWhether finite-rate chemistry is live [-]
Returns
The index above
Exceptions
std::invalid_argumentif species_h0k is missing or the wrong length while an electron-impact reaction is live

Definition at line 36 of file ElectronReactions.cpp.

◆ equationHasElectron()

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.

Parameters
[in]equationReaction equation, e.g. "CH4 + e- => CH3 + H + e-"
[in]electronElectron species name as the mechanism spells it
Returns
True when the electron appears as its own token

Definition at line 17 of file ElectronReactions.cpp.

◆ evalAtState()

double rizer::evalAtState ( const PropertyTable & table,
double x,
const char * procedure,
const char * what,
const char * unit,
const char * remedy )
inline

Value of table at x, refused outside its tabulated range.

Parameters
[in]tableTable to evaluate, not empty
[in]xState variable to evaluate at [units of the abscissa]
[in]procedureFunction evaluating it, for the exception
[in]whatName of the tabulated property, for the exception
[in]unitUnit of the abscissa, for the exception
[in]remedyWhat the caller can change to cover the state
Returns
The interpolated value
Exceptions
TrialStateErrorif x is outside [table.first(), table.last()]

Definition at line 50 of file TableLookup.h.

◆ hydroStep()

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.

Parameters
[in]cfgGeometry, boundary treatment, stepping controls and the injected thermo accessor
[in,out]statePrimitive per-node state; read as the initial condition and overwritten with the advanced one
Returns
Sub-cycle count, CFL bound and the positivity minima
Exceptions
std::invalid_argumentif the array lengths disagree, thermo is null, or the boundary is not subsonic outflow where OuterBc::PressureOutlet assumes it
std::runtime_errorif 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.

◆ loadMechanism()

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.

Parameters
[in]mechCantera mechanism (YAML) path
[in]phasePhase name within mech
Returns
The loaded Solution

Definition at line 88 of file PlasmaRates.cpp.

◆ monatomicElectronCv()

double rizer::monatomicElectronCv ( double electron_molecular_weight)
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.

Parameters
[in]electron_molecular_weight\(W_\mathrm{e}\) [kg/kmol]
Returns
Electron \(c_v\) [J/kg of electrons/K]

Definition at line 64 of file PlasmaState.h.

◆ parseOuterBc()

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.

Parameters
modeConfig value, "ambient_ghost" or "pressure_outlet"
Exceptions
std::invalid_argumenton any other value

Definition at line 13 of file BoundaryConditions.cpp.

◆ readTwoTemperatureState()

TwoTemperatureState rizer::readTwoTemperatureState ( const Cantera::PlasmaPhase & phase)
inline

Read the two-temperature EOS back from a phase whose state is set.

Parameters
[in]phasePhase to read; its state is not modified
Returns
The quantities above, at that state

Definition at line 84 of file PlasmaState.h.

◆ registerPlasmaRates()

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.

◆ significant()

std::string rizer::significant ( double value)
inline

value to 6 significant digits, for exception messages.

std::to_string prints six fixed decimals, which turns a nanosecond time or a sub-mm radius into 0.000000.

Parameters
[in]valueNumber to format
Returns
Its text

Definition at line 18 of file Format.h.

◆ solveChannelTransient()

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

Parameters
optsMechanism/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.

◆ solveColumn()

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.

Parameters
ROuter wall radius [m]
electric_fieldAxial E field [V/m], held fixed for this solve
T_wallWall (boundary) temperature [K] at r=R
sigmaElectrical conductivity table \(\sigma(T)\) [S/m] vs. T [K]
kappaThermal conductivity table \(\kappa(T)\) [W/m/K] vs. T [K]
p_radVolumetric radiative loss table \(P_\text{rad}(T)\) [W/m^3] vs. T [K]
optsSolver configuration (grid, refinement, initial guess, etc.)
Exceptions
std::invalid_argumentif only one of opts.init_r / opts.init_T is given, or they differ in length, or have fewer than 2 points.
std::runtime_errorif the converged temperature is outside the sigma, kappa or p_rad table.

Definition at line 22 of file PlasmaColumnSolver.cpp.

◆ throwOutsideTable()

void rizer::throwOutsideTable ( const PropertyTable & table,
double x,
const char * procedure,
const std::string & what,
const char * unit,
const char * remedy )
inline

Throw the TrialStateError for x outside table.

Parameters
[in]tableTable that does not cover x, not empty
[in]xState variable it was asked for [units of the abscissa]
[in]procedureFunction evaluating it, for the exception
[in]whatName of the tabulated property, for the exception
[in]unitUnit of the abscissa, for the exception
[in]remedyWhat the caller can change to cover the state
Exceptions
TrialStateErroralways

Definition at line 30 of file TableLookup.h.

◆ wallEnergyOutflow()

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.

Parameters
[in]domainGrid and state layout
[in]xThis domain's state vector
[in]cCoefficients and ghosts, as addRadialDiffusion()
[in]species_enthalpyMass-basis enthalpy of each species at the outermost node [J/kg], length K; see PlasmaCell::speciesEnthalpies
Returns
The two energy outflows [W/m] and the species mass outflow

Definition at line 273 of file RadialDiffusion.cpp.

Variable Documentation

◆ Boltzmann

double rizer::Boltzmann = units::k_b
constexpr

Definition at line 49 of file PlasmaState.h.

◆ ElectronGamma

double rizer::ElectronGamma = 5.0 / 3.0
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.

◆ GasConstant

double rizer::GasConstant = units::R_kmol
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.

◆ TemperatureCeiling

double rizer::TemperatureCeiling = 1.0e5
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.

◆ TemperatureFloor

double rizer::TemperatureFloor = 200.0
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.