rizer.cantera_ext
C++ Cantera 1-D plasma extension (custom Domain1D models and solvers)
Loading...
Searching...
No Matches
PlasmaChannel1D.h
Go to the documentation of this file.
1
99
100#ifndef RIZER_PLASMA_CHANNEL_1D_H
101#define RIZER_PLASMA_CHANNEL_1D_H
102
103#ifndef NOMINMAX
104#define NOMINMAX
105#endif
110#include "BoundaryConditions.h"
111#include "PlasmaCell.h"
112#include "RadialDiffusion.h"
113
114#include <memory>
115#include <string>
116#include <vector>
117
118namespace rizer
119{
120
121 // Physics + initial/boundary configuration for a PlasmaChannel1D.
127 {
128 // ---- Mechanism ----------------------------------------------------
129
131 std::string mech;
133 std::string phase;
134
135 // ---- Grid ---------------------------------------------------------
136
138 std::size_t n_points = 1;
140 double R_max = 1.0e-3;
144 std::vector<double> grid;
145
146 // ---- Initial state ------------------------------------------------
147
151 double rho = 0.1;
154 std::vector<double> initTg_r, initTg_v;
156 std::vector<double> initTe_r, initTe_v;
162 std::vector<double> initY_r, initY_v;
167 std::vector<double> init_rho_r, init_rho_v;
170 std::vector<double> init_ur_r, init_ur_v;
171
172 // ---- Chemistry ----------------------------------------------------
173
175 bool reacting = true;
180 std::vector<double> species_h0k;
181
182 // ---- Discharge ----------------------------------------------------
183
188 double electric_field = 0.0;
189
190 // ---- Transport, bulk closures -------------------------------------
191 //
192 // Each `_T` array is a table's temperature axis [K] -- electron
193 // temperature for sigma and kappa_e, heavy-pool temperature for
194 // kappa_H -- and each `_v` array the tabulated value there.
195
198 std::vector<double> sigma_T, sigma_v;
201 double nu_E = 0.0;
206 double nu_m = 0.0;
210 std::vector<double> nu_m_T, nu_m_v;
213 std::vector<double> kappa_H_T, kappa_H_v;
216 std::vector<double> kappa_e_T, kappa_e_v;
219 double D_species = 0.0;
220
221 // ---- Transport, composition-resolved model ------------------------
222
232 std::vector<CollisionModel::SpeciesSpec> specs;
235 double Te_min = 200.0;
238 double Te_max = 1.0e5;
240 std::size_t Te_n = 400;
241
242 // ---- Ambient and boundary -----------------------------------------
243
246 double T_amb = 300.0;
250 double p_amb = -1.0;
255 std::vector<double> Y_amb;
260 std::string outer_bc_mode = "ambient_ghost";
261
262 // ---- Hydrodynamics ------------------------------------------------
263
267 bool hydrodynamics = false;
269 double cfl = 0.9;
274 double hydro_substep = 0.0;
275 };
276
278 {
279 public:
282 explicit PlasmaChannel1D(const PlasmaChannelConfig &cfg);
283
284 std::string domainType() const override { return "plasma-channel-1d"; }
285
298 void eval(std::size_t jg, Cantera::span<const double> xg, Cantera::span<double> rg,
299 Cantera::span<int> maskg, double rdt) override;
300
302 std::string componentName(std::size_t n) const override;
303
307 std::size_t componentIndex(const std::string &name,
308 bool checkAlias = true) const override;
312 bool hasComponent(const std::string &name, bool checkAlias = true) const override;
313
319 void getValues(const std::string &component,
320 Cantera::span<double> values) const override;
321
326 double initialValue(std::size_t n, std::size_t j) override;
327
330 void setElectricField(double electricField) { m_electric_field = electricField; }
332 std::size_t nSpecies() const { return m_n_species; }
333
338 const PropertyTable &heavyConductivity() const { return m_kappa_H; }
339
341 const PropertyTable &electronConductivity() const { return m_kappa_e; }
342
344 const std::vector<double> &molecularWeights() const
345 {
346 return m_cell->molecularWeights();
347 }
348
354 const std::vector<double> &speciesCp() const { return m_cell->speciesCp(); }
355
361 void updateSpeciesCp(double Tg, double Te, const double *Y, double rho) const
362 {
363 m_cell->updateSpeciesCp(Tg, Te, Y, rho);
364 }
365
368 OuterBc outerBcMode() const { return m_outer_bc_mode; }
369
372 bool hasTransport() const { return m_has_transport; }
373
375 bool hydrodynamics() const { return m_hydrodynamics; }
376
379 std::size_t electronIndex() const { return m_electron_index; }
380
382 const std::vector<double> &density() const { return m_rho; }
383
385 const std::vector<double> &velocity() const { return m_u_r; }
386
397 void setHydroState(const std::vector<double> &rho,
398 const std::vector<double> &u_r);
399
413 void nodeDiagnostics(double Tg, double Te, const double *Y, std::size_t j,
414 double &pressure, double &electron_density) const;
415
431 void nodeRates(std::size_t j, double Tg, double Te, const double *Y,
432 double electric_field, double *ydot) const;
433
442 double nodeElectricalConductivity(double Tg, double Te, const double *Y,
443 std::size_t j) const;
444
456 void wallEnergyOutflow(Cantera::span<const double> x, double &conduction_out,
457 double &diffusion_out,
458 std::vector<double> &species_mass_out) const;
459
462 const std::vector<double> &ambientMassFractions() const { return m_Y_amb; }
463
479 double faceRadius(std::size_t j) const;
480
492 double faceSpacing(std::size_t j) const;
493
509 void setEvaluatorPoolSize(std::size_t slots);
510
513 std::size_t evaluatorPoolSize() const { return 1 + m_extra_rhs.size(); }
514
515 private:
518 RadialDiffusionCoefficients diffusionCoefficients() const;
519
520 // Cantera solution, which owns the thermo/kinetics manager (PlasmaPhase) and the
521 // transport manager (Transport).
522 std::shared_ptr<Cantera::Solution> m_solution;
523 // The single evaluator slot 0, which owns its own Solution and is the one
524 // nodeRates() uses when the pool size is 1. It is also the one that eval()
525 // uses, so it is the only one that sees the evolving state vector.
526 std::unique_ptr<PlasmaCell> m_cell;
527
528 // Evaluator slots 1..n for setEvaluatorPoolSize(); slot 0 is
529 // m_cell. Each owns its own Solution, so nothing is shared.
530 std::vector<std::unique_ptr<PlasmaCell>> m_extra_rhs;
531 // What setEvaluatorPoolSize() needs to build another evaluator: the same
532 // closure configuration, over a mechanism loaded again from scratch.
533 PlasmaCellConfig m_reactor_config;
534 std::string m_mech, m_phase;
535 std::size_t m_n_species; // Number of species K [-] (thermo->nSpecies())
536 std::size_t m_electron_index; // Species index of "e-" [-] (npos if the
537 // mechanism has none)
538 double m_outer_radius; // Outer (wall) radius R [m]
539 std::vector<double> m_rho; // Mass density rho [kg/m^3], one per radial
540 // node. Held outside the Domain1D solution
541 // vector, which stays nv=2+K: the radial
542 // hydrodynamic sub-step owns this field
543 // (NUMERICS.md section 4.2), so eval() has
544 // no residual row to write for it
545 std::vector<double> m_u_r; // Radial velocity u_r [m/s], one per radial
546 // node, owned by the hydro sub-step like
547 // m_rho and held outside the solution
548 // vector for the same reason
549 bool m_hydrodynamics; // Run the radial hydrodynamic sub-step [-]
550 OuterBc m_outer_bc_mode; // Outer boundary treatment for the hydro
551 // sub-step, parsed from the config string
552 double m_wall_ghost_density; // Mass density of the wall ghost half-cell
553 // [kg/m^3]. The ghost carries the ambient
554 // composition and temperature, so with
555 // hydrodynamics on -- the only mode that
556 // supplies an ambient pressure -- it carries
557 // the ambient density too, rather than the
558 // outermost node's
559 double m_electric_field; // Applied electric field E [V/m], set per
560 // eval() via setElectricField()
561 double m_species_diffusivity; // Constant scalar species mass diffusivity
562 // D [m^2/s] (0 = frozen)
563 bool m_reacting; // Include finite-rate chemistry source terms [-]
564 double m_ambient_temperature; // Wall/ambient temperature T_amb [K]
565 std::vector<double> m_Y_amb; // Ambient mass fractions [-] (length K,
566 // sums to 1), outside the domain
567 PropertyTable m_kappa_H; // Heavy-pool thermal conductivity table
568 // @f$\kappa_\mathrm{H}(T_g)@f$ [W/m/K];
569 // empty -> disabled
570 PropertyTable m_kappa_e; // Electron thermal conductivity table
571 // @f$\kappa_e(T_e)@f$ [W/m/K]; empty ->
572 // disabled
573 PropertyTable m_initTg; // Initial radial profile Tg(r) [K]; empty
574 // -> uniform m_ambient_temperature
575 PropertyTable m_initTe; // Initial radial profile Te(r) [K]; empty
576 // -> uniform m_ambient_temperature
577 std::vector<PropertyTable> m_initY; // Initial radial profiles Y_k(r)
578 // [-], one per species
579 bool m_has_transport; // True if any conduction/diffusion term is
580 // enabled (kappa_H, kappa_e, or
581 // D_species > 0)
582 };
583
584} // namespace rizer
585
586#endif
Outer-boundary vocabulary for the 1D radial channel: which treatment is applied, the primitive state ...
One cell of two-temperature reacting plasma: the source terms the 0-D reactor and the 1-D channel bot...
The parabolic half of PlasmaChannel1D::eval(): conduction in both pools, Fickian species diffusion,...
shared_ptr< Solution > m_solution
vector< double > values(const string &component) const
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 ...
const PropertyTable & electronConductivity() const
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 th...
OuterBc outerBcMode() const
Outer boundary treatment for the hydro sub-step [-].
void setEvaluatorPoolSize(std::size_t slots)
Give nodeRates() slots independent evaluators so that many threads can call it at once.
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 compone...
std::size_t nSpecies() const
Number of species K [-] in this domain's mechanism.
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-temperatu...
std::size_t electronIndex() const
Species index of the electron [-]; the constructor rejects a mechanism without one,...
bool hasComponent(const std::string &name, bool checkAlias=true) const override
Whether name is "Tg", "Te", or a species of this domain's mechanism.
std::string componentName(std::size_t n) const override
Component n -> name ("Tg", "Te", or a species name).
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 h...
bool hydrodynamics() const
Whether the radial hydrodynamic sub-step is active [-].
void setElectricField(double electricField)
Applied electric field E [V/m] used by the next eval() call.
const std::vector< double > & molecularWeights() const
const PropertyTable & heavyConductivity() const
The transport tables and per-species properties the diffusion operator reads.
void updateSpeciesCp(double Tg, double Te, const double *Y, double rho) const
Refresh speciesCp() at one node's state.
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().
std::string domainType() const override
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 sou...
double faceRadius(std::size_t j) const
Radius of face j, the single definition of where a cell boundary sits (NUMERICS.md section 2).
std::size_t evaluatorPoolSize() const
Number of independent evaluators nodeRates() can be called on at once [-]; 1 unless setEvaluatorPoolS...
PlasmaChannel1D(const PlasmaChannelConfig &cfg)
Build the domain (mesh, thermo/kinetics, property tables) from cfg.
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.
bool hasTransport() const
Whether any conduction or diffusion term is enabled [-].
std::size_t componentIndex(const std::string &name, bool checkAlias=true) const override
Component name -> index (inverse of componentName()); throws if unknown.
const std::vector< double > & speciesCp() const
Per-species [J/kg/K], length nSpecies(), at the state the cell was last evaluated at.
const std::vector< double > & ambientMassFractions() const
Ambient mass fractions [-], length nSpecies(): the composition outside the domain,...
OuterBc
Outer-boundary treatment (NUMERICS.md section 7).
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.
Everything PlasmaChannel1D needs to build itself.
std::vector< double > initTe_v
std::vector< double > kappa_e_T
Electron thermal conductivity table kappa_e(Te) [K], [W/m/K].
std::vector< double > init_rho_v
std::vector< double > initY_v
double electric_field
Applied electric field E [V/m], held at every node until the driver changes it through setElectricFie...
std::string mech
Cantera mechanism (YAML) file path.
double T_amb
Wall/ambient temperature T_amb [K], and the outer-wall Dirichlet ghost value for Tg.
std::vector< double > init_ur_v
std::vector< double > init_ur_r
u_r(r) at t=0 [m], [m/s].
bool hydrodynamics
Radial hydrodynamics (NUMERICS.md section 4.2's Strang split).
std::vector< double > sigma_v
double nu_m
Electron momentum-transfer frequency nu_m [1/s].
std::vector< double > species_h0k
Per-species standard enthalpy of formation at 0 K [J/kmol], forwarded to PlasmaCellConfig::species_h0...
std::vector< double > initTg_r
Tg(r) at t=0: _r is the radius axis [m], _v the temperature at that radius [K].
std::vector< double > kappa_e_v
double p_amb
Ambient pressure [Pa] handed to the hydro sub-step.
std::vector< double > kappa_H_v
std::vector< double > Y_amb
Ambient mass fractions [-], length K, summing to 1: the composition of the gas OUTSIDE the domain.
std::vector< double > init_rho_r
rho(r) at t=0 [m], [kg/m^3]; every value must be > 0.
double hydro_substep
Pinned hydro sub-step [s]; 0 lets the CFL bound choose it.
std::size_t n_points
Number of radial grid points [-]. Ignored when grid is given.
double nu_E
Elastic electron-heavy energy-exchange frequency nu_E [1/s].
std::vector< double > kappa_H_T
Heavy-pool thermal conductivity table kappa_H(Tg) [K], [W/m/K].
std::size_t Te_n
Collision-model Te grid point count [-]. Read only with specs.
std::string outer_bc_mode
Outer boundary treatment: "ambient_ghost" (the default, and the accurate choice while R_max sits beyo...
std::vector< double > initTg_v
double R_max
Outer (wall) radius R [m]. Ignored when grid is given.
double D_species
Constant scalar species mass diffusivity D [m^2/s].
double Te_min
Collision-model Te grid lower bound [K].
std::vector< double > sigma_T
Electrical conductivity table sigma(Te) [K], [S/m].
bool reacting
Include finite-rate chemistry source terms [-].
std::vector< double > initTe_r
Te(r) at t=0 [m], [K]. Python: Te0 (uniform) or Te_profile.
double cfl
Courant number for the hydro sub-step's own CFL sub-cycling [-].
std::vector< double > initY_r
Y(r) at t=0.
std::vector< double > nu_m_T
Te-dependent nu_m(Te) table [K], [1/s].
double Te_max
Collision-model Te grid upper bound [K].
std::vector< CollisionModel::SpeciesSpec > specs
Composition-resolved collision model, preferred over the legacy sigma/nu_m/nu_E closures above and mu...
double rho
Mass density rho [kg/m^3] held at every node, unless init_rho_r/init_rho_v give a radial profile.
std::vector< double > nu_m_v
std::vector< double > grid
Explicit radial grid [m], increasing from 0.
std::string phase
Phase name within mech; must be a PlasmaPhase carrying "e-".
Everything the diffusion block needs that the grid and the state do not carry: the transport coeffici...