|
rizer.cantera_ext
C++ Cantera 1-D plasma extension (custom Domain1D models and solvers)
|
Transient, two-temperature (Te != Tg), finite-rate reacting 1-D radial plasma channel (custom Cantera Domain1D). More...
#include <PlasmaChannel1D.h>
Public Member Functions | |
| PlasmaChannel1D (const PlasmaChannelConfig &cfg) | |
| Build the domain (mesh, thermo/kinetics, property tables) from cfg. | |
| std::string | domainType () const override |
| void | eval (std::size_t jg, Cantera::span< const double > xg, Cantera::span< double > rg, Cantera::span< int > maskg, double rdt) override |
| Residual + transient-mask assembly at global point jg (or every point if jg == Cantera::npos); see the .cpp for the finite-volume stencil. | |
| std::string | componentName (std::size_t n) const override |
| Component n -> name ("Tg", "Te", or a species name). | |
| std::size_t | componentIndex (const std::string &name, bool checkAlias=true) const override |
| Component name -> index (inverse of componentName()); throws if unknown. | |
| bool | hasComponent (const std::string &name, bool checkAlias=true) const override |
| Whether name is "Tg", "Te", or a species of this domain's mechanism. | |
| void | getValues (const std::string &component, Cantera::span< double > values) const override |
| Radial profile of one component, read from the domain's own solution buffer (units match that component: [K] for Tg/Te, [-] for a species). | |
| double | initialValue (std::size_t n, std::size_t j) override |
| Initial value of component n at grid point j ([K] for Tg/Te, [-] for a species mass fraction); seeds the first solve. | |
| void | setElectricField (double electricField) |
| Applied electric field E [V/m] used by the next eval() call. | |
| std::size_t | nSpecies () const |
| Number of species K [-] in this domain's mechanism. | |
| const PropertyTable & | heavyConductivity () const |
| The transport tables and per-species properties the diffusion operator reads. | |
| const PropertyTable & | electronConductivity () const |
| const std::vector< double > & | molecularWeights () const |
| const std::vector< double > & | speciesCp () const |
| Per-species \(c_p\) [J/kg/K], length nSpecies(), at the state the cell was last evaluated at. | |
| void | updateSpeciesCp (double Tg, double Te, const double *Y, double rho) const |
| Refresh speciesCp() at one node's state. | |
| OuterBc | outerBcMode () const |
| Outer boundary treatment for the hydro sub-step [-]. | |
| bool | hasTransport () const |
| Whether any conduction or diffusion term is enabled [-]. | |
| bool | hydrodynamics () const |
| Whether the radial hydrodynamic sub-step is active [-]. | |
| std::size_t | electronIndex () const |
| Species index of the electron [-]; the constructor rejects a mechanism without one, so this is always a valid index. | |
| const std::vector< double > & | density () const |
| Per-node mass density [kg/m^3], length nPoints(). | |
| const std::vector< double > & | velocity () const |
| Per-node radial velocity [m/s], length nPoints(). | |
| void | setHydroState (const std::vector< double > &rho, const std::vector< double > &u_r) |
| Replace the fields the hydro sub-step owns. | |
| void | nodeDiagnostics (double Tg, double Te, const double *Y, std::size_t j, double &pressure, double &electron_density) const |
| Total pressure [Pa] and electron number density [1/m^3] for a node state, both from the two-temperature equation of state the source terms themselves run on: n_e is X_e * P / (k_B * Tmean), the same value PlasmaCell::sourceTerms() sees. | |
| void | nodeRates (std::size_t j, double Tg, double Te, const double *Y, double electric_field, double *ydot) const |
| One node's time derivatives with no transport stencil: exactly what eval() computes for node j when hasTransport() is false, written into ydot in this domain's own component order (Tg, Te, then Y_k). | |
| double | nodeElectricalConductivity (double Tg, double Te, const double *Y, std::size_t j) const |
| Electrical conductivity [S/m] at one node's state, from the same composition-resolved closure the source terms run on. | |
| void | wallEnergyOutflow (Cantera::span< const double > x, double &conduction_out, double &diffusion_out, std::vector< double > &species_mass_out) const |
| Energy conduction and species diffusion move out through the wall ghost face at the state x, per unit axial length and per radian [W/m]; positive is outward. | |
| const std::vector< double > & | ambientMassFractions () const |
| Ambient mass fractions [-], length nSpecies(): the composition outside the domain, which the hydro sub-step uses as its inflow. | |
| double | faceRadius (std::size_t j) const |
| Radius of face j, the single definition of where a cell boundary sits (NUMERICS.md section 2). | |
| double | faceSpacing (std::size_t j) const |
| Node-to-node spacing across face j [m], the distance a gradient at that face is taken over. | |
| void | setEvaluatorPoolSize (std::size_t slots) |
| Give nodeRates() slots independent evaluators so that many threads can call it at once. | |
| std::size_t | evaluatorPoolSize () const |
| Number of independent evaluators nodeRates() can be called on at once [-]; 1 unless setEvaluatorPoolSize() raised it. | |
| Public Member Functions inherited from Cantera::Domain1D | |
| size_t | domainIndex () |
| virtual bool | isConnector () |
| virtual void | setTransportModel (const string &model) |
| const OneDim & | container () const |
| void | setContainer (OneDim *c, size_t index) |
| void | setBandwidth (int bw=-1) |
| size_t | bandwidth () |
| virtual void | init () |
| virtual void | resetBadValues (span< double > x) |
| virtual void | resize (size_t nv, size_t np) |
| Refiner & | refiner () |
| size_t | nComponents () const |
| size_t | nPoints () const |
| virtual string | componentName (size_t n) const |
| void | setComponentName (size_t n, const string &name) |
| virtual size_t | componentIndex (const string &name, bool checkAlias=true) const |
| virtual bool | hasComponent (const string &name, bool checkAlias=true) const |
| virtual void | updateState (size_t loc) |
| void | setBounds (size_t n, double lower, double upper) |
| void | setTransientTolerances (double rtol, double atol, size_t n=npos) |
| void | setSteadyTolerances (double rtol, double atol, size_t n=npos) |
| double | rtol (size_t n) |
| double | atol (size_t n) |
| double | steady_rtol (size_t n) |
| double | steady_atol (size_t n) |
| double | transient_rtol (size_t n) |
| double | transient_atol (size_t n) |
| double | upperBound (size_t n) const |
| double | lowerBound (size_t n) const |
| void | setRefineCriteria (double ratio=10.0, double slope=0.8, double curve=0.8, double prune=-0.1) |
| vector< double > | getRefineCriteria () |
| void | initTimeInteg (double dt, span< const double > x0) |
| void | setSteadyMode () |
| bool | steady () |
| bool | transient () |
| void | needJacUpdate () |
| virtual void | eval (size_t j, span< const double > x, span< double > r, span< int > mask, double rdt=0.0) |
| size_t | index (size_t n, size_t j) const |
| virtual double | value (const string &component) const |
| virtual void | setValue (const string &component, double value) |
| vector< double > | values (const string &component) const |
| virtual void | getValues (const string &component, span< double > values) const |
| virtual void | setValues (const string &component, span< const double > values) |
| vector< double > | residuals (const string &component) const |
| virtual void | getResiduals (const string &component, span< double > values) const |
| virtual void | setProfile (const string &component, span< const double > pos, span< const double > values) |
| virtual void | setFlatProfile (const string &component, double value) |
| virtual shared_ptr< SolutionArray > | toArray (bool normalize=false) |
| virtual void | fromArray (const shared_ptr< SolutionArray > &arr) |
| string | info (const vector< string > &keys, int rows=10, int width=80) |
| string | _info (int rows=10, int width=80) |
| shared_ptr< Solution > | phase () const |
| size_t | size () const |
| void | locate () |
| virtual size_t | loc (size_t j=0) const |
| size_t | firstPoint () const |
| size_t | lastPoint () const |
| void | linkLeft (Domain1D *left) |
| void | linkRight (Domain1D *right) |
| void | append (Domain1D *right) |
| Domain1D * | left () const |
| Domain1D * | right () const |
| double | prevSoln (size_t n, size_t j) const |
| void | setID (const string &s) |
| string | id () const |
| virtual void | show (span< const double > x) |
| double | z (size_t jlocal) const |
| double | zmin () const |
| double | zmax () const |
| span< double > | grid () |
| span< const double > | grid () const |
| virtual void | setupGrid (span< const double > z) |
| void | setupUniformGrid (size_t points, double length, double start=0.) |
| virtual void | _getInitialSoln (span< double > x) |
| virtual double | initialValue (size_t n, size_t j) |
| virtual void | _finalize (span< const double > x) |
| void | forceFullUpdate (bool update) |
| void | setData (shared_ptr< vector< double > > &data) |
Additional Inherited Members | |
| Protected Member Functions inherited from Cantera::Domain1D | |
| Domain1D (size_t nv=1, size_t points=1, double time=0.0) | |
| virtual void | _setKinetics (shared_ptr< Kinetics > kin) |
| virtual void | _setTransport (shared_ptr< Transport > trans) |
| virtual AnyMap | getMeta () const |
| virtual void | setMeta (const AnyMap &meta) |
| Protected Attributes inherited from Cantera::Domain1D | |
| double | m_press |
| shared_ptr< vector< double > > | m_state |
| double | m_rdt |
| size_t | m_nv |
| size_t | m_points |
| vector< double > | m_slast |
| vector< double > | m_max |
| vector< double > | m_min |
| vector< double > | m_rtol_ss |
| vector< double > | m_rtol_ts |
| vector< double > | m_atol_ss |
| vector< double > | m_atol_ts |
| vector< double > | m_z |
| OneDim * | m_container |
| size_t | m_index |
| size_t | m_iloc |
| size_t | m_jstart |
| Domain1D * | m_left |
| Domain1D * | m_right |
| string | m_id |
| unique_ptr< Refiner > | m_refiner |
| vector< string > | m_name |
| int | m_bw |
| bool | m_force_full_update |
| shared_ptr< Solution > | m_solution |
Transient, two-temperature (Te != Tg), finite-rate reacting 1-D radial plasma channel (custom Cantera Domain1D).
PlasmaChannel1D: a transient, two-temperature (Te != Tg), finite-rate reacting plasma channel as a custom Cantera Domain1D on a radial grid.
Thermo/kinetics-backed (holds a Cantera Solution whose ThermoPhase is a PlasmaPhase). Per radial node it evaluates finite-rate chemistry + two two-temperature energy balances + radial transport (conduction/diffusion), mirroring rizer's 0D Isomass2TVolumeReactor generalised to 1D radial.
Components per radial node (nv = 2 + K): 0 : Tg gas/heavy temperature [K] 1 : Te electron temperature [K] 2 .. 2+K-1 : Y_k species mass fractions
Equations (finite-volume, cylindrical; specified in PHYSICS.md sections 2 to 6 and NUMERICS.md sections 2 to 3):
Species mass fraction:
\[ \rho \frac{dY_k}{dt} = \frac{1}{r} \frac{d}{dr}\!\left(r \rho D \frac{dY_k}{dr}\right) + W_k \dot\omega_k \]
Gas (heavy-species) energy:
\[ \rho \bar{c}_{v,h} \frac{dT_g}{dt} = \frac{1}{r} \frac{d}{dr}\!\left(r \kappa \frac{dT_g}{dr}\right) - P_\text{chem,H} + Q_\text{el} + Q_\text{inel} + \rho D R T_g \sum_{k \neq e} \frac{1}{W_k} \frac{1}{r} \frac{d}{dr}\!\left(r \frac{dY_k}{dr}\right) + \rho D \frac{dT_g}{dr} \sum_{k \neq e} c_{p,k} \frac{dY_k}{dr} \]
Electron energy:
\[ \frac{3}{2} n_e k_B \frac{dT_e}{dt} = \frac{1}{r} \frac{d}{dr}\!\left(r \kappa_e \frac{dT_e}{dr}\right) + \sigma E^2 - P_{\text{chem},e} - Q_\text{el} - Q_\text{inel} + \rho D \frac{R T_e}{W_e} \frac{1}{r} \frac{d}{dr}\!\left(r \frac{dY_e}{dr}\right) + \rho D c_{p,e} \frac{dY_e}{dr} \frac{dT_e}{dr} \]
The last two terms in each equation are the species-diffusion COMPRESSIBILITY term (from expanding \(DP/Dt\) for the two-temperature ideal-gas EOS under Fick's law) and the ENTHALPY-DIFFUSION (species heat transport) term (the Fickian reduction of the full multicomponent energy equation's \(-\nabla\!\cdot\!\left(\sum_k h_k \vec\jmath_k\right)\) term); both vanish when D_species == 0 or the composition is uniform. See the species-diffusion block in eval() and PHYSICS.md section 5.
BCs: r=0 symmetry (zero-area axis face); r=R wall Dirichlet to ambient. Transport is OFF when all conductivities/diffusivity are zero (P0 limit: each node is an independent 0D reactor).
ASSUMPTIONS AND DOMAIN OF VALIDITY (mirrored in the Python wrapper PlasmaChannel, which is what Sphinx renders – keep the two in sync):
Definition at line 277 of file PlasmaChannel1D.h.
|
explicit |
Build the domain (mesh, thermo/kinetics, property tables) from cfg.
Throws std::invalid_argument if cfg is inconsistent (see the .cpp).
Definition at line 30 of file PlasmaChannel1D.cpp.
|
inline |
Ambient mass fractions [-], length nSpecies(): the composition outside the domain, which the hydro sub-step uses as its inflow.
Definition at line 462 of file PlasmaChannel1D.h.
|
override |
Component name -> index (inverse of componentName()); throws if unknown.
| name | Component name: "Tg", "Te", or a species name |
| checkAlias | Unused (this domain has no aliases) |
Definition at line 580 of file PlasmaChannel1D.cpp.
|
override |
Component n -> name ("Tg", "Te", or a species name).
Definition at line 568 of file PlasmaChannel1D.cpp.
|
inline |
Per-node mass density [kg/m^3], length nPoints().
Definition at line 382 of file PlasmaChannel1D.h.
|
inlineoverridevirtual |
Reimplemented from Cantera::Domain1D.
Definition at line 284 of file PlasmaChannel1D.h.
|
inline |
Definition at line 341 of file PlasmaChannel1D.h.
|
inline |
Species index of the electron [-]; the constructor rejects a mechanism without one, so this is always a valid index.
Definition at line 379 of file PlasmaChannel1D.h.
|
override |
Residual + transient-mask assembly at global point jg (or every point if jg == Cantera::npos); see the .cpp for the finite-volume stencil.
| jg | Global point to (re)evaluate, or Cantera::npos for a full residual pass [-] | |
| xg | Full global state vector (all domains), this domain's slice at loc() [K]/[K]/[-] (Tg/Te/Y_k) | |
| [out] | rg | Full global residual vector to write into, same layout as xg |
| [out] | maskg | Full global transient/algebraic mask (1 = transient unknown, 0 = algebraic row) [-] |
| rdt | Pseudo-transient reciprocal time step 1/dt [1/s] (0 for steady/method-of-lines) |
Definition at line 467 of file PlasmaChannel1D.cpp.
|
inline |
Number of independent evaluators nodeRates() can be called on at once [-]; 1 unless setEvaluatorPoolSize() raised it.
Definition at line 513 of file PlasmaChannel1D.h.
| double rizer::PlasmaChannel1D::faceRadius | ( | std::size_t | j | ) | const |
Radius of face j, the single definition of where a cell boundary sits (NUMERICS.md section 2).
Both sub-steps read their faces from here, which is what lets them act on one set of cells rather than on two that agree only as long as nobody edits one of them: the conduction faces of eval()'s divergence and the hydrodynamic faces of HydroStepConfig::r_face have to be the same positions, and a comment saying so is not a guarantee.
Faces run 0..nPoints(). The axis face is pinned to zero so it carries no area, interior faces sit at node midpoints, and the wall face is mirrored half the last spacing beyond the outermost node.
| [in] | j | Face index [-], 0 at the axis through nPoints() at the wall |
Definition at line 758 of file PlasmaChannel1D.cpp.
| double rizer::PlasmaChannel1D::faceSpacing | ( | std::size_t | j | ) | const |
Node-to-node spacing across face j [m], the distance a gradient at that face is taken over.
Interior faces span their two nodes. The wall face has only one, so it mirrors the last interior spacing – and on a single-point grid there is no spacing to mirror, which is what the domain radius stands in for. The fallback lives here once, so every face the residual touches applies the same one.
| [in] | j | Face index [-], 1 at the first interior face through nPoints() at the wall |
Definition at line 773 of file PlasmaChannel1D.cpp.
|
override |
Radial profile of one component, read from the domain's own solution buffer (units match that component: [K] for Tg/Te, [-] for a species).
| component | Component name: "Tg", "Te", or a species name | |
| [out] | values | One value per radial node, in that component's unit [K] or [-] |
Definition at line 604 of file PlasmaChannel1D.cpp.
|
override |
Whether name is "Tg", "Te", or a species of this domain's mechanism.
| name | Component name to test: "Tg", "Te", or a species name |
| checkAlias | Unused (this domain has no aliases) |
Definition at line 592 of file PlasmaChannel1D.cpp.
|
inline |
Whether any conduction or diffusion term is enabled [-].
False means every node's residual depends on that node alone.
Definition at line 372 of file PlasmaChannel1D.h.
|
inline |
The transport tables and per-species properties the diffusion operator reads.
Exposed for radial_diffusion_probe, which evaluates that operator outside a solve (NUMERICS.md section 6.4).
Definition at line 338 of file PlasmaChannel1D.h.
|
inline |
Whether the radial hydrodynamic sub-step is active [-].
Definition at line 375 of file PlasmaChannel1D.h.
|
override |
Initial value of component n at grid point j ([K] for Tg/Te, [-] for a species mass fraction); seeds the first solve.
| n | Component index: 0=Tg, 1=Te, 2+k=species k [-] |
| j | Radial grid point index [-] |
Definition at line 624 of file PlasmaChannel1D.cpp.
|
inline |
Definition at line 344 of file PlasmaChannel1D.h.
| void rizer::PlasmaChannel1D::nodeDiagnostics | ( | double | Tg, |
| double | Te, | ||
| const double * | Y, | ||
| std::size_t | j, | ||
| double & | pressure, | ||
| double & | electron_density ) const |
Total pressure [Pa] and electron number density [1/m^3] for a node state, both from the two-temperature equation of state the source terms themselves run on: n_e is X_e * P / (k_B * Tmean), the same value PlasmaCell::sourceTerms() sees.
Used to record p(r,t) and n_e(r,t).
One call rather than two accessors, because the state-setting behind them computes both and is the entire cost of either.
| Tg | Gas (heavy-species) temperature [K] | |
| Te | Electron temperature [K] | |
| Y | Species mass fractions [-] (length nSpecies()) | |
| j | Radial grid point index [-], which supplies the density | |
| [out] | pressure | Total pressure [Pa] |
| [out] | electron_density | Electron number density [1/m^3] |
Definition at line 668 of file PlasmaChannel1D.cpp.
| double rizer::PlasmaChannel1D::nodeElectricalConductivity | ( | double | Tg, |
| double | Te, | ||
| const double * | Y, | ||
| std::size_t | j ) const |
Electrical conductivity [S/m] at one node's state, from the same composition-resolved closure the source terms run on.
Integrated over the cross-section it gives the channel's conductance, which is what a circuit closes on.
| Tg | Gas (heavy-species) temperature [K] |
| Te | Electron temperature [K] |
| Y | Species mass fractions [-] (length nSpecies()) |
| j | Radial grid point index [-], which supplies the density |
Definition at line 724 of file PlasmaChannel1D.cpp.
| void rizer::PlasmaChannel1D::nodeRates | ( | std::size_t | j, |
| double | Tg, | ||
| double | Te, | ||
| const double * | Y, | ||
| double | electric_field, | ||
| double * | ydot ) const |
One node's time derivatives with no transport stencil: exactly what eval() computes for node j when hasTransport() is false, written into ydot in this domain's own component order (Tg, Te, then Y_k).
Only meaningful in that case. With conduction or diffusion live, a node's residual also reads its neighbours, and this would silently drop those terms rather than fail, so callers must check hasTransport() first.
| j | Radial grid point index [-], which supplies the density | |
| Tg | Gas (heavy-species) temperature [K] | |
| Te | Electron temperature [K] | |
| Y | Species mass fractions [-] (length nSpecies()) | |
| electric_field | Field magnitude at this instant [V/m] | |
| [out] | ydot | Derivatives, length nComponents(): [K/s], [K/s], then [1/s] per species |
Definition at line 676 of file PlasmaChannel1D.cpp.
|
inline |
Number of species K [-] in this domain's mechanism.
Definition at line 332 of file PlasmaChannel1D.h.
|
inline |
Outer boundary treatment for the hydro sub-step [-].
Parsed at construction, so an unknown name fails before any stepping.
Definition at line 368 of file PlasmaChannel1D.h.
|
inline |
Applied electric field E [V/m] used by the next eval() call.
| electricField | Applied electric field E [V/m] |
Definition at line 330 of file PlasmaChannel1D.h.
| void rizer::PlasmaChannel1D::setEvaluatorPoolSize | ( | std::size_t | slots | ) |
Give nodeRates() slots independent evaluators so that many threads can call it at once.
One PlasmaCell carries eight mutable scratch vectors it rewrites on every call, and the Cantera phase behind it holds the state those calls set, so two threads sharing one would overwrite each other's intermediates and return wrong numbers rather than crash. Each slot therefore gets its own PlasmaCell over its own Solution.
Expensive: a Solution is a mechanism parse (measured 227 ms for the 31-species CH4 mechanism), so this is a per-THREAD pool, never a per-node one. Slot 0 is the evaluator built at construction and is never rebuilt, so a pool of 1 costs nothing. Shrinking the pool is allowed and simply drops the extra evaluators.
| slots | Number of independent evaluators, at least 1 [-] |
Definition at line 782 of file PlasmaChannel1D.cpp.
| void rizer::PlasmaChannel1D::setHydroState | ( | const std::vector< double > & | rho, |
| const std::vector< double > & | u_r ) |
Replace the fields the hydro sub-step owns.
The one writer of m_rho and m_u_r, so that the positivity the species equation's division by rho depends on is checked once here rather than left to a caller to remember.
| rho | New per-node mass density [kg/m^3], length nPoints(), every entry > 0 |
| u_r | New per-node radial velocity [m/s], same length |
| std::invalid_argument | if a length is wrong or a density is not positive |
Definition at line 637 of file PlasmaChannel1D.cpp.
|
inline |
Per-species \(c_p\) [J/kg/K], length nSpecies(), at the state the cell was last evaluated at.
eval() refreshes it per node before reading it; a caller reaching the diffusion operator directly has to call updateSpeciesCp() first, or it reads the zeros the constructor left.
Definition at line 354 of file PlasmaChannel1D.h.
|
inline |
Refresh speciesCp() at one node's state.
See PlasmaCell.
| [in] | Tg | Gas temperature [K] |
| [in] | Te | Electron temperature [K] |
| [in] | Y | Mass fractions, length nSpecies() [-] |
| [in] | rho | Mass density [kg/m^3] |
Definition at line 361 of file PlasmaChannel1D.h.
|
inline |
Per-node radial velocity [m/s], length nPoints().
Definition at line 385 of file PlasmaChannel1D.h.
| void rizer::PlasmaChannel1D::wallEnergyOutflow | ( | Cantera::span< const double > | x, |
| double & | conduction_out, | ||
| double & | diffusion_out, | ||
| std::vector< double > & | species_mass_out ) const |
Energy conduction and species diffusion move out through the wall ghost face at the state x, per unit axial length and per radian [W/m]; positive is outward.
Both are zero when hasTransport() is false: no parabolic term runs, so nothing crosses the wall by that route.
| [in] | x | This domain's state vector |
| [out] | conduction_out | Conduction, both pools [W/m] |
| [out] | diffusion_out | Enthalpy carried by species diffusion [W/m] |
| [out] | species_mass_out | Mass of each species species diffusion carries out [kg/m/s], length nSpecies() |
Definition at line 731 of file PlasmaChannel1D.cpp.