Cantera  4.0.0a2
Loading...
Searching...
No Matches
EEDFTwoTermApproximation.h
Go to the documentation of this file.
1/**
2 * @file EEDFTwoTermApproximation.h EEDF Two-Term approximation solver.
3 */
4
5// This file is part of Cantera. See License.txt in the top-level directory or
6// at https://cantera.org/license.txt for license and copyright information.
7
8#ifndef CT_EEDF_TWO_TERM_APPROXIMATION_H
9#define CT_EEDF_TWO_TERM_APPROXIMATION_H
10
12#include "cantera/numerics/eigen_sparse.h"
13
14namespace Cantera
15{
16
17class PlasmaPhase;
18
19//! Boltzmann equation solver for the electron energy distribution function based on
20//! the two-term approximation.
21/*!
22 * This class implements a solver for the electron energy distribution function
23 * based on a steady-state solution to the Boltzmann equation using the classical
24 * two-term expansion, applicable to weakly ionized plasmas. The numerical approach
25 * and theory are primarily derived from the work of Hagelaar and Pitchford
26 * @cite hagelaar2005.
27 *
28 * The two-term approximation assumes that the EEDF can be represented as:
29 * @f[
30 * f(\epsilon, \mu) = f_0(\epsilon) + \mu f_1(\epsilon),
31 * @f]
32 * where @f$ \epsilon @f$ is the electron energy and @f$ \mu @f$ is the cosine
33 * of the angle between the electron velocity vector and the electric field.
34 * The Boltzmann equation is projected onto the zeroth moment over mu to obtain
35 * an equation for @f$ f_0(\epsilon) @f$ , the isotropic part of the distribution.
36 * The first-order anisotropic term @f$ f_1(\epsilon) @f$ is not solved directly,
37 * but is approximated and substituted into the drift and collision terms. This
38 * results in a second-order differential equation for @f$ f_0(\epsilon) @f$ alone.
39 *
40 * The governing equation for @f$ f_0(\epsilon) @f$ is discretized on an energy
41 * grid using a finite difference method and solved using a tridiagonal matrix
42 * algorithm.
43 *
44 * @since New in %Cantera 3.2.
45 * @warning This class is an experimental part of %Cantera and may be changed without
46 * notice.
47 */
49{
50public:
51 EEDFTwoTermApproximation() = default;
52
53 //! Constructor combined with the initialization function
54 /*!
55 * This constructor initializes the EEDFTwoTermApproximation object with everything
56 * it needs to start solving EEDF.
57 *
58 * @param s PlasmaPhase object that will be used in the solver calls.
59 */
61
62 virtual ~EEDFTwoTermApproximation() = default;
63
64 //! compute the EEDF given an electric field
65 //! CQM The solver will take the species to consider and the set of cross-sections
66 //! from the PlasmaPhase object.
67 //! It will write the EEDF and its grid into the PlasmaPhase object.
68 //! Successful returns are indicated by a return value of 0.
70
71 //! Sets a linear energy grid for the EEDF solver, defined by the maximum energy and
72 //! the number of grid cells.
73 //! @since New in %Cantera 4.0
74 //! @param kTe_max: maximum grid energy in eV
75 //! @param ncell: number of cell to discretize the grid.
76 void setLinearGrid(double kTe_max, size_t ncell);
77
78 //! Sets a quadratic energy grid for the EEDF solver, defined by the maximum energy
79 //! and the number of grid cells.
80 //! @since New in %Cantera 4.0
81 //! @param kTe_max: maximum grid energy in eV
82 //! @param ncell: number of cell to discretize the grid.
83 void setQuadraticGrid(double kTe_max, size_t ncell);
84
85 //! Sets a geometric energy grid for the EEDF solver, defined by the maximum energy
86 //! and the number of grid cells.
87 //! @since New in %Cantera 4.0
88 //! @param kTe_max: maximum grid energy in eV
89 //! @param ncell: number of cell to discretize the grid.
90 //! @param ratio: the geometric growth ratio.
91 void setGeometricGrid(double kTe_max, size_t ncell, double ratio = 1.01);
92
93 //! Sets a custom energy grid for the EEDF solver, defined by the user-provided
94 //! vector of energy levels.
95 void setCustomGrid(span<const double> levels);
96
97 //! Build or rebuild the grid-dependent cache used for scattering matrices.
98 void setGridCache();
99
100 //! Set the initial grid parameters used by generated EEDF grids.
101 /*!
102 * These values are used when creating linear, quadratic, or geometric grids,
103 * and are also reused during grid adaptation.
104 *
105 * @param initialMaxEnergy Maximum electron energy of the initial grid [eV].
106 * @param nGridCells Number of grid cells. The number of grid edges is
107 * nGridCells + 1.
108 * @param gridType Type of grid spacing to use when generating or adapting
109 * the electron energy grid. Supported values are "linear",
110 * "quadratic", and "geometric".
111 * @since New in %Cantera 4.0
112 */
113 void setInitialGridParameters(double initialMaxEnergy, size_t nGridCells,
114 const string& gridType);
115
116 //! Enable or disable automatic grid adaptation for the EEDF solver energy grid.
117 //! @since New in %Cantera 4.0
118 void enableGridAdaptation(bool enabled);
119
120 //! Set parameters controlling automatic adaptation of the EEDF energy grid.
121 /*!
122 * Grid adaptation adjusts the maximum grid energy based on the number of
123 * decades by which the EEDF decays between the low- and high-energy ends of
124 * the grid. The number of grid cells is kept fixed.
125 *
126 * @param minDecayDecades Minimum acceptable EEDF tail decay in decades. If the
127 * decay is smaller, the maximum grid energy is increased.
128 * @param maxDecayDecades Maximum acceptable EEDF tail decay in decades. If the
129 * decay is larger, the maximum grid energy is decreased.
130 * @param updateFactor Relative factor used to increase or decrease the maximum
131 * grid energy during adaptation.
132 * @param maxIterations Maximum number of grid adaptation iterations per EEDF
133 * solve.
134 * @param maxwellianReset Boolean flag to reset the EEDF to a Maxwellian
135 * distribution at the gas temperature when grid adaptation
136 * is activated.
137 * @since New in %Cantera 4.0
138 */
139 void setGridAdaptationParameters(double minDecayDecades, double maxDecayDecades,
140 double updateFactor, size_t maxIterations,
141 bool maxwellianReset);
142
143 //! Return the electron energy grid edges [eV].
144 /*!
145 * The returned span contains m_points + 1 values corresponding to cell boundaries.
146 */
147 //! @since New in %Cantera 4.0
148 span<const double> getGridEdge() const {
149 return m_gridEdge;
150 }
151
152 //! Return the EEDF values interpolated at the electron energy grid edges.
153 /*!
154 * These values are copied back to PlasmaPhase after a successful
155 * Boltzmann-two-term EEDF solve.
156 */
157 //! @since New in %Cantera 4.0
158 span<const double> getEEDFEdge() const {
159 return m_f0_edge;
160 }
161
162 //! Return the latest value of the computed electron mobility computed from the EEDF
163 //! @since New in %Cantera 4.0
164 double getElectronMobility() const {
165 return m_electronMobility;
166 }
167 //! Sets the threshold in reduced electric field below which a Maxwellian is imposed
168 //! instead of computing the EEDF.
169 //! @param threshold The threshold in Td.
170 //! @since New in %Cantera 4.0
172 m_thresholdToMaxwellian = threshold;
173 }
174
175protected:
176
177 //! Formerly options for the EEDF solver
178
179 //! The first step size
180 double m_delta0 = 1e14;
181
182 //! Maximum number of iterations
183 size_t m_maxn = 200;
184
185 //! The factor for step size change
186 double m_factorM = 4.0;
187
188 //! The number of points in the EEDF grid
189 size_t m_points = 150;
190
191 //! Error tolerance for convergence
192 double m_rtol = 1e-5;
193
194 //! The growth model of EEDF
195 std::string m_growth = "temporal";
196
197 //! The threshold for species mole fractions
199
200 //! The initial electron temperature [eV]
201 double m_init_kTe = 2.0;
202
203 //! Pointer to the PlasmaPhase object used to initialize this object.
204 /*!
205 * This PlasmaPhase object provides species, element, and cross-section
206 * data used by the EEDF solver. It is set during construction and is not
207 * modified afterwards. All subsequent calls to compute functions must
208 * use the same PlasmaPhase context.
209 */
211
212 //! Iterate f0 (EEDF) until convergence
213 void converge(Eigen::VectorXd& f0);
214
215 //! An iteration of solving electron energy distribution function
216 Eigen::VectorXd iterate(const Eigen::VectorXd& f0, double delta);
217
218 //! The integral in [a, b] of \f$x u(x) \exp[g (x_0 - x)]\f$
219 //! assuming that u is linear with u(a) = u0 and u(b) = u1
220 double integralPQ(double a, double b, double u0, double u1,
221 double g, double x0);
222
223 //! Vector g is used by matrix_P() and matrix_Q().
224 /**
225 * \f[
226 * g_i = \frac{1}{\epsilon_{i+1} - \epsilon_{i-1}} \ln(\frac{F_{0, i+1}}{F_{0, i-1}})
227 * \f]
228 */
229 vector<double> vector_g(const Eigen::VectorXd& f0);
230
231 //! The matrix of scattering-out.
232 /**
233 * \f[
234 * P_{i,k} = \gamma \int_{\epsilon_i - 1/2}^{\epsilon_i + 1/2}
235 * \epsilon \sigma_k exp[(\epsilon_i - \epsilon)g_i] d \epsilon
236 * \f]
237 */
238 Eigen::SparseMatrix<double> matrix_P(span<const double> g, size_t k);
239
240 //! The matrix of scattering-in
241 /**
242 * \f[
243 * Q_{i,j,k} = \gamma \int_{\epsilon_1}^{\epsilon_2}
244 * \epsilon \sigma_k exp[(\epsilon_j - \epsilon)g_j] d \epsilon
245 * \f]
246 */
247 //! where the interval \f$[\epsilon_1, \epsilon_2]\f$ is the overlap of cell j,
248 //! and cell i shifted by the threshold energy:
249 /**
250 * \f[
251 * \epsilon_1 = \min(\max(\epsilon_{i-1/2}+u_k, \epsilon_{j-1/2}),\epsilon_{j+1/2}),
252 * \f]
253 * \f[
254 * \epsilon_2 = \min(\max(\epsilon_{i+1/2}+u_k, \epsilon_{j-1/2}),\epsilon_{j+1/2})
255 * \f]
256 */
257 Eigen::SparseMatrix<double> matrix_Q(span<const double> g, size_t k);
258
259 //! Matrix A (Ax = b) of the equation of EEDF, which is discretized by the exponential scheme
260 //! of Scharfetter and Gummel,
261 /**
262 * \f[
263 * \left[ \tilde{W} F_0 - \tilde{D} \frac{d F_0}{\epsilon} \right]_{i+1/2} =
264 * \frac{\tilde{W}_{i+1/2} F_{0,i}}{1 - \exp[-z_{i+1/2}]} +
265 * \frac{\tilde{W}_{i+1/2} F_{0,i+1}}{1 - \exp[z_{i+1/2}]}
266 * \f]
267 * where \f$ z_{i+1/2} = \tilde{w}_{i+1/2} / \tilde{D}_{i+1/2} \f$ (Peclet number).
268 */
269 Eigen::SparseMatrix<double> matrix_A(const Eigen::VectorXd& f0);
270
271 //! Reduced net production frequency. Equation (10) of ref. [1]
272 //! divided by N.
273 //! @param f0 EEDF
274 double netProductionFrequency(const Eigen::VectorXd& f0);
275
276 //! Diffusivity
277 double electronDiffusivity(const Eigen::VectorXd& f0);
278
279 //! Mobility
280 double electronMobility(const Eigen::VectorXd& f0);
281
282 //! Initialize species indices associated with cross-section data
284
285 //! Update the total cross sections based on the current state
286 void updateCrossSections();
287
288 //! Update the vector of species mole fractions
289 void updateMoleFractions();
290
291 //! Compute the total elastic collision cross section
293
294 //! Compute the total (elastic + inelastic) cross section
296
297 //! Compute the L1 norm of a function f defined over a given energy grid.
298 //!
299 //! @param f Vector representing the function values (EEDF)
300 //! @param grid Vector representing the energy grid corresponding to f
301 double norm(const Eigen::VectorXd& f, const Eigen::VectorXd& grid);
302
303 //! Electron mobility [m²/V·s]
305
306 //! Grid of electron energy (cell center) [eV]
307 Eigen::VectorXd m_gridCenter;
308
309 //! Grid of electron energy (cell boundary i-1/2) [eV]
310 vector<double> m_gridEdge;
311
312 //! Location of cell j for grid cache
313 vector<vector<size_t>> m_j;
314
315 //! Location of cell i for grid cache
316 vector<vector<size_t>> m_i;
317
318 //! Cross section at the boundaries of the overlap of cell i and j
319 vector<vector<vector<double>>> m_sigma;
320
321 //! The energy boundaries of the overlap of cell i and j
322 vector<vector<vector<double>>> m_eps;
323
324 //! Normalized electron energy distribution function
325 Eigen::VectorXd m_f0;
326
327 //! EEDF at grid edges (cell boundaries)
328 vector<double> m_f0_edge;
329
330 //! Total electron cross section on the cell center of energy grid
332
333 //! Total electron cross section on the cell boundary (i-1/2) of
334 //! energy grid
336
337 //! Vector of total elastic cross section weighted with mass ratio
338 vector<double> m_sigmaElastic;
339
340 //! List of target species indices in global Cantera numbering (1 index per cs)
341 vector<size_t> m_kTargets;
342
343 //! List of target species indices in local X EEDF numbering (1 index per cs)
344 vector<size_t> m_klocTargets;
345
346 //! Indices of species which has no cross-section data
347 vector<size_t> m_kOthers;
348
349 //! Local to global indices
350 vector<size_t> m_k_lg_Targets;
351
352 //! Mole fraction of targets
353 vector<double> m_X_targets;
354
355 //! Previous mole fraction of targets used to compute eedf
356 vector<double> m_X_targets_prev;
357
358 //! In factor. This is used for calculating the Q matrix of
359 //! scattering-in processes.
360 vector<int> m_inFactor;
361
362 //! Defined by the formula: pow(2.0 * ElectronCharge / ElectronMass, 0.5) and
363 //! comupted during phase initialization.
364 double m_gamma;
365
366 //! Flag of having an EEDF
368
369 //! First call to calculateDistributionFunction
371
372 //! Energy grid spacing type. Can be linear, quadratic or geometric.
373 string m_gridType = "linear";
374
375 //! Maximum value of the energy grid [eV].
376 double m_kTeMax = 60.0;
377
378 //! Number of cells for the starting energy grid.
379 size_t m_initialGridCells = 301;
380
381 //! Flag activating or deactivating automatic grid adaptation.
382 bool m_adaptGrid = false;
383
384 //! Minimum amount of decades decay at the tail of the EEDF when grid adaptation is
385 //! on.
386 double m_minEedfDecay = 10;
387
388 //! Maximum amount of decades decay at the tail of the EEDF when grid adaptation is
389 //! on.
390 double m_maxEedfDecay = 12.0;
391
392 //! Factor by which the EEDF grid maximum energy is increased of shrunk when grid
393 //! adaptation is on.
394 double m_gridUpdateFactor = 0.1;
395
396 //! Maximum number of iterations on the maximum energy accepted for grid adaptation.
398
399 //! Updates the grid according to the grid type and the new maximum energy when
400 //! running grid adaptation.
401 void updateGrid(double maxEnergy);
402
403 //! Runs the energy grid adaptation script when this feature is activated.
404 void adaptEnergyGrid();
405
406 //! Sets a Maxwellian distribution with the specified electron temperature [eV]
407 void setMaxwellianDistribution(double kTe);
408
409 //! Projects a previously converged EEDF onto the current energy grid.
410 //! Used as first guess after grid adaptation when Maxwellian reset is disabled.
411 //! @since New in %Cantera 4.0
412 void projectPreviousEEDFOnCurrentGrid(const Eigen::VectorXd& oldGridCenter,
413 const Eigen::VectorXd& oldF0);
414
415 //! An extension of the linearInterp function that returns specified values when the
416 //! input is out of bounds instead of returning one of the extremities of the list.
417 double linearInterpBounded(double x, span<const double> xpts,
418 span<const double> fpts, double below_value,
419 double above_value);
420
421 //! The threshold in reduced electric field [townsend, Td] below which no EEDF will
422 //! be computed, but a Maxwellian at the gas temperature will be imposed instead.
424
425 //! In the case where a geometric grid is employed, this stores the corresponding
426 //! geometric ratio.
427 double m_geometricRatio = 1.01;
428
429 //! Boolean flag to reset the EEDF to a Maxwellian distribution at the gas
430 //! temperature when the grid is adapted. This is a base parameter for the non-pro
431 //! user for code solidity. It can be disabled by the user and in this case the
432 //! previous EEDF will be projected onto the new grid instead of being reset to a
433 //! Maxwellian.
434 bool m_maxwellianReset = true;
435};
436
437} // end of namespace Cantera
438
439#endif
Boltzmann equation solver for the electron energy distribution function based on the two-term approxi...
double m_rtol
Error tolerance for convergence.
Eigen::VectorXd m_f0
Normalized electron energy distribution function.
vector< double > m_gridEdge
Grid of electron energy (cell boundary i-1/2) [eV].
void enableGridAdaptation(bool enabled)
Enable or disable automatic grid adaptation for the EEDF solver energy grid.
vector< vector< size_t > > m_i
Location of cell i for grid cache.
void calculateTotalCrossSection()
Compute the total (elastic + inelastic) cross section.
vector< vector< size_t > > m_j
Location of cell j for grid cache.
vector< double > m_X_targets_prev
Previous mole fraction of targets used to compute eedf.
double m_thresholdToMaxwellian
The threshold in reduced electric field [townsend, Td] below which no EEDF will be computed,...
void projectPreviousEEDFOnCurrentGrid(const Eigen::VectorXd &oldGridCenter, const Eigen::VectorXd &oldF0)
Projects a previously converged EEDF onto the current energy grid.
void adaptEnergyGrid()
Runs the energy grid adaptation script when this feature is activated.
vector< vector< vector< double > > > m_eps
The energy boundaries of the overlap of cell i and j.
double m_maxEedfDecay
Maximum amount of decades decay at the tail of the EEDF when grid adaptation is on.
void setGeometricGrid(double kTe_max, size_t ncell, double ratio=1.01)
Sets a geometric energy grid for the EEDF solver, defined by the maximum energy and the number of gri...
span< const double > getEEDFEdge() const
Return the EEDF values interpolated at the electron energy grid edges.
vector< vector< vector< double > > > m_sigma
Cross section at the boundaries of the overlap of cell i and j.
void setGridAdaptationParameters(double minDecayDecades, double maxDecayDecades, double updateFactor, size_t maxIterations, bool maxwellianReset)
Set parameters controlling automatic adaptation of the EEDF energy grid.
vector< size_t > m_k_lg_Targets
Local to global indices.
string m_gridType
Energy grid spacing type. Can be linear, quadratic or geometric.
double m_moleFractionThreshold
The threshold for species mole fractions.
bool m_first_call
First call to calculateDistributionFunction.
double m_kTeMax
Maximum value of the energy grid [eV].
size_t m_initialGridCells
Number of cells for the starting energy grid.
double m_gamma
Defined by the formula: pow(2.0 * ElectronCharge / ElectronMass, 0.5) and comupted during phase initi...
void converge(Eigen::VectorXd &f0)
Iterate f0 (EEDF) until convergence.
double m_delta0
Formerly options for the EEDF solver.
double electronDiffusivity(const Eigen::VectorXd &f0)
Diffusivity.
PlasmaPhase * m_phase
Pointer to the PlasmaPhase object used to initialize this object.
double norm(const Eigen::VectorXd &f, const Eigen::VectorXd &grid)
Compute the L1 norm of a function f defined over a given energy grid.
void updateMoleFractions()
Update the vector of species mole fractions.
vector< size_t > m_kTargets
List of target species indices in global Cantera numbering (1 index per cs)
void setCustomGrid(span< const double > levels)
Sets a custom energy grid for the EEDF solver, defined by the user-provided vector of energy levels.
void setReducedElectricFieldThresholdForMaxwellian(double threshold)
Sets the threshold in reduced electric field below which a Maxwellian is imposed instead of computing...
void setQuadraticGrid(double kTe_max, size_t ncell)
Sets a quadratic energy grid for the EEDF solver, defined by the maximum energy and the number of gri...
double electronMobility(const Eigen::VectorXd &f0)
Mobility.
void setMaxwellianDistribution(double kTe)
Sets a Maxwellian distribution with the specified electron temperature [eV].
Eigen::VectorXd m_gridCenter
Grid of electron energy (cell center) [eV].
size_t m_maxn
Maximum number of iterations.
Eigen::SparseMatrix< double > matrix_A(const Eigen::VectorXd &f0)
Matrix A (Ax = b) of the equation of EEDF, which is discretized by the exponential scheme of Scharfet...
Eigen::SparseMatrix< double > matrix_Q(span< const double > g, size_t k)
The matrix of scattering-in.
Eigen::VectorXd iterate(const Eigen::VectorXd &f0, double delta)
An iteration of solving electron energy distribution function.
double m_gridUpdateFactor
Factor by which the EEDF grid maximum energy is increased of shrunk when grid adaptation is on.
double getElectronMobility() const
Return the latest value of the computed electron mobility computed from the EEDF.
double m_electronMobility
Electron mobility [m²/V·s].
void setInitialGridParameters(double initialMaxEnergy, size_t nGridCells, const string &gridType)
Set the initial grid parameters used by generated EEDF grids.
size_t m_points
The number of points in the EEDF grid.
vector< size_t > m_kOthers
Indices of species which has no cross-section data.
double m_factorM
The factor for step size change.
void calculateTotalElasticCrossSection()
Compute the total elastic collision cross section.
double m_minEedfDecay
Minimum amount of decades decay at the tail of the EEDF when grid adaptation is on.
void updateCrossSections()
Update the total cross sections based on the current state.
size_t m_maxGridAdaptIterations
Maximum number of iterations on the maximum energy accepted for grid adaptation.
double m_geometricRatio
In the case where a geometric grid is employed, this stores the corresponding geometric ratio.
void initSpeciesIndexCrossSections()
Initialize species indices associated with cross-section data.
double m_init_kTe
The initial electron temperature [eV].
double netProductionFrequency(const Eigen::VectorXd &f0)
Reduced net production frequency.
double linearInterpBounded(double x, span< const double > xpts, span< const double > fpts, double below_value, double above_value)
An extension of the linearInterp function that returns specified values when the input is out of boun...
span< const double > getGridEdge() const
Return the electron energy grid edges [eV].
bool m_maxwellianReset
Boolean flag to reset the EEDF to a Maxwellian distribution at the gas temperature when the grid is a...
std::string m_growth
The growth model of EEDF.
void setGridCache()
Build or rebuild the grid-dependent cache used for scattering matrices.
int calculateDistributionFunction()
compute the EEDF given an electric field CQM The solver will take the species to consider and the set...
vector< double > m_totalCrossSectionEdge
Total electron cross section on the cell boundary (i-1/2) of energy grid.
Eigen::SparseMatrix< double > matrix_P(span< const double > g, size_t k)
The matrix of scattering-out.
vector< double > m_f0_edge
EEDF at grid edges (cell boundaries)
bool m_adaptGrid
Flag activating or deactivating automatic grid adaptation.
vector< size_t > m_klocTargets
List of target species indices in local X EEDF numbering (1 index per cs)
vector< double > m_X_targets
Mole fraction of targets.
void updateGrid(double maxEnergy)
Updates the grid according to the grid type and the new maximum energy when running grid adaptation.
double integralPQ(double a, double b, double u0, double u1, double g, double x0)
The integral in [a, b] of assuming that u is linear with u(a) = u0 and u(b) = u1.
vector< double > m_totalCrossSectionCenter
Total electron cross section on the cell center of energy grid.
vector< double > vector_g(const Eigen::VectorXd &f0)
Vector g is used by matrix_P() and matrix_Q().
vector< double > m_sigmaElastic
Vector of total elastic cross section weighted with mass ratio.
void setLinearGrid(double kTe_max, size_t ncell)
Sets a linear energy grid for the EEDF solver, defined by the maximum energy and the number of grid c...
Base class for handling plasma properties, specifically focusing on the electron energy distribution.
This file contains definitions of constants, types and terms that are used in internal routines and a...
Namespace for the Cantera kernel.
Definition AnyMap.cpp:595