Garfield 0.3
Toolkit for the detailed simulation of particle detectors based on ionization measurement in gases and semiconductors
Loading...
Searching...
No Matches
MediumMagboltz.hh
Go to the documentation of this file.
1#if defined(__GPUCOMPILE__) || !defined(G_MEDIUM_MAGBOLTZ_11)
2
3#if !defined(__GPUCOMPILE__) && !defined(G_MEDIUM_MAGBOLTZ_11)
4#define G_MEDIUM_MAGBOLTZ_11
5#endif
6
7#ifndef __GPUCOMPILE__
8#include <array>
9#include <mutex>
10#endif
12#include "Garfield/MediumGas.hh"
13#ifndef __GPUCOMPILE__
14
15class TPad;
16
17namespace Garfield {
18
21
22class MediumMagboltz : public MediumGas {
23 public:
27 MediumMagboltz(const std::string& gas1, const double f1 = 1.,
28 const std::string& gas2 = "", const double f2 = 0.,
29 const std::string& gas3 = "", const double f3 = 0.,
30 const std::string& gas4 = "", const double f4 = 0.,
31 const std::string& gas5 = "", const double f5 = 0.,
32 const std::string& gas6 = "", const double f6 = 0.);
34 virtual ~MediumMagboltz() {}
35
38 bool SetMaxElectronEnergy(const double e);
40 double GetMaxElectronEnergy() const { return m_eMax; }
41
44 bool SetMaxPhotonEnergy(const double e);
46 double GetMaxPhotonEnergy() const { return m_eFinalGamma; }
47
49 void EnableAnisotropicScattering(const bool on = true) {
51 m_isChanged = true;
52 }
53
60
71 void SetLineWidth(const double n) { m_nAbsWidths = n; }
72
73 bool EnablePenningTransfer() override;
74 bool EnablePenningTransfer(const double r, const double lambda) override;
75 bool EnablePenningTransfer(const double r, const double lambda,
76 std::string gasname) override;
77 void DisablePenningTransfer() override;
78 bool DisablePenningTransfer(std::string gasname) override;
79
81 void EnableCrossSectionOutput(const bool on = true) { m_useCsOutput = on; }
82
84 void SetExcitationScaling(const double r, std::string gasname);
85
89 bool Initialise(const bool verbose = false);
90
91 void PrintGas() override;
92
93#endif
94
95#ifdef __GPUCOMPILE__
97 __device__ double GetElectronNullCollisionRate(const int band);
98#else
99double GetElectronNullCollisionRate(const int band) override;
100#endif
101
102#ifdef __GPUCOMPILE__
103 __device__ double GetElectronCollisionRate__MediumMagboltz(const double e,
104 const int band);
105#endif
106
107#ifndef __GPUCOMPILE__
109 double GetElectronCollisionRate(const double e, const int band) override;
111 double GetElectronCollisionRate(const double e, const unsigned int level,
112 const int band);
114 bool ElectronCollision(const double e, int& type, int& level, double& e1,
115 double& dx, double& dy, double& dz,
116 std::vector<Secondary>& secondaries,
117 int& band) override;
118 void ComputeDeexcitation(int iLevel, int& fLevel,
119 std::vector<Secondary>& secondaries);
120
121 double GetPhotonCollisionRate(const double e) override;
122 bool PhotonCollision(const double e, int& type, int& level, double& e1,
123 double& ctheta,
124 std::vector<Secondary>& secondaries) override;
125
129 unsigned int GetNumberOfElectronCollisions() const;
131 unsigned int GetNumberOfElectronCollisions(unsigned int& nElastic,
132 unsigned int& nIonising,
133 unsigned int& nAttachment,
134 unsigned int& nInelastic,
135 unsigned int& nExcitation,
136 unsigned int& nSuperelastic) const;
138 unsigned int GetNumberOfLevels();
140 bool GetLevel(const unsigned int i, int& ngas, int& type, std::string& descr,
141 double& e);
143 bool GetPenningTransfer(const unsigned int i, double& r, double& lambda);
144
146 unsigned int GetNumberOfElectronCollisions(const unsigned int level) const;
147
149 unsigned int GetNumberOfPenningTransfers() const { return m_nPenning; }
150
152 unsigned int GetNumberOfPhotonCollisions() const;
154 unsigned int GetNumberOfPhotonCollisions(unsigned int& nElastic,
155 unsigned int& nIonising,
156 unsigned int& nInelastic) const;
157
161 void EnableThermalMotion(const bool on = true) { m_useGasMotion = on; }
164 void EnableAutoEnergyLimit(const bool on = true) { m_autoEnergyLimit = on; }
165
192 void RunMagboltz(const double e, const double b, const double btheta,
193 const int ncoll, bool verbose, double& vx, double& vy,
194 double& vz, double& wv, double& wr, double& dl, double& dt,
195 double& alpha, double& eta, double& riontof, double& ratttof,
196 double& lor, double& vxerr, double& vyerr, double& vzerr,
197 double& wverr, double& wrerr, double& dlerr, double& dterr,
198 double& alphaerr, double& etaerr, double& riontoferr,
199 double& ratttoferr, double& lorerr, double& alphatof,
200 std::array<double, 6>& difftens);
201
205 void GenerateGasTable(const int numCollisions = 10,
206 const bool verbose = true);
207
208 void PlotElectronCrossSections(const unsigned int i, TPad* pad);
211
212 static int GetGasNumberMagboltz(const std::string& input);
213 double CreateGPUTransferObject(MediumGPU*& med_gpu) override;
214
215 private:
216#endif
217 static constexpr int nEnergyStepsLog = 1000;
218 static constexpr int nEnergyStepsGamma = 5000;
219 static constexpr int nCsTypes = 7;
220
221#ifndef __GPUCOMPILE__
222 static constexpr int nCsTypesGamma = 4;
223
224 static const int DxcTypeRad;
225 static const int DxcTypeCollIon;
226 static const int DxcTypeCollNonIon;
227
229 std::mutex m_mutex;
230
232 bool m_useGasMotion = false;
234 bool m_autoEnergyLimit = true;
235#endif
236
238 double m_eMax;
240 double m_eStep;
244 double m_lnStep;
245
247 bool m_useCsOutput = false;
249 unsigned int m_nTerms = 0;
250#ifndef __GPUCOMPILE__
252 std::array<double, m_nMaxGases> m_mgas;
254 std::array<double, m_nMaxGases> m_rgas;
255 std::array<double, m_nMaxGases> m_s2;
257 std::array<double, Magboltz::nMaxLevels> m_wOpalBeaty;
260 std::array<std::array<double, 5>, m_nMaxGases> m_parGreenSawada;
261 std::array<bool, m_nMaxGases> m_hasGreenSawada;
262#endif
264 bool m_useOpalBeaty = true;
266 bool m_useGreenSawada = false;
267
268#ifdef __GPUCOMPILE__
271
272 double** m_scatPar{nullptr};
273 int* m_numscatParIdx{nullptr};
274 int m_numscatPar{0};
275
276 double** m_scatCut{nullptr};
277 int* m_numscatCutIdx{nullptr};
278 int m_numscatCut{0};
279
280 double** m_scatParLog{nullptr};
281 int* m_numscatParLogIdx{nullptr};
282 int m_numscatParLog{0};
283
284 double** m_scatCutLog{nullptr};
285 int* m_numscatCutLogIdx{nullptr};
286 int m_numscatCutLog{0};
288
289 double* m_cfTot{nullptr};
290 int m_numcfTot{0};
291 double* m_cfTotLog{nullptr};
292 int m_numcfTotLog{0};
293
294 double** m_cf{nullptr};
295 int* m_numcfIdx{nullptr};
296 int m_numcf{0};
297
298 double** m_cfLog{nullptr};
299 int* m_numcfLogIdx{nullptr};
300 int m_numcfLog{0};
301#else
303std::array<double, Magboltz::nMaxLevels> m_energyLoss;
305std::array<int, Magboltz::nMaxLevels> m_csType;
306
308std::array<double, Magboltz::nMaxLevels> m_yFluorescence;
310std::array<unsigned int, Magboltz::nMaxLevels> m_nAuger1;
311std::array<unsigned int, Magboltz::nMaxLevels> m_nAuger2;
313std::array<double, Magboltz::nMaxLevels> m_eAuger1;
314std::array<double, Magboltz::nMaxLevels> m_eAuger2;
315std::array<unsigned int, Magboltz::nMaxLevels> m_nFluorescence;
316std::array<double, Magboltz::nMaxLevels> m_eFluorescence;
317
318// Parameters for calculation of scattering angles
319std::vector<std::vector<double> > m_scatPar;
320std::vector<std::vector<double> > m_scatCut;
321std::vector<std::vector<double> > m_scatParLog;
322std::vector<std::vector<double> > m_scatCutLog;
323std::array<int, Magboltz::nMaxLevels> m_scatModel;
324
326std::vector<std::string> m_description;
327
328// Total collision frequency
329std::vector<double> m_cfTot;
330std::vector<double> m_cfTotLog;
331// Collision frequencies
332std::vector<std::vector<double> > m_cf;
333std::vector<std::vector<double> > m_cfLog;
334
335#endif
336 bool m_useAnisotropic = true;
338 double m_cfNull = 0.;
339#ifdef __GPUCOMPILE__
342
343 unsigned int m_nAuger1[Magboltz::nMaxLevels];
344 unsigned int m_nAuger2[Magboltz::nMaxLevels];
348
351 double m_rgas[m_nMaxGases];
352 double m_s2[m_nMaxGases];
353#endif
354
355#ifndef __GPUCOMPILE__
363 std::array<unsigned int, nCsTypes> m_nCollisions;
365 std::vector<unsigned int> m_nCollisionsDetailed;
366
367 // Penning transfer
369 std::array<double, Magboltz::nMaxLevels> m_rPenning;
371 std::array<double, Magboltz::nMaxLevels> m_lambdaPenning;
373 unsigned int m_nPenning = 0;
374
375 // Deexcitation
377 bool m_useDeexcitation = false;
380 bool m_useRadTrap = true;
381
383 // Gas component
384 int gas;
385 // Associated cross-section term
386 int level;
387 // Level description
388 std::string label;
389 // Energy
390 double energy;
391 // Branching ratios
392 std::vector<double> p;
393 // Final levels
394 std::vector<int> final;
395 // Type of transition
396 std::vector<int> type;
397 // Oscillator strength
398 double osc;
399 // Total decay rate
400 double rate;
401 // Doppler broadening
402 double sDoppler;
403 // Pressure broadening
404 double gPressure;
405 // Effective width
406 double width;
407 // Integrated absorption collision rate
408 double cf;
409 };
410 std::vector<Deexcitation> m_deexcitations;
411 // Mapping between deexcitations and cross-section terms.
412 std::array<int, Magboltz::nMaxLevels> m_iDeexcitation;
413 // Number of emission widths within which to conosider discrete line
414 // absorption.
415 // TODO: default value?
416 double m_nAbsWidths = 1000.;
417
419 std::array<double, m_nMaxGases> m_ionPot;
421 double m_minIonPot = -1.;
422
423 // Scaling factor for excitation cross-sections
424 std::array<double, m_nMaxGases> m_scaleExc;
425
426 // Energy spacing of photon collision rates table
428 // Number of photon collision cross-section terms
429 unsigned int m_nPhotonTerms = 0;
430 // Total photon collision frequencies
431 std::vector<double> m_cfTotGamma;
432 // Photon collision frequencies
433 std::vector<std::vector<double> > m_cfGamma;
434 std::vector<int> csTypeGamma;
435 // Photon collision counters
436 // 0: elastic
437 // 1: ionisation
438 // 2: inelastic
439 // 3: excitation
440 std::array<unsigned int, nCsTypesGamma> m_nPhotonCollisions;
441
442 bool Update(const bool verbose = false);
443 bool Mixer(const bool verbose = false);
445
447
448 void ComputeDeexcitationTable(const bool verbose);
449 void AddPenningDeexcitation(Deexcitation& dxc, const double rate,
450 const double pPenning) {
451 dxc.p.push_back(rate * (1. - pPenning));
452 dxc.type.push_back(DxcTypeCollNonIon);
453 dxc.final.push_back(-1);
454 if (pPenning > 0.) {
455 dxc.p.push_back(rate * pPenning);
456 dxc.type.push_back(DxcTypeCollIon);
457 dxc.final.push_back(-1);
458 }
459 }
460 double RateConstantWK(const double energy, const double osc,
461 const double pacs, const int igas1,
462 const int igas2) const;
463 double RateConstantHardSphere(const double r1, const double r2,
464 const int igas1, const int igas2) const;
465 double CalcDiscreteLineCf(const Deexcitation& dxc, double e,
466 double cfOth) const;
467 void ComputeDeexcitationInternal(int iLevel, int& fLevel,
468 std::vector<Secondary>& secondaries);
469 bool ComputePhotonCollisionTable(const bool verbose);
470};
471}
472#endif
473#endif
#define __device__
Definition Vector.hh:12
static constexpr unsigned int m_nMaxGases
Definition MediumGas.hh:174
MediumGas()
Constructor.
std::array< double, Magboltz::nMaxLevels > m_eAuger2
void RunMagboltz(const double e, const double b, const double btheta, const int ncoll, bool verbose, double &vx, double &vy, double &vz, double &wv, double &wr, double &dl, double &dt, double &alpha, double &eta, double &riontof, double &ratttof, double &lor, double &vxerr, double &vyerr, double &vzerr, double &wverr, double &wrerr, double &dlerr, double &dterr, double &alphaerr, double &etaerr, double &riontoferr, double &ratttoferr, double &lorerr, double &alphatof, std::array< double, 6 > &difftens)
Run Magboltz for a given electric field, magnetic field and angle.
bool EnablePenningTransfer(const double r, const double lambda) override
Switch on simulation of Penning transfers by means of transfer probabilities, for all excitation leve...
std::array< unsigned int, nCsTypes > m_nCollisions
Collision counters 0: elastic 1: ionisation 2: attachment 3: inelastic 4: excitation 5: super-elastic...
void SetSplittingFunctionGreenSawada()
Sample the secondary electron energy according to the Green-Sawada model.
double RateConstantHardSphere(const double r1, const double r2, const int igas1, const int igas2) const
std::vector< std::vector< double > > m_scatParLog
bool EnablePenningTransfer() override
Switch on simulation of Penning transfers, using pre-implemented parameterisations of the transfer pr...
std::array< double, m_nMaxGases > m_mgas
Mass.
void EnableAnisotropicScattering(const bool on=true)
Switch on/off anisotropic scattering (enabled by default)
unsigned int GetNumberOfPhotonCollisions(unsigned int &nElastic, unsigned int &nIonising, unsigned int &nInelastic) const
Get number of photon collisions by collision type.
std::array< double, Magboltz::nMaxLevels > m_eAuger1
Energy imparted to Auger electrons.
std::array< double, Magboltz::nMaxLevels > m_yFluorescence
Fluorescence yield.
unsigned int GetNumberOfLevels()
Get the number of cross-section terms.
static int GetGasNumberMagboltz(const std::string &input)
bool ComputePhotonCollisionTable(const bool verbose)
void SetExcitationScaling(const double r, std::string gasname)
Multiply all excitation cross-sections by a uniform scaling factor.
bool EnablePenningTransfer(const double r, const double lambda, std::string gasname) override
Switch on simulation of Penning transfers by means of transfer probabilities, for all excitations of ...
bool m_useDeexcitation
Flag enabling/disabling detailed simulation of de-excitation process.
void PlotElectronInverseMeanFreePath(TPad *pad)
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.
bool m_useCsOutput
Flag enabling/disabling output of cross-section table to file.
bool ElectronCollision(const double e, int &type, int &level, double &e1, double &dx, double &dy, double &dz, std::vector< Secondary > &secondaries, int &band) override
Sample the collision type.
std::array< int, Magboltz::nMaxLevels > m_csType
Cross-section type.
double GetElectronNullCollisionRate(const int band) override
std::array< unsigned int, Magboltz::nMaxLevels > m_nAuger1
Number of Auger electrons produced in a collision.
std::array< double, Magboltz::nMaxLevels > m_rPenning
Penning transfer probability (by level)
virtual ~MediumMagboltz()
Destructor.
void ResetCollisionCounters()
Reset the collision counters.
std::array< double, m_nMaxGases > m_s2
void SetLineWidth(const double n)
Set the number of emission line widths within which to apply absorption by discrete lines.
void EnableRadiationTrapping()
Switch on discrete photoabsorption levels.
std::array< double, Magboltz::nMaxLevels > m_energyLoss
Energy loss.
double GetElectronCollisionRate(const double e, const unsigned int level, const int band)
Get the collision rate [ns-1] for a specific level.
unsigned int m_nPenning
Number of Penning ionisations.
std::vector< std::vector< double > > m_scatPar
std::vector< std::vector< double > > m_cf
static const int DxcTypeCollNonIon
MediumMagboltz(const std::string &gas1, const double f1=1., const std::string &gas2="", const double f2=0., const std::string &gas3="", const double f3=0., const std::string &gas4="", const double f4=0., const std::string &gas5="", const double f5=0., const std::string &gas6="", const double f6=0.)
Constructor.
unsigned int GetNumberOfElectronCollisions() const
Get the total number of electron collisions.
double GetPhotonCollisionRate(const double e) override
std::array< std::array< double, 5 >, m_nMaxGases > m_parGreenSawada
Green-Sawada splitting parameters [eV] (Γs, Γb, Ts, Ta, Tb).
bool m_useRadTrap
Flag enabling/disable radiation trapping (absorption of photons discrete excitation lines)
static constexpr int nEnergyStepsGamma
double m_eStep
Energy spacing in the linear part of the collision rate tables.
std::vector< std::vector< double > > m_cfGamma
void EnableAutoEnergyLimit(const bool on=true)
Let Magboltz determine the upper energy limit (this is the default) or use the energy limit specified...
void ComputeDeexcitationTable(const bool verbose)
std::array< double, m_nMaxGases > m_rgas
Recoil energy parameter.
double CreateGPUTransferObject(MediumGPU *&med_gpu) override
Create and initialise GPU Transfer class.
unsigned int GetNumberOfElectronCollisions(const unsigned int level) const
Get the number of collisions for a specific cross-section term.
bool m_useGasMotion
Simulate thermal motion of the gas or not (when running Magboltz).
std::vector< std::vector< double > > m_cfLog
void SetSplittingFunctionOpalBeaty()
Sample the secondary electron energy according to the Opal-Beaty model.
double CalcDiscreteLineCf(const Deexcitation &dxc, double e, double cfOth) const
double m_cfNull
Null-collision frequency.
void ComputeDeexcitation(int iLevel, int &fLevel, std::vector< Secondary > &secondaries)
bool DisablePenningTransfer(std::string gasname) override
Switch the simulation of Penning transfers off for a given component.
std::array< unsigned int, nCsTypesGamma > m_nPhotonCollisions
std::vector< Deexcitation > m_deexcitations
static const int DxcTypeRad
void GenerateGasTable(const int numCollisions=10, const bool verbose=true)
Generate a new gas table (can later be saved to file) by running Magboltz for all electric fields,...
static constexpr int nCsTypesGamma
bool m_useOpalBeaty
Sample secondary electron energies using Opal-Beaty parameterisation.
double GetMaxElectronEnergy() const
Get the highest electron energy in the table of scattering rates.
void SetSplittingFunctionFlat()
Sample the secondary electron energy from a flat distribution.
bool Mixer(const bool verbose=false)
std::array< double, Magboltz::nMaxLevels > m_lambdaPenning
Mean distance of Penning ionisation (by level)
MediumMagboltz()
Default constructor.
std::array< bool, m_nMaxGases > m_hasGreenSawada
unsigned int GetNumberOfPenningTransfers() const
Get the number of Penning transfers that occured since the last reset.
std::array< double, m_nMaxGases > m_scaleExc
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)
Set the highest photon energy to be included in the table of scattering rates.
void AddPenningDeexcitation(Deexcitation &dxc, const double rate, const double pPenning)
void DisablePenningTransfer() override
Switch the simulation of Penning transfers off globally.
bool m_useGreenSawada
Sample secondary electron energies using Green-Sawada parameterisation.
bool GetPenningTransfer(const unsigned int i, double &r, double &lambda)
Get the Penning transfer probability and distance of a specific level.
std::array< int, Magboltz::nMaxLevels > m_scatModel
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.
unsigned int GetNumberOfElectronCollisions(unsigned int &nElastic, unsigned int &nIonising, unsigned int &nAttachment, unsigned int &nInelastic, unsigned int &nExcitation, unsigned int &nSuperelastic) const
Get the number of collisions broken down by cross-section type.
std::array< int, Magboltz::nMaxLevels > m_iDeexcitation
static const int DxcTypeCollIon
std::array< unsigned int, Magboltz::nMaxLevels > m_nFluorescence
void PlotElectronCollisionRates(TPad *pad)
void ComputeDeexcitationInternal(int iLevel, int &fLevel, std::vector< Secondary > &secondaries)
static constexpr int nCsTypes
double m_eStepInv
Inverse energy spacing.
std::vector< std::string > m_description
Level description.
std::vector< double > m_cfTotGamma
static constexpr int nEnergyStepsLog
bool Initialise(const bool verbose=false)
Initialise the table of scattering rates (called internally when a collision rate is requested and th...
void PlotElectronCrossSections(const unsigned int i, TPad *pad)
bool Update(const bool verbose=false)
std::array< double, Magboltz::nMaxLevels > m_wOpalBeaty
Opal-Beaty-Peterson splitting parameter [eV].
std::array< double, Magboltz::nMaxLevels > m_eFluorescence
unsigned int m_nTerms
Number of different cross-section types in the current gas mixture.
std::vector< double > m_cfTotLog
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)
Set the highest electron energy to be included in the table of scattering rates.
void EnableThermalMotion(const bool on=true)
Take the thermal motion of the gas at the selected temperature into account in the calculations done ...
std::array< unsigned int, Magboltz::nMaxLevels > m_nAuger2
double m_minIonPot
Minimum ionisation potential.
std::vector< std::vector< double > > m_scatCut
double RateConstantWK(const double energy, const double osc, const double pacs, const int igas1, const int igas2) const
void PrintGas() override
Print information about the present gas mixture and available data.
bool PhotonCollision(const double e, int &type, int &level, double &e1, double &ctheta, std::vector< Secondary > &secondaries) override
bool m_autoEnergyLimit
Automatic calculation of the energy limit by Magboltz or not.
std::vector< std::vector< double > > m_scatCutLog
void EnableDeexcitation()
Switch on (microscopic) de-excitation handling.
std::array< double, m_nMaxGases > m_ionPot
Ionisation potentials of each component.
std::vector< double > m_cfTot
std::vector< int > csTypeGamma
std::vector< unsigned int > m_nCollisionsDetailed
Number of collisions for each cross-section term.
double m_eMax
Max. electron energy in the collision rate tables.
constexpr unsigned int nMaxLevels