Cantera  3.2.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.
69 int calculateDistributionFunction();
70
71 void setLinearGrid(double& kTe_max, size_t& ncell);
72
73 void setGridCache();
74
75 vector<double> getGridEdge() const {
76 return m_gridEdge;
77 }
78
79 vector<double> getEEDFEdge() const {
80 return m_f0_edge;
81 }
82
83 double getElectronMobility() const {
84 return m_electronMobility;
85 }
86
87protected:
88
89 //! Formerly options for the EEDF solver
90
91 //! The first step size
92 double m_delta0 = 1e14;
93
94 //! Maximum number of iterations
95 size_t m_maxn = 200;
96
97 //! The factor for step size change
98 double m_factorM = 4.0;
99
100 //! The number of points in the EEDF grid
101 size_t m_points = 150;
102
103 //! Error tolerance for convergence
104 double m_rtol = 1e-5;
105
106 //! The growth model of EEDF
107 std::string m_growth = "temporal";
108
109 //! The threshold for species mole fractions
111
112 //! The first guess for the EEDF
113 std::string m_firstguess = "maxwell";
114
115 //! The initial electron temperature [eV]
116 double m_init_kTe = 2.0;
117
118 //! Pointer to the PlasmaPhase object used to initialize this object.
119 /*!
120 * This PlasmaPhase object provides species, element, and cross-section
121 * data used by the EEDF solver. It is set during construction and is not
122 * modified afterwards. All subsequent calls to compute functions must
123 * use the same PlasmaPhase context.
124 */
126
127 //! Iterate f0 (EEDF) until convergence
128 void converge(Eigen::VectorXd& f0);
129
130 //! An iteration of solving electron energy distribution function
131 Eigen::VectorXd iterate(const Eigen::VectorXd& f0, double delta);
132
133 //! The integral in [a, b] of \f$x u(x) \exp[g (x_0 - x)]\f$
134 //! assuming that u is linear with u(a) = u0 and u(b) = u1
135 double integralPQ(double a, double b, double u0, double u1,
136 double g, double x0);
137
138 //! Vector g is used by matrix_P() and matrix_Q().
139 /**
140 * \f[
141 * g_i = \frac{1}{\epsilon_{i+1} - \epsilon_{i-1}} \ln(\frac{F_{0, i+1}}{F_{0, i-1}})
142 * \f]
143 */
144 vector<double> vector_g(const Eigen::VectorXd& f0);
145
146 //! The matrix of scattering-out.
147 /**
148 * \f[
149 * P_{i,k} = \gamma \int_{\epsilon_i - 1/2}^{\epsilon_i + 1/2}
150 * \epsilon \sigma_k exp[(\epsilon_i - \epsilon)g_i] d \epsilon
151 * \f]
152 */
153 Eigen::SparseMatrix<double> matrix_P(const vector<double>& g, size_t k);
154
155 //! The matrix of scattering-in
156 /**
157 * \f[
158 * Q_{i,j,k} = \gamma \int_{\epsilon_1}^{\epsilon_2}
159 * \epsilon \sigma_k exp[(\epsilon_j - \epsilon)g_j] d \epsilon
160 * \f]
161 */
162 //! where the interval \f$[\epsilon_1, \epsilon_2]\f$ is the overlap of cell j,
163 //! and cell i shifted by the threshold energy:
164 /**
165 * \f[
166 * \epsilon_1 = \min(\max(\epsilon_{i-1/2}+u_k, \epsilon_{j-1/2}),\epsilon_{j+1/2}),
167 * \f]
168 * \f[
169 * \epsilon_2 = \min(\max(\epsilon_{i+1/2}+u_k, \epsilon_{j-1/2}),\epsilon_{j+1/2})
170 * \f]
171 */
172 Eigen::SparseMatrix<double> matrix_Q(const vector<double>& g, size_t k);
173
174 //! Matrix A (Ax = b) of the equation of EEDF, which is discretized by the exponential scheme
175 //! of Scharfetter and Gummel,
176 /**
177 * \f[
178 * \left[ \tilde{W} F_0 - \tilde{D} \frac{d F_0}{\epsilon} \right]_{i+1/2} =
179 * \frac{\tilde{W}_{i+1/2} F_{0,i}}{1 - \exp[-z_{i+1/2}]} +
180 * \frac{\tilde{W}_{i+1/2} F_{0,i+1}}{1 - \exp[z_{i+1/2}]}
181 * \f]
182 * where \f$ z_{i+1/2} = \tilde{w}_{i+1/2} / \tilde{D}_{i+1/2} \f$ (Peclet number).
183 */
184 Eigen::SparseMatrix<double> matrix_A(const Eigen::VectorXd& f0);
185
186 //! Reduced net production frequency. Equation (10) of ref. [1]
187 //! divided by N.
188 //! @param f0 EEDF
189 double netProductionFrequency(const Eigen::VectorXd& f0);
190
191 //! Diffusivity
192 double electronDiffusivity(const Eigen::VectorXd& f0);
193
194 //! Mobility
195 double electronMobility(const Eigen::VectorXd& f0);
196
197 //! Initialize species indices associated with cross-section data
199
200 //! Update the total cross sections based on the current state
201 void updateCrossSections();
202
203 //! Update the vector of species mole fractions
204 void updateMoleFractions();
205
206 //! Compute the total elastic collision cross section
208
209 //! Compute the total (elastic + inelastic) cross section
211
212 //! Compute the L1 norm of a function f defined over a given energy grid.
213 //!
214 //! @param f Vector representing the function values (EEDF)
215 //! @param grid Vector representing the energy grid corresponding to f
216 double norm(const Eigen::VectorXd& f, const Eigen::VectorXd& grid);
217
218 //! Electron mobility [m²/V·s]
220
221 //! Grid of electron energy (cell center) [eV]
222 Eigen::VectorXd m_gridCenter;
223
224 //! Grid of electron energy (cell boundary i-1/2) [eV]
225 vector<double> m_gridEdge;
226
227 //! Location of cell j for grid cache
228 vector<vector<size_t>> m_j;
229
230 //! Location of cell i for grid cache
231 vector<vector<size_t>> m_i;
232
233 //! Cross section at the boundaries of the overlap of cell i and j
234 vector<vector<vector<double>>> m_sigma;
235
236 //! The energy boundaries of the overlap of cell i and j
237 vector<vector<vector<double>>> m_eps;
238
239 //! normalized electron energy distribution function
240 Eigen::VectorXd m_f0;
241
242 //! EEDF at grid edges (cell boundaries)
243 vector<double> m_f0_edge;
244
245 //! Total electron cross section on the cell center of energy grid
247
248 //! Total electron cross section on the cell boundary (i-1/2) of
249 //! energy grid
251
252 //! vector of total elastic cross section weighted with mass ratio
253 vector<double> m_sigmaElastic;
254
255 //! list of target species indices in global Cantera numbering (1 index per cs)
256 vector<size_t> m_kTargets;
257
258 //! list of target species indices in local X EEDF numbering (1 index per cs)
259 vector<size_t> m_klocTargets;
260
261 //! Indices of species which has no cross-section data
262 vector<size_t> m_kOthers;
263
264 //! Local to global indices
265 vector<size_t> m_k_lg_Targets;
266
267 //! Mole fraction of targets
268 vector<double> m_X_targets;
269
270 //! Previous mole fraction of targets used to compute eedf
271 vector<double> m_X_targets_prev;
272
273 //! in factor. This is used for calculating the Q matrix of
274 //! scattering-in processes.
275 vector<int> m_inFactor;
276
277 double m_gamma;
278
279 //! flag of having an EEDF
281
282 //! First call to calculateDistributionFunction
284}; // end of class EEDFTwoTermApproximation
285
286} // end of namespace Cantera
287
288#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].
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.
vector< vector< vector< double > > > m_eps
The energy boundaries of the overlap of cell i and j.
vector< vector< vector< double > > > m_sigma
Cross section at the boundaries of the overlap of cell i and j.
vector< size_t > m_k_lg_Targets
Local to global indices.
Eigen::SparseMatrix< double > matrix_Q(const vector< double > &g, size_t k)
The matrix of scattering-in.
double m_moleFractionThreshold
The threshold for species mole fractions.
bool m_first_call
First call to calculateDistributionFunction.
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)
double electronMobility(const Eigen::VectorXd &f0)
Mobility.
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::VectorXd iterate(const Eigen::VectorXd &f0, double delta)
An iteration of solving electron energy distribution function.
double m_electronMobility
Electron mobility [m²/V·s].
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.
void updateCrossSections()
Update the total cross sections based on the current state.
void initSpeciesIndexCrossSections()
Initialize species indices associated with cross-section data.
double m_init_kTe
The initial electron temperature [eV].
Eigen::SparseMatrix< double > matrix_P(const vector< double > &g, size_t k)
The matrix of scattering-out.
double netProductionFrequency(const Eigen::VectorXd &f0)
Reduced net production frequency.
std::string m_firstguess
The first guess for the EEDF.
std::string m_growth
The growth model of EEDF.
vector< double > m_totalCrossSectionEdge
Total electron cross section on the cell boundary (i-1/2) of energy grid.
vector< double > m_f0_edge
EEDF at grid edges (cell boundaries)
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.
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
Base class for handling plasma properties, specifically focusing on the electron energy distribution.
Definition PlasmaPhase.h:84
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