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
88
89#ifndef RIZER_PLASMA_CHANNEL_1D_H
90#define RIZER_PLASMA_CHANNEL_1D_H
91
92#ifndef NOMINMAX
93#define NOMINMAX
94#endif
99#include "ReactorRHS.h"
100
101#include <memory>
102#include <string>
103#include <vector>
104
105namespace rizer {
106
107// Physics + initial/boundary configuration for a PlasmaChannel1D.
109 std::string mech; // Cantera mechanism (YAML) file path
110 std::string phase; // Phase name within `mech` (a PlasmaPhase
111 // with "e-")
112 std::size_t n_points = 1; // Number of radial grid points [-]
113 // (ignored if `grid` is given)
114 double R_max = 1.0e-3; // Outer (wall) radius R [m] (ignored if
115 // `grid` is given)
116 double rho = 0.1; // Fixed mass density rho [kg/m^3]
117 // (constant-volume model; not a state)
118 double electric_field = 0.0; // Constant applied electric field E
119 // [V/m] (ignored if Et_t/Et_v given);
120 // Python: `electric_field` (scalar case)
121 double nu_E = 0.0; // Elastic electron-heavy energy-exchange
122 // frequency nu_E [1/s] (legacy closure
123 // only; mutually exclusive with `specs`)
124 double nu_m = 0.0; // Electron momentum-transfer frequency
125 // nu_m [1/s]. If > 0, @f$\sigma = n_e
126 // e^2/(m_e \nu_m)@f$ (local, from the
127 // evolving n_e) overrides the
128 // @f$\sigma(T_e)@f$ table. (legacy
129 // closure only; mutually exclusive with
130 // `specs`)
131 std::vector<double> nu_m_T, nu_m_v; // Te-dependent @f$\nu_m(T_e)@f$
132 // table [K],[1/s]; if given, overrides
133 // the scalar nu_m (sigma then
134 // self-regulates as Te rises, like the
135 // 0D model). (legacy closure only;
136 // mutually exclusive with `specs`)
137 // Composition-resolved collision model (preferred over the legacy sigma/nu_m/
138 // nu_E closures below -- mutually exclusive with them, see PlasmaChannel1D.cpp).
139 // One entry per species, in species-index order; empty -> legacy closure.
140 // molar_mass/is_electron are filled in by the constructor from the mechanism,
141 // so callers only need to set energy_J/sigma_m2 (tabulated neutral), radius
142 // (hard-sphere neutral), or Z (ion) per species -- see CollisionModel.h.
143 // Python: built from the `mtcf` list of MomentumTransferCollisionFrequencyModel.
144 std::vector<CollisionModel::SpeciesSpec> specs;
145 double Te_min = 300.0; // Collision-model Te grid lower bound [K]
146 // (only used when `specs` is given)
147 double Te_max = 1.0e5; // Collision-model Te grid upper bound [K]
148 // (only used when `specs` is given)
149 std::size_t Te_n = 400; // Collision-model Te grid point count [-]
150 // (only used when `specs` is given)
151 bool spitzer = true; // Apply the Spitzer e-e correction
152 // (II-13.18) [-] (only used when `specs`
153 // is given)
154 double D_species = 0.0; // Constant scalar species mass
155 // diffusivity D [m^2/s] (0 = frozen
156 // species transport)
157 bool reacting = true; // Include finite-rate chemistry source terms [-]
158 std::vector<double> species_h0k; // Per-species standard enthalpy of
159 // formation at 0 K [J/kmol]; forwarded to
160 // ReactorRHS::Config::species_h0k (see
161 // there). Required when `reacting` is true
162 // and the mechanism has an electron-impact
163 // reaction.
164 double T_amb = 300.0; // Wall/ambient temperature T_amb [K];
165 // also the outer-wall Dirichlet ghost
166 // value for Tg
167 std::vector<double> Y0; // Initial + ambient mass fractions [-]
168 // (length K, sums to 1); also the
169 // outer-wall Dirichlet ghost value per
170 // species
171 // Explicit radial grid [m], increasing from 0. Empty -> setupUniformGrid
172 // (n_points, R_max). When provided, it sets the mesh directly (Cantera-flame
173 // style, Domain1D::setupGrid) and defines n_points and R_max.
174 std::vector<double> grid;
175 // Property tables (empty/constant -> disabled). Each `_T` array is the table's
176 // temperature axis [K] (electron temperature Te for sigma/kappa_e, gas
177 // temperature Tg for kappa); each `_v` array is the tabulated value at that
178 // temperature, in the unit noted below.
179 std::vector<double> sigma_T, sigma_v; // Electrical conductivity
180 // table @f$\sigma(T_e)@f$ [K],[S/m]
181 // (legacy closure only; mutually
182 // exclusive with `specs`)
183 std::vector<double> kappa_T, kappa_v; // Gas thermal conductivity
184 // table @f$\kappa(T_g)@f$ [K],[W/m/K]
185 // (empty = conduction on Tg disabled)
186 std::vector<double> kappa_e_T, kappa_e_v; // Electron thermal
187 // conductivity table @f$\kappa_e(T_e)@f$
188 // [K],[W/m/K] (empty = conduction on Te
189 // disabled)
190 // Initial radial temperature profiles (empty -> uniform T_amb-based):
191 // `_r` is the radius axis [m], `_v` is the temperature at that radius [K].
192 std::vector<double> initTg_r, initTg_v; // Tg(r) at t=0 [m],[K];
193 // Python: `Tg_profile`
194 std::vector<double> initTe_r, initTe_v; // Te(r) at t=0 [m],[K];
195 // Python: `Te_profile`
196 // Initial radial composition profile (empty -> uniform Y0 everywhere).
197 // initY_r: radii [m] (length nr); initY_v: row-major [nr*K] mass fractions [-].
198 std::vector<double> initY_r, initY_v; // Python: `Y0_profile`
199 // Field-vs-time table @f$E(t)@f$: Et_t [s], Et_v [V/m]. Empty -> constant
200 // electric_field; non-empty -> E(t) interpolated, evaluated each time step.
201 std::vector<double> Et_t, Et_v; // Python: `electric_field`
202 // (tuple/schedule case)
203};
204
206public:
209 explicit PlasmaChannel1D(const PlasmaChannelConfig& cfg);
210
211 std::string domainType() const override { return "plasma-channel-1d"; }
212
225 void eval(std::size_t jg, Cantera::span<const double> xg, Cantera::span<double> rg,
226 Cantera::span<int> maskg, double rdt) override;
227
229 std::string componentName(std::size_t n) const override;
233 std::size_t componentIndex(const std::string& name,
234 bool checkAlias = true) const override;
238 bool hasComponent(const std::string& name, bool checkAlias = true) const override;
244 void getValues(const std::string& component,
245 Cantera::span<double> values) const override;
246
251 double initialValue(std::size_t n, std::size_t j) override;
256 void resetBadValues(Cantera::span<double> xg) override;
257
260 void setElectricField(double electricField) { m_electric_field = electricField; }
262 double electricField() const { return m_electric_field; }
264 std::size_t nSpecies() const { return m_n_species; }
265
271 double electronDensity(double Tg, double Te, const double* Y) const;
272
273private:
274 std::shared_ptr<Cantera::Solution> m_solution; // Cantera thermo/kinetics
275 // manager (PlasmaPhase)
276 std::unique_ptr<ReactorRHS> m_reactor_rhs; // Shared single-cell 2T
277 // physics (chemistry/Joule/exchange)
278 std::size_t m_n_species; // Number of species K [-] (thermo->nSpecies())
279 std::size_t m_electron_index; // Species index of "e-" [-] (npos if the
280 // mechanism has none)
281 double m_outer_radius; // Outer (wall) radius R [m]
282 double m_rho; // Fixed mass density rho [kg/m^3]
283 // (constant-volume model)
284 double m_electric_field; // Applied electric field E [V/m], set per
285 // eval() via setElectricField()
286 double m_species_diffusivity; // Constant scalar species mass diffusivity
287 // D [m^2/s] (0 = frozen)
288 bool m_reacting; // Include finite-rate chemistry source terms [-]
289 double m_ambient_temperature; // Wall/ambient temperature T_amb [K]
290 std::vector<double> m_Y0; // Initial + ambient mass fractions [-]
291 // (length K, sums to 1)
292 PropertyTable m_kappa; // Gas thermal conductivity table
293 // @f$\kappa(T_g)@f$ [W/m/K]; empty ->
294 // disabled
295 PropertyTable m_kappa_e; // Electron thermal conductivity table
296 // @f$\kappa_e(T_e)@f$ [W/m/K]; empty ->
297 // disabled
298 PropertyTable m_initTg; // Initial radial profile Tg(r) [K]; empty
299 // -> uniform m_ambient_temperature
300 PropertyTable m_initTe; // Initial radial profile Te(r) [K]; empty
301 // -> uniform m_ambient_temperature
302 std::vector<PropertyTable> m_initY; // Initial radial profiles Y_k(r)
303 // [-], one per species (empty ->
304 // uniform m_Y0)
305 bool m_has_transport; // True if any conduction/diffusion term is
306 // enabled (kappa, kappa_e, or D_species > 0)
307};
308
309} // namespace rizer
310
311#endif
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 ...
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...
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.
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 resetBadValues(Cantera::span< double > xg) override
Clamp a trial state back onto a physically evaluable range (Tg, Te >= 200 K; every Y_k in [0,...
std::string componentName(std::size_t n) const override
Component n -> name ("Tg", "Te", or a species name).
void setElectricField(double electricField)
Applied electric field E [V/m] used by the next eval() call.
std::string domainType() const override
double electronDensity(double Tg, double Te, const double *Y) const
Electron number density [1/m^3] for a node state (X_e * P / (k_B * Tmean)), matching the n_e used int...
PlasmaChannel1D(const PlasmaChannelConfig &cfg)
Build the domain (mesh, thermo/kinetics, property tables) from cfg.
std::size_t componentIndex(const std::string &name, bool checkAlias=true) const override
Component name -> index (inverse of componentName()); throws if unknown.
double electricField() const
Currently-set electric field E [V/m].
std::vector< double > initTe_v
std::vector< double > kappa_e_T
std::vector< double > initY_v
std::vector< double > sigma_v
std::vector< double > species_h0k
std::vector< double > initTg_r
std::vector< double > kappa_e_v
std::vector< double > Y0
std::vector< double > initTg_v
std::vector< double > sigma_T
std::vector< double > initTe_r
std::vector< double > kappa_T
std::vector< double > initY_r
std::vector< double > kappa_v
std::vector< double > nu_m_T
std::vector< double > Et_v
std::vector< CollisionModel::SpeciesSpec > specs
std::vector< double > nu_m_v
std::vector< double > grid
std::vector< double > Et_t