Garfield++ 5.0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
MediumMagboltz.hh
Go to the documentation of this file.
1#ifndef G_MEDIUM_MAGBOLTZ_9
2#define G_MEDIUM_MAGBOLTZ_9
3
4#include <mutex>
5#include <array>
6
8#include "MediumGas.hh"
9
10namespace Garfield {
11
12/// Interface to %Magboltz (version 11).
13/// - http://magboltz.web.cern.ch/magboltz/
14
15class MediumMagboltz : public MediumGas {
16 public:
17 /// Default constructor.
19 /// Constructor.
20 MediumMagboltz(const std::string& gas1, const double f1 = 1.,
21 const std::string& gas2 = "", const double f2 = 0.,
22 const std::string& gas3 = "", const double f3 = 0.,
23 const std::string& gas4 = "", const double f4 = 0.,
24 const std::string& gas5 = "", const double f5 = 0.,
25 const std::string& gas6 = "", const double f6 = 0.);
26 /// Destructor
27 virtual ~MediumMagboltz() {}
28
29 /// Set the highest electron energy to be included
30 /// in the table of scattering rates.
31 bool SetMaxElectronEnergy(const double e);
32 /// Get the highest electron energy in the table of scattering rates.
33 double GetMaxElectronEnergy() const { return m_eMax; }
34
35 /// Set the highest photon energy to be included
36 /// in the table of scattering rates.
37 bool SetMaxPhotonEnergy(const double e);
38 /// Get the highest photon energy in the table of scattering rates.
39 double GetMaxPhotonEnergy() const { return m_eFinalGamma; }
40
41 /// Switch on/off anisotropic scattering (enabled by default)
42 void EnableAnisotropicScattering(const bool on = true) {
43 m_useAnisotropic = on;
44 m_isChanged = true;
45 }
46
47 /// Sample the secondary electron energy according to the Opal-Beaty model.
49 /// Sample the secondary electron energy according to the Green-Sawada model.
51 /// Sample the secondary electron energy from a flat distribution.
53
54 /// Switch on (microscopic) de-excitation handling.
55 void EnableDeexcitation();
56 /// Switch off (microscopic) de-excitation handling.
57 void DisableDeexcitation() { m_useDeexcitation = false; }
58 /// Switch on discrete photoabsorption levels.
60 /// Switch off discrete photoabsorption levels.
61 void DisableRadiationTrapping() { m_useRadTrap = false; }
62
63 bool EnablePenningTransfer() override;
64 bool EnablePenningTransfer(const double r, const double lambda) override;
65 bool EnablePenningTransfer(const double r, const double lambda,
66 std::string gasname) override;
67 void DisablePenningTransfer() override;
68 bool DisablePenningTransfer(std::string gasname) override;
69
70 /// Write the gas cross-section table to a file during the initialisation.
71 void EnableCrossSectionOutput(const bool on = true) { m_useCsOutput = on; }
72
73 /// Multiply all excitation cross-sections by a uniform scaling factor.
74 void SetExcitationScaling(const double r, std::string gasname);
75
76 /// Initialise the table of scattering rates (called internally when a
77 /// collision rate is requested and the gas mixture or other parameters
78 /// have changed).
79 bool Initialise(const bool verbose = false);
80
81 void PrintGas() override;
82
83 /// Get the overall null-collision rate [ns-1].
84 double GetElectronNullCollisionRate(const int band) override;
85 /// Get the (real) collision rate [ns-1] at a given electron energy e [eV].
86 double GetElectronCollisionRate(const double e, const int band) override;
87 /// Get the collision rate [ns-1] for a specific level.
88 double GetElectronCollisionRate(const double e, const unsigned int level,
89 const int band);
90 /// Sample the collision type.
91 bool ElectronCollision(const double e, int& type, int& level, double& e1,
92 double& dx, double& dy, double& dz,
93 std::vector<std::pair<Particle, double> >& secondaries,
94 int& ndxc, int& band) override;
95 void ComputeDeexcitation(int iLevel, int& fLevel);
96 unsigned int GetNumberOfDeexcitationProducts() const override {
97 return m_dxcProducts.size();
98 }
99 bool GetDeexcitationProduct(const unsigned int i, double& t, double& s,
100 int& type, double& energy) const override;
101
102 double GetPhotonCollisionRate(const double e) override;
103 bool GetPhotonCollision(const double e, int& type, int& level, double& e1,
104 double& ctheta, int& nsec, double& esec) override;
105
106 /// Reset the collision counters.
108 /// Get the total number of electron collisions.
109 unsigned int GetNumberOfElectronCollisions() const;
110 /// Get the number of collisions broken down by cross-section type.
111 unsigned int GetNumberOfElectronCollisions(unsigned int& nElastic,
112 unsigned int& nIonising,
113 unsigned int& nAttachment,
114 unsigned int& nInelastic,
115 unsigned int& nExcitation,
116 unsigned int& nSuperelastic) const;
117 /// Get the number of cross-section terms.
118 unsigned int GetNumberOfLevels();
119 /// Get detailed information about a given cross-section term i.
120 bool GetLevel(const unsigned int i, int& ngas, int& type, std::string& descr,
121 double& e);
122 /// Get the Penning transfer probability and distance of a specific level.
123 bool GetPenningTransfer(const unsigned int i, double& r, double& lambda);
124
125 /// Get the number of collisions for a specific cross-section term.
126 unsigned int GetNumberOfElectronCollisions(const unsigned int level) const;
127
128 /// Get the number of Penning transfers that occured since the last reset.
129 unsigned int GetNumberOfPenningTransfers() const { return m_nPenning; }
130
131 /// Get the total number of photon collisions.
132 unsigned int GetNumberOfPhotonCollisions() const;
133 /// Get number of photon collisions by collision type.
134 unsigned int GetNumberOfPhotonCollisions(unsigned int& nElastic,
135 unsigned int& nIonising,
136 unsigned int& nInelastic) const;
137
138 /// Take the thermal motion of the gas at the selected temperature
139 /// into account in the calculations done by Magboltz.
140 /// By the default, this feature is off (static gas at 0 K).
141 void EnableThermalMotion(const bool on = true) { m_useGasMotion = on; }
142 /// Let Magboltz determine the upper energy limit (this is the default)
143 /// or use the energy limit specified using SetMaxElectronEnergy).
144 void EnableAutoEnergyLimit(const bool on = true) { m_autoEnergyLimit = on; }
145
146 /** Run Magboltz for a given electric field, magnetic field and angle.
147 * \param[in] e electric field
148 * \param[in] b magnetic field
149 * \param[in] btheta angle between electric and magnetic field
150 * \param[in] ncoll number of collisions (in multiples of 10<sup>7</sup>)
151 to be simulated
152 * \param[in] verbose verbosity flag
153 * \param[out] vx,vy,vz drift velocity vector
154 * \param[out] dl,dt diffusion cofficients
155 * \param[out] alpha Townsend cofficient
156 * \param[out] eta attachment cofficient
157 * \param[out] lor Lorentz angle
158 * \param[out] vxerr,vyerr,vzerr errors on drift velocity
159 * \param[out] dlerr,dterr errors on diffusion coefficients
160 * \param[out] alphaerr,etaerr errors on Townsend/attachment coefficients
161 * \param[out] lorerr error on Lorentz angle
162 * \param[out] alphatof effective Townsend coefficient \f$(\alpha - \eta)\f$
163 * calculated using time-of-flight method
164 * \param[out] difftens components of the diffusion tensor (zz, xx, yy, xz, yz, xy)
165 */
166 void RunMagboltz(const double e, const double b, const double btheta,
167 const int ncoll, bool verbose, double& vx, double& vy,
168 double& vz, double& dl, double& dt, double& alpha,
169 double& eta, double& lor, double& vxerr, double& vyerr,
170 double& vzerr, double& dlerr, double& dterr,
171 double& alphaerr, double& etaerr, double& lorerr,
172 double& alphatof, std::array<double, 6>& difftens);
173
174 /// Generate a new gas table (can later be saved to file) by running
175 /// Magboltz for all electric fields, magnetic fields, and
176 /// angles in the currently set grid.
177 void GenerateGasTable(const int numCollisions = 10,
178 const bool verbose = true);
179
181
182 static int GetGasNumberMagboltz(const std::string& input);
183 private:
184 static constexpr int nEnergyStepsLog = 1000;
185 static constexpr int nEnergyStepsGamma = 5000;
186 static constexpr int nCsTypes = 7;
187 static constexpr int nCsTypesGamma = 4;
188
189 static const int DxcTypeRad;
190 static const int DxcTypeCollIon;
191 static const int DxcTypeCollNonIon;
192
193 /// Mutex.
194 std::mutex m_mutex;
195
196 /// Simulate thermal motion of the gas or not (when running Magboltz).
197 bool m_useGasMotion = false;
198 /// Automatic calculation of the energy limit by Magboltz or not.
199 bool m_autoEnergyLimit = true;
200
201 /// Max. electron energy in the collision rate tables.
202 double m_eMax;
203 /// Energy spacing in the linear part of the collision rate tables.
204 double m_eStep;
205 /// Inverse energy spacing.
206 double m_eStepInv;
207 double m_eHigh, m_eHighLog;
208 double m_lnStep;
209
210 /// Flag enabling/disabling output of cross-section table to file
211 bool m_useCsOutput = false;
212 /// Number of different cross-section types in the current gas mixture
213 unsigned int m_nTerms = 0;
214 /// Recoil energy parameter
215 std::array<double, m_nMaxGases> m_rgas;
216 std::array<double, m_nMaxGases> m_s2;
217 /// Opal-Beaty-Peterson splitting parameter [eV]
218 std::array<double, Magboltz::nMaxLevels> m_wOpalBeaty;
219 /// Green-Sawada splitting parameters [eV]
220 /// (&Gamma;s, &Gamma;b, Ts, Ta, Tb).
221 std::array<std::array<double, 5>, m_nMaxGases> m_parGreenSawada;
222 std::array<bool, m_nMaxGases> m_hasGreenSawada;
223 /// Sample secondary electron energies using Opal-Beaty parameterisation
224 bool m_useOpalBeaty = true;
225 /// Sample secondary electron energies using Green-Sawada parameterisation
226 bool m_useGreenSawada = false;
227
228 /// Energy loss
229 std::array<double, Magboltz::nMaxLevels> m_energyLoss;
230 /// Cross-section type
231 std::array<int, Magboltz::nMaxLevels> m_csType;
232
233 /// Fluorescence yield
234 std::array<double, Magboltz::nMaxLevels> m_yFluorescence;
235 /// Number of Auger electrons produced in a collision
236 std::array<unsigned int, Magboltz::nMaxLevels> m_nAuger1;
237 std::array<unsigned int, Magboltz::nMaxLevels> m_nAuger2;
238 /// Energy imparted to Auger electrons
239 std::array<double, Magboltz::nMaxLevels> m_eAuger1;
240 std::array<double, Magboltz::nMaxLevels> m_eAuger2;
241 std::array<unsigned int, Magboltz::nMaxLevels> m_nFluorescence;
242 std::array<double, Magboltz::nMaxLevels> m_eFluorescence;
243
244 // Parameters for calculation of scattering angles
245 bool m_useAnisotropic = true;
246 std::vector<std::vector<double> > m_scatPar;
247 std::vector<std::vector<double> > m_scatCut;
248 std::vector<std::vector<double> > m_scatParLog;
249 std::vector<std::vector<double> > m_scatCutLog;
250 std::array<int, Magboltz::nMaxLevels> m_scatModel;
251
252 /// Level description
253 std::vector<std::string> m_description;
254
255 // Total collision frequency
256 std::vector<double> m_cfTot;
257 std::vector<double> m_cfTotLog;
258 /// Null-collision frequency
259 double m_cfNull = 0.;
260 // Collision frequencies
261 std::vector<std::vector<double> > m_cf;
262 std::vector<std::vector<double> > m_cfLog;
263
264 /// Collision counters
265 /// 0: elastic
266 /// 1: ionisation
267 /// 2: attachment
268 /// 3: inelastic
269 /// 4: excitation
270 /// 5: super-elastic
271 std::array<unsigned int, nCsTypes> m_nCollisions;
272 /// Number of collisions for each cross-section term
273 std::vector<unsigned int> m_nCollisionsDetailed;
274
275 // Penning transfer
276 /// Penning transfer probability (by level)
277 std::array<double, Magboltz::nMaxLevels> m_rPenning;
278 /// Mean distance of Penning ionisation (by level)
279 std::array<double, Magboltz::nMaxLevels> m_lambdaPenning;
280 /// Number of Penning ionisations
281 unsigned int m_nPenning = 0;
282
283 // Deexcitation
284 /// Flag enabling/disabling detailed simulation of de-excitation process
285 bool m_useDeexcitation = false;
286 /// Flag enabling/disable radiation trapping
287 /// (absorption of photons discrete excitation lines)
288 bool m_useRadTrap = true;
289
290 struct Deexcitation {
291 // Gas component
292 int gas;
293 // Associated cross-section term
294 int level;
295 // Level description
296 std::string label;
297 // Energy
298 double energy;
299 // Branching ratios
300 std::vector<double> p;
301 // Final levels
302 std::vector<int> final;
303 // Type of transition
304 std::vector<int> type;
305 // Oscillator strength
306 double osc;
307 // Total decay rate
308 double rate;
309 // Doppler broadening
310 double sDoppler;
311 // Pressure broadening
312 double gPressure;
313 // Effective width
314 double width;
315 // Integrated absorption collision rate
316 double cf;
317 };
318 std::vector<Deexcitation> m_deexcitations;
319 // Mapping between deexcitations and cross-section terms.
320 std::array<int, Magboltz::nMaxLevels> m_iDeexcitation;
321
322 // List of de-excitation products
323 struct dxcProd {
324 // Radial spread
325 double s;
326 // Time delay
327 double t;
328 // Type of deexcitation product
329 int type;
330 // Energy of the electron or photon
331 double energy;
332 };
333 std::vector<dxcProd> m_dxcProducts;
334
335 /// Ionisation potentials of each component
336 std::array<double, m_nMaxGases> m_ionPot;
337 /// Minimum ionisation potential
338 double m_minIonPot = -1.;
339
340 // Scaling factor for excitation cross-sections
341 std::array<double, m_nMaxGases> m_scaleExc;
342
343 // Energy spacing of photon collision rates table
344 double m_eFinalGamma, m_eStepGamma;
345 // Number of photon collision cross-section terms
346 unsigned int m_nPhotonTerms = 0;
347 // Total photon collision frequencies
348 std::vector<double> m_cfTotGamma;
349 // Photon collision frequencies
350 std::vector<std::vector<double> > m_cfGamma;
351 std::vector<int> csTypeGamma;
352 // Photon collision counters
353 // 0: elastic
354 // 1: ionisation
355 // 2: inelastic
356 // 3: excitation
357 std::array<unsigned int, nCsTypesGamma> m_nPhotonCollisions;
358
359 bool Update(const bool verbose = false);
360 bool Mixer(const bool verbose = false);
361 void SetupGreenSawada();
362
363 void GetExcitationIonisationLevels();
364
365 void ComputeDeexcitationTable(const bool verbose);
366 void AddPenningDeexcitation(Deexcitation& dxc, const double rate,
367 const double pPenning) {
368 dxc.p.push_back(rate * (1. - pPenning));
369 dxc.type.push_back(DxcTypeCollNonIon);
370 dxc.final.push_back(-1);
371 if (pPenning > 0.) {
372 dxc.p.push_back(rate * pPenning);
373 dxc.type.push_back(DxcTypeCollIon);
374 dxc.final.push_back(-1);
375 }
376 }
377 double RateConstantWK(const double energy, const double osc,
378 const double pacs, const int igas1,
379 const int igas2) const;
380 double RateConstantHardSphere(const double r1, const double r2,
381 const int igas1, const int igas2) const;
382 void ComputeDeexcitationInternal(int iLevel, int& fLevel);
383 bool ComputePhotonCollisionTable(const bool verbose);
384};
385}
386#endif
static constexpr unsigned int m_nMaxGases
Definition MediumGas.hh:161
MediumGas()
Constructor.
Definition MediumGas.cc:115
void SetSplittingFunctionGreenSawada()
Sample the secondary electron energy according to the Green-Sawada model.
bool EnablePenningTransfer() override
void EnableAnisotropicScattering(const bool on=true)
Switch on/off anisotropic scattering (enabled by default)
unsigned int GetNumberOfLevels()
Get the number of cross-section terms.
void SetExcitationScaling(const double r, std::string gasname)
Multiply all excitation cross-sections by a uniform scaling factor.
bool GetLevel(const unsigned int i, int &ngas, int &type, std::string &descr, double &e)
Get detailed information about a given cross-section term i.
double GetElectronNullCollisionRate(const int band) override
Get the overall null-collision rate [ns-1].
virtual ~MediumMagboltz()
Destructor.
void ResetCollisionCounters()
Reset the collision counters.
void EnableRadiationTrapping()
Switch on discrete photoabsorption levels.
unsigned int GetNumberOfElectronCollisions() const
Get the total number of electron collisions.
double GetPhotonCollisionRate(const double e) override
bool ElectronCollision(const double e, int &type, int &level, double &e1, double &dx, double &dy, double &dz, std::vector< std::pair< Particle, double > > &secondaries, int &ndxc, int &band) override
Sample the collision type.
void EnableAutoEnergyLimit(const bool on=true)
void RunMagboltz(const double e, const double b, const double btheta, const int ncoll, bool verbose, double &vx, double &vy, double &vz, double &dl, double &dt, double &alpha, double &eta, double &lor, double &vxerr, double &vyerr, double &vzerr, double &dlerr, double &dterr, double &alphaerr, double &etaerr, double &lorerr, double &alphatof, std::array< double, 6 > &difftens)
void ComputeDeexcitation(int iLevel, int &fLevel)
void SetSplittingFunctionOpalBeaty()
Sample the secondary electron energy according to the Opal-Beaty model.
static int GetGasNumberMagboltz(const std::string &input)
void GenerateGasTable(const int numCollisions=10, const bool verbose=true)
double GetMaxElectronEnergy() const
Get the highest electron energy in the table of scattering rates.
bool GetDeexcitationProduct(const unsigned int i, double &t, double &s, int &type, double &energy) const override
void SetSplittingFunctionFlat()
Sample the secondary electron energy from a flat distribution.
MediumMagboltz()
Default constructor.
unsigned int GetNumberOfPenningTransfers() const
Get the number of Penning transfers that occured since the last reset.
double GetMaxPhotonEnergy() const
Get the highest photon energy in the table of scattering rates.
unsigned int GetNumberOfPhotonCollisions() const
Get the total number of photon collisions.
bool SetMaxPhotonEnergy(const double e)
void DisablePenningTransfer() override
Switch the simulation of Penning transfers off globally.
bool GetPhotonCollision(const double e, int &type, int &level, double &e1, double &ctheta, int &nsec, double &esec) override
bool GetPenningTransfer(const unsigned int i, double &r, double &lambda)
Get the Penning transfer probability and distance of a specific level.
unsigned int GetNumberOfDeexcitationProducts() const override
void DisableDeexcitation()
Switch off (microscopic) de-excitation handling.
void EnableCrossSectionOutput(const bool on=true)
Write the gas cross-section table to a file during the initialisation.
void DisableRadiationTrapping()
Switch off discrete photoabsorption levels.
bool Initialise(const bool verbose=false)
double GetElectronCollisionRate(const double e, const int band) override
Get the (real) collision rate [ns-1] at a given electron energy e [eV].
bool SetMaxElectronEnergy(const double e)
void EnableThermalMotion(const bool on=true)
void PrintGas() override
Print information about the present gas mixture and available data.
void EnableDeexcitation()
Switch on (microscopic) de-excitation handling.