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
97#include "CollisionModel.h"
98#include "PropertyTable.h"
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 double T_amb = 300.0; // Wall/ambient temperature T_amb [K];
159 // also the outer-wall Dirichlet ghost
160 // value for Tg
161 std::vector<double> Y0; // Initial + ambient mass fractions [-]
162 // (length K, sums to 1); also the
163 // outer-wall Dirichlet ghost value per
164 // species
165 // Explicit radial grid [m], increasing from 0. Empty -> setupUniformGrid
166 // (n_points, R_max). When provided, it sets the mesh directly (Cantera-flame
167 // style, Domain1D::setupGrid) and defines n_points and R_max.
168 std::vector<double> grid;
169 // Property tables (empty/constant -> disabled). Each `_T` array is the table's
170 // temperature axis [K] (electron temperature Te for sigma/kappa_e, gas
171 // temperature Tg for kappa); each `_v` array is the tabulated value at that
172 // temperature, in the unit noted below.
173 std::vector<double> sigma_T, sigma_v; // Electrical conductivity
174 // table @f$\sigma(T_e)@f$ [K],[S/m]
175 // (legacy closure only; mutually
176 // exclusive with `specs`)
177 std::vector<double> kappa_T, kappa_v; // Gas thermal conductivity
178 // table @f$\kappa(T_g)@f$ [K],[W/m/K]
179 // (empty = conduction on Tg disabled)
180 std::vector<double> kappa_e_T, kappa_e_v; // Electron thermal
181 // conductivity table @f$\kappa_e(T_e)@f$
182 // [K],[W/m/K] (empty = conduction on Te
183 // disabled)
184 // Initial radial temperature profiles (empty -> uniform T_amb-based):
185 // `_r` is the radius axis [m], `_v` is the temperature at that radius [K].
186 std::vector<double> initTg_r, initTg_v; // Tg(r) at t=0 [m],[K];
187 // Python: `Tg_profile`
188 std::vector<double> initTe_r, initTe_v; // Te(r) at t=0 [m],[K];
189 // Python: `Te_profile`
190 // Initial radial composition profile (empty -> uniform Y0 everywhere).
191 // initY_r: radii [m] (length nr); initY_v: row-major [nr*K] mass fractions [-].
192 std::vector<double> initY_r, initY_v; // Python: `Y0_profile`
193 // Field-vs-time table @f$E(t)@f$: Et_t [s], Et_v [V/m]. Empty -> constant
194 // electric_field; non-empty -> E(t) interpolated, evaluated each time step.
195 std::vector<double> Et_t, Et_v; // Python: `electric_field`
196 // (tuple/schedule case)
197};
198
200public:
203 explicit PlasmaChannel1D(const PlasmaChannelConfig& cfg);
204
205 std::string domainType() const override { return "plasma-channel-1d"; }
206
219 void eval(std::size_t jg, Cantera::span<const double> xg, Cantera::span<double> rg,
220 Cantera::span<int> maskg, double rdt) override;
221
223 std::string componentName(std::size_t n) const override;
227 std::size_t componentIndex(const std::string& name,
228 bool checkAlias = true) const override;
232 bool hasComponent(const std::string& name, bool checkAlias = true) const override;
238 void getValues(const std::string& component,
239 Cantera::span<double> values) const override;
240
245 double initialValue(std::size_t n, std::size_t j) override;
250 void resetBadValues(Cantera::span<double> xg) override;
251
254 void setElectricField(double electricField) { m_electric_field = electricField; }
256 double electricField() const { return m_electric_field; }
258 std::size_t nSpecies() const { return m_n_species; }
259
265 double electronDensity(double Tg, double Te, const double* Y) const;
266
267private:
268 std::shared_ptr<Cantera::Solution> m_solution; // Cantera thermo/kinetics
269 // manager (PlasmaPhase)
270 std::unique_ptr<ReactorRHS> m_reactor_rhs; // Shared single-cell 2T
271 // physics (chemistry/Joule/exchange)
272 std::size_t m_n_species; // Number of species K [-] (thermo->nSpecies())
273 std::size_t m_electron_index; // Species index of "e-" [-] (npos if the
274 // mechanism has none)
275 double m_outer_radius; // Outer (wall) radius R [m]
276 double m_rho; // Fixed mass density rho [kg/m^3]
277 // (constant-volume model)
278 double m_electric_field; // Applied electric field E [V/m], set per
279 // eval() via setElectricField()
280 double m_species_diffusivity; // Constant scalar species mass diffusivity
281 // D [m^2/s] (0 = frozen)
282 bool m_reacting; // Include finite-rate chemistry source terms [-]
283 double m_ambient_temperature; // Wall/ambient temperature T_amb [K]
284 std::vector<double> m_Y0; // Initial + ambient mass fractions [-]
285 // (length K, sums to 1)
286 PropertyTable m_kappa; // Gas thermal conductivity table
287 // @f$\kappa(T_g)@f$ [W/m/K]; empty ->
288 // disabled
289 PropertyTable m_kappa_e; // Electron thermal conductivity table
290 // @f$\kappa_e(T_e)@f$ [W/m/K]; empty ->
291 // disabled
292 PropertyTable m_initTg; // Initial radial profile Tg(r) [K]; empty
293 // -> uniform m_ambient_temperature
294 PropertyTable m_initTe; // Initial radial profile Te(r) [K]; empty
295 // -> uniform m_ambient_temperature
296 std::vector<PropertyTable> m_initY; // Initial radial profiles Y_k(r)
297 // [-], one per species (empty ->
298 // uniform m_Y0)
299 bool m_has_transport; // True if any conduction/diffusion term is
300 // enabled (kappa, kappa_e, or D_species > 0)
301};
302
303} // namespace rizer
304
305#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 > 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