Garfield++ 3.0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
Garfield::MediumMagboltz Class Reference

#include <MediumMagboltz.hh>

+ Inheritance diagram for Garfield::MediumMagboltz:

Public Member Functions

 MediumMagboltz ()
 Constructor.
 
virtual ~MediumMagboltz ()
 Destructor.
 
bool SetMaxElectronEnergy (const double e)
 
double GetMaxElectronEnergy () const
 Get the highest electron energy in the table of scattering rates.
 
bool SetMaxPhotonEnergy (const double e)
 
double GetMaxPhotonEnergy () const
 Get the highest photon energy in the table of scattering rates.
 
void EnableEnergyRangeAdjustment (const bool on)
 
void EnableAnisotropicScattering (const bool on=true)
 Switch on/off anisotropic scattering (enabled by default)
 
void SetSplittingFunctionOpalBeaty ()
 Sample the secondary electron energy according to the Opal-Beaty model.
 
void SetSplittingFunctionGreenSawada ()
 Sample the secondary electron energy according to the Green-Sawada model.
 
void SetSplittingFunctionFlat ()
 Sample the secondary electron energy from a flat distribution.
 
void EnableDeexcitation ()
 Switch on (microscopic) de-excitation handling.
 
void DisableDeexcitation ()
 Switch off (microscopic) de-excitation handling.
 
void EnableRadiationTrapping ()
 Switch on discrete photoabsorption levels.
 
void DisableRadiationTrapping ()
 Switch off discrete photoabsorption levels.
 
bool EnablePenningTransfer (const double r, const double lambda) override
 
bool EnablePenningTransfer (const double r, const double lambda, std::string gasname) override
 
void DisablePenningTransfer () override
 Switch the simulation of Penning transfers off globally.
 
bool DisablePenningTransfer (std::string gasname) override
 Switch the simulation of Penning transfers off for a given component.
 
void EnableCrossSectionOutput (const bool on=true)
 Write the gas cross-section table to a file during the initialisation.
 
void SetExcitationScaling (const double r, std::string gasname)
 Multiply all excitation cross-sections by a uniform scaling factor.
 
bool Initialise (const bool verbose=false)
 
void PrintGas () override
 Print information about the present gas mixture and available data.
 
double GetElectronNullCollisionRate (const int band) override
 Get the overall null-collision rate [ns-1].
 
double GetElectronCollisionRate (const double e, const int band) override
 Get the (real) collision rate [ns-1] at a given electron energy e [eV].
 
double GetElectronCollisionRate (const double e, const unsigned int level, const int band)
 Get the collision rate [ns-1] for a specific level.
 
bool GetElectronCollision (const double e, int &type, int &level, double &e1, double &dx, double &dy, double &dz, std::vector< std::pair< int, double > > &secondaries, int &ndxc, int &band) override
 Sample the collision type.
 
void ComputeDeexcitation (int iLevel, int &fLevel)
 
unsigned int GetNumberOfDeexcitationProducts () const override
 
bool GetDeexcitationProduct (const unsigned int i, double &t, double &s, int &type, double &energy) const override
 
double GetPhotonCollisionRate (const double e) override
 
bool GetPhotonCollision (const double e, int &type, int &level, double &e1, double &ctheta, int &nsec, double &esec) override
 
void ResetCollisionCounters ()
 Reset the collision counters.
 
unsigned int GetNumberOfElectronCollisions () const
 Get the total number of electron collisions.
 
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.
 
unsigned int GetNumberOfLevels ()
 Get the number of cross-section terms.
 
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.
 
unsigned int GetNumberOfElectronCollisions (const unsigned int level) const
 Get the number of collisions for a specific cross-section term.
 
unsigned int GetNumberOfPenningTransfers () const
 Get the number of Penning transfers that occured since the last reset.
 
unsigned int GetNumberOfPhotonCollisions () const
 Get the total number of photon collisions.
 
unsigned int GetNumberOfPhotonCollisions (unsigned int &nElastic, unsigned int &nIonising, unsigned int &nInelastic) const
 Get number of photon collisions by collision type.
 
void EnableThermalMotion (const bool on=true)
 
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 GenerateGasTable (const int numCollisions=10, const bool verbose=true)
 
- Public Member Functions inherited from Garfield::MediumGas
 MediumGas ()
 Constructor.
 
virtual ~MediumGas ()
 Destructor.
 
bool IsGas () const override
 Is this medium a gas?
 
bool SetComposition (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.)
 Set the gas mixture.
 
void GetComposition (std::string &gas1, double &f1, std::string &gas2, double &f2, std::string &gas3, double &f3, std::string &gas4, double &f4, std::string &gas5, double &f5, std::string &gas6, double &f6)
 Retrieve the gas mixture.
 
void GetComponent (const unsigned int i, std::string &label, double &f) override
 Get the name and fraction of a given component.
 
void SetAtomicNumber (const double z) override
 Set the effective atomic number.
 
double GetAtomicNumber () const override
 Get the effective atomic number.
 
void SetAtomicWeight (const double a) override
 Set the effective atomic weight.
 
double GetAtomicWeight () const override
 Get the effective atomic weight.
 
void SetNumberDensity (const double n) override
 Set the number density [cm-3].
 
double GetNumberDensity () const override
 Get the number density [cm-3].
 
void SetMassDensity (const double rho) override
 Set the mass density [g/cm3].
 
double GetMassDensity () const override
 Get the mass density [g/cm3].
 
bool LoadGasFile (const std::string &filename)
 Read table of gas properties (transport parameters) from file.
 
bool WriteGasFile (const std::string &filename)
 Save the present table of gas properties (transport parameters) to a file.
 
bool MergeGasFile (const std::string &filename, const bool replaceOld)
 Read table of gas properties from and merge with the existing dataset.
 
virtual bool EnablePenningTransfer (const double r, const double lambda)
 
virtual bool EnablePenningTransfer (const double r, const double lambda, std::string gasname)
 
virtual void DisablePenningTransfer ()
 Switch the simulation of Penning transfers off globally.
 
virtual bool DisablePenningTransfer (std::string gasname)
 Switch the simulation of Penning transfers off for a given component.
 
virtual void PrintGas ()
 Print information about the present gas mixture and available data.
 
bool LoadIonMobility (const std::string &filename)
 Read a table of ion mobilities as function of electric field from file.
 
bool AdjustTownsendCoefficient ()
 
void ResetTables () override
 Reset all tables of transport parameters.
 
void SetExtrapolationMethodExcitationRates (const std::string &low, const std::string &high)
 
void SetExtrapolationMethodIonisationRates (const std::string &low, const std::string &high)
 
void SetInterpolationMethodExcitationRates (const unsigned int intrp)
 
void SetInterpolationMethodIonisationRates (const unsigned int intrp)
 
double ScaleElectricField (const double e) const override
 
double UnScaleElectricField (const double e) const override
 
double ScaleDiffusion (const double d) const override
 
double ScaleDiffusionTensor (const double d) const override
 
double ScaleTownsend (const double alpha) const override
 
double ScaleAttachment (const double eta) const override
 
double ScaleLorentzAngle (const double lor) const override
 
bool GetPhotoAbsorptionCrossSection (const double e, double &sigma, const unsigned int i) override
 
- Public Member Functions inherited from Garfield::Medium
 Medium ()
 Constructor.
 
virtual ~Medium ()
 Destructor.
 
int GetId () const
 Return the id number of the class instance.
 
const std::string & GetName () const
 Get the medium name/identifier.
 
virtual bool IsGas () const
 Is this medium a gas?
 
virtual bool IsSemiconductor () const
 Is this medium a semiconductor?
 
virtual bool IsConductor () const
 Is this medium a conductor?
 
void SetTemperature (const double t)
 Set the temperature [K].
 
double GetTemperature () const
 Get the temperature [K].
 
void SetPressure (const double p)
 
double GetPressure () const
 
void SetDielectricConstant (const double eps)
 Set the relative static dielectric constant.
 
double GetDielectricConstant () const
 Get the relative static dielectric constant.
 
unsigned int GetNumberOfComponents () const
 Get number of components of the medium.
 
virtual void GetComponent (const unsigned int i, std::string &label, double &f)
 Get the name and fraction of a given component.
 
virtual void SetAtomicNumber (const double z)
 Set the effective atomic number.
 
virtual double GetAtomicNumber () const
 Get the effective atomic number.
 
virtual void SetAtomicWeight (const double a)
 Set the effective atomic weight.
 
virtual double GetAtomicWeight () const
 Get the effective atomic weight.
 
virtual void SetNumberDensity (const double n)
 Set the number density [cm-3].
 
virtual double GetNumberDensity () const
 Get the number density [cm-3].
 
virtual void SetMassDensity (const double rho)
 Set the mass density [g/cm3].
 
virtual double GetMassDensity () const
 Get the mass density [g/cm3].
 
virtual void EnableDrift (const bool on=true)
 Switch electron/ion/hole on/off.
 
virtual void EnablePrimaryIonisation (const bool on=true)
 Make the medium ionisable or non-ionisable.
 
bool IsDriftable () const
 Is charge carrier transport enabled in this medium?
 
bool IsMicroscopic () const
 Does the medium have electron scattering rates?
 
bool IsIonisable () const
 Is charge deposition by charged particles/photon enabled in this medium?
 
void SetW (const double w)
 Set the W value (average energy to produce an electron/ion or e/h pair).
 
double GetW ()
 Get the W value.
 
void SetFanoFactor (const double f)
 Set the Fano factor.
 
double GetFanoFactor ()
 Get the Fano factor.
 
virtual bool ElectronVelocity (const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &vx, double &vy, double &vz)
 Drift velocity [cm / ns].
 
virtual bool ElectronDiffusion (const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &dl, double &dt)
 Longitudinal and transverse diffusion coefficients [cm1/2].
 
virtual bool ElectronDiffusion (const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double cov[3][3])
 
virtual bool ElectronTownsend (const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &alpha)
 Ionisation coefficient [cm-1].
 
virtual bool ElectronAttachment (const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &eta)
 Attachment coefficient [cm-1].
 
virtual bool ElectronLorentzAngle (const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &lor)
 Lorentz angle.
 
virtual double ElectronMobility ()
 Low-field mobility [cm2 V-1 ns-1].
 
virtual double GetElectronEnergy (const double px, const double py, const double pz, double &vx, double &vy, double &vz, const int band=0)
 Dispersion relation (energy vs. wave vector)
 
virtual void GetElectronMomentum (const double e, double &px, double &py, double &pz, int &band)
 
virtual double GetElectronNullCollisionRate (const int band=0)
 Null-collision rate [ns-1].
 
virtual double GetElectronCollisionRate (const double e, const int band=0)
 Collision rate [ns-1] for given electron energy.
 
virtual bool GetElectronCollision (const double e, int &type, int &level, double &e1, double &dx, double &dy, double &dz, std::vector< std::pair< int, double > > &secondaries, int &ndxc, int &band)
 Sample the collision type. Update energy and direction vector.
 
virtual unsigned int GetNumberOfDeexcitationProducts () const
 
virtual bool GetDeexcitationProduct (const unsigned int i, double &t, double &s, int &type, double &energy) const
 
virtual bool HoleVelocity (const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &vx, double &vy, double &vz)
 Drift velocity [cm / ns].
 
virtual bool HoleDiffusion (const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &dl, double &dt)
 Longitudinal and transverse diffusion coefficients [cm1/2].
 
virtual bool HoleDiffusion (const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double cov[3][3])
 Diffusion tensor.
 
virtual bool HoleTownsend (const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &alpha)
 Ionisation coefficient [cm-1].
 
virtual bool HoleAttachment (const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &eta)
 Attachment coefficient [cm-1].
 
virtual double HoleMobility ()
 Low-field mobility [cm2 V-1 ns-1].
 
virtual bool IonVelocity (const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &vx, double &vy, double &vz)
 Drift velocity [cm / ns].
 
virtual bool IonDiffusion (const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &dl, double &dt)
 Longitudinal and transverse diffusion coefficients [cm1/2].
 
virtual bool IonDissociation (const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &diss)
 Dissociation coefficient.
 
virtual double IonMobility ()
 Low-field mobility [cm2 V-1 ns-1].
 
void SetFieldGrid (double emin, double emax, const size_t ne, bool logE, double bmin=0., double bmax=0., const size_t nb=1, double amin=HalfPi, double amax=HalfPi, const size_t na=1)
 Set the range of fields to be covered by the transport tables.
 
void SetFieldGrid (const std::vector< double > &efields, const std::vector< double > &bfields, const std::vector< double > &angles)
 Set the fields and E-B angles to be used in the transport tables.
 
void GetFieldGrid (std::vector< double > &efields, std::vector< double > &bfields, std::vector< double > &angles)
 Get the fields and E-B angles used in the transport tables.
 
bool SetElectronVelocityE (const unsigned int ie, const unsigned int ib, const unsigned int ia, const double v)
 Set an entry in the table of drift speeds along E.
 
bool GetElectronVelocityE (const unsigned int ie, const unsigned int ib, const unsigned int ia, double &v)
 Get an entry in the table of drift speeds along E.
 
bool SetElectronVelocityExB (const unsigned int ie, const unsigned int ib, const unsigned int ia, const double v)
 Set an entry in the table of drift speeds along ExB.
 
bool GetElectronVelocityExB (const unsigned int ie, const unsigned int ib, const unsigned int ia, double &v)
 Get an entry in the table of drift speeds along ExB.
 
bool SetElectronVelocityB (const unsigned int ie, const unsigned int ib, const unsigned int ia, const double v)
 Set an entry in the table of drift speeds along Btrans.
 
bool GetElectronVelocityB (const unsigned int ie, const unsigned int ib, const unsigned int ia, double &v)
 Get an entry in the table of drift speeds along Btrans.
 
bool SetElectronLongitudinalDiffusion (const unsigned int ie, const unsigned int ib, const unsigned int ia, const double dl)
 Set an entry in the table of longitudinal diffusion coefficients.
 
bool GetElectronLongitudinalDiffusion (const unsigned int ie, const unsigned int ib, const unsigned int ia, double &dl)
 Get an entry in the table of longitudinal diffusion coefficients.
 
bool SetElectronTransverseDiffusion (const unsigned int ie, const unsigned int ib, const unsigned int ia, const double dt)
 Set an entry in the table of transverse diffusion coefficients.
 
bool GetElectronTransverseDiffusion (const unsigned int ie, const unsigned int ib, const unsigned int ia, double &dt)
 Get an entry in the table of transverse diffusion coefficients.
 
bool SetElectronTownsend (const unsigned int ie, const unsigned int ib, const unsigned int ia, const double alpha)
 Set an entry in the table of Townsend coefficients.
 
bool GetElectronTownsend (const unsigned int ie, const unsigned int ib, const unsigned int ia, double &alpha)
 Get an entry in the table of Townsend coefficients.
 
bool SetElectronAttachment (const unsigned int ie, const unsigned int ib, const unsigned int ia, const double eta)
 Set an entry in the table of attachment coefficients.
 
bool GetElectronAttachment (const unsigned int ie, const unsigned int ib, const unsigned int ia, double &eta)
 Get an entry in the table of attachment coefficients.
 
bool SetElectronLorentzAngle (const unsigned int ie, const unsigned int ib, const unsigned int ia, const double lor)
 Set an entry in the table of Lorentz angles.
 
bool GetElectronLorentzAngle (const unsigned int ie, const unsigned int ib, const unsigned int ia, double &lor)
 Get an entry in the table of Lorentz angles.
 
bool SetHoleVelocityE (const unsigned int ie, const unsigned int ib, const unsigned int ia, const double v)
 Set an entry in the table of drift speeds along E.
 
bool GetHoleVelocityE (const unsigned int ie, const unsigned int ib, const unsigned int ia, double &v)
 Get an entry in the table of drift speeds along E.
 
bool SetHoleVelocityExB (const unsigned int ie, const unsigned int ib, const unsigned int ia, const double v)
 Set an entry in the table of drift speeds along ExB.
 
bool GetHoleVelocityExB (const unsigned int ie, const unsigned int ib, const unsigned int ia, double &v)
 Get an entry in the table of drift speeds along ExB.
 
bool SetHoleVelocityB (const unsigned int ie, const unsigned int ib, const unsigned int ia, const double v)
 Set an entry in the table of drift speeds along Btrans.
 
bool GetHoleVelocityB (const unsigned int ie, const unsigned int ib, const unsigned int ia, double &v)
 Get an entry in the table of drift speeds along Btrans.
 
bool SetHoleLongitudinalDiffusion (const unsigned int ie, const unsigned int ib, const unsigned int ia, const double dl)
 Set an entry in the table of longitudinal diffusion coefficients.
 
bool GetHoleLongitudinalDiffusion (const unsigned int ie, const unsigned int ib, const unsigned int ia, double &dl)
 Get an entry in the table of longitudinal diffusion coefficients.
 
bool SetHoleTransverseDiffusion (const unsigned int ie, const unsigned int ib, const unsigned int ia, const double dt)
 Set an entry in the table of transverse diffusion coefficients.
 
bool GetHoleTransverseDiffusion (const unsigned int ie, const unsigned int ib, const unsigned int ia, double &dt)
 Get an entry in the table of transverse diffusion coefficients.
 
bool SetHoleTownsend (const unsigned int ie, const unsigned int ib, const unsigned int ia, const double alpha)
 Set an entry in the table of Townsend coefficients.
 
bool GetHoleTownsend (const unsigned int ie, const unsigned int ib, const unsigned int ia, double &alpha)
 Get an entry in the table of Townsend coefficients.
 
bool SetHoleAttachment (const unsigned int ie, const unsigned int ib, const unsigned int ia, const double eta)
 Set an entry in the table of attachment coefficients.
 
bool GetHoleAttachment (const unsigned int ie, const unsigned int ib, const unsigned int ia, double &eta)
 Get an entry in the table of attachment coefficients.
 
bool SetIonMobility (const std::vector< double > &fields, const std::vector< double > &mobilities)
 
bool SetIonMobility (const unsigned int ie, const unsigned int ib, const unsigned int ia, const double mu)
 Set an entry in the table of ion mobilities.
 
bool GetIonMobility (const unsigned int ie, const unsigned int ib, const unsigned int ia, double &mu)
 Get an entry in the table of ion mobilities.
 
bool SetIonLongitudinalDiffusion (const unsigned int ie, const unsigned int ib, const unsigned int ia, const double dl)
 Set an entry in the table of longitudinal diffusion coefficients.
 
bool GetIonLongitudinalDiffusion (const unsigned int ie, const unsigned int ib, const unsigned int ia, double &dl)
 Get an entry in the table of longitudinal diffusion coefficients.
 
bool SetIonTransverseDiffusion (const unsigned int ie, const unsigned int ib, const unsigned int ia, const double dt)
 Set an entry in the table of transverse diffusion coefficients.
 
bool GetIonTransverseDiffusion (const unsigned int ie, const unsigned int ib, const unsigned int ia, double &dt)
 Get an entry in the table of transverse diffusion coefficients.
 
bool SetIonDissociation (const unsigned int ie, const unsigned int ib, const unsigned int ia, const double diss)
 Set an entry in the table of dissociation coefficients.
 
bool GetIonDissociation (const unsigned int ie, const unsigned int ib, const unsigned int ia, double &diss)
 Get an entry in the table of dissociation coefficients.
 
virtual void ResetTables ()
 Reset all tables of transport parameters.
 
void ResetElectronVelocity ()
 
void ResetElectronDiffusion ()
 
void ResetElectronTownsend ()
 
void ResetElectronAttachment ()
 
void ResetElectronLorentzAngle ()
 
void ResetHoleVelocity ()
 
void ResetHoleDiffusion ()
 
void ResetHoleTownsend ()
 
void ResetHoleAttachment ()
 
void ResetIonMobility ()
 
void ResetIonDiffusion ()
 
void ResetIonDissociation ()
 
void SetExtrapolationMethodVelocity (const std::string &extrLow, const std::string &extrHigh)
 
void SetExtrapolationMethodDiffusion (const std::string &extrLow, const std::string &extrHigh)
 
void SetExtrapolationMethodTownsend (const std::string &extrLow, const std::string &extrHigh)
 
void SetExtrapolationMethodAttachment (const std::string &extrLow, const std::string &extrHigh)
 
void SetExtrapolationMethodIonMobility (const std::string &extrLow, const std::string &extrHigh)
 
void SetExtrapolationMethodIonDissociation (const std::string &extrLow, const std::string &extrHigh)
 
void SetInterpolationMethodVelocity (const unsigned int intrp)
 Set the degree of polynomial interpolation (usually 2).
 
void SetInterpolationMethodDiffusion (const unsigned int intrp)
 
void SetInterpolationMethodTownsend (const unsigned int intrp)
 
void SetInterpolationMethodAttachment (const unsigned int intrp)
 
void SetInterpolationMethodIonMobility (const unsigned int intrp)
 
void SetInterpolationMethodIonDissociation (const unsigned int intrp)
 
virtual double ScaleElectricField (const double e) const
 
virtual double UnScaleElectricField (const double e) const
 
virtual double ScaleVelocity (const double v) const
 
virtual double ScaleDiffusion (const double d) const
 
virtual double ScaleDiffusionTensor (const double d) const
 
virtual double ScaleTownsend (const double alpha) const
 
virtual double ScaleAttachment (const double eta) const
 
virtual double ScaleLorentzAngle (const double lor) const
 
virtual double ScaleDissociation (const double diss) const
 
virtual bool GetOpticalDataRange (double &emin, double &emax, const unsigned int i=0)
 Get the energy range [eV] of the available optical data.
 
virtual bool GetDielectricFunction (const double e, double &eps1, double &eps2, const unsigned int i=0)
 Get the complex dielectric function at a given energy.
 
virtual bool GetPhotoAbsorptionCrossSection (const double e, double &sigma, const unsigned int i=0)
 
virtual double GetPhotonCollisionRate (const double e)
 
virtual bool GetPhotonCollision (const double e, int &type, int &level, double &e1, double &ctheta, int &nsec, double &esec)
 
void EnableDebugging ()
 Switch on/off debugging messages.
 
void DisableDebugging ()
 

Additional Inherited Members

- Protected Member Functions inherited from Garfield::MediumGas
bool ReadHeader (std::ifstream &gasfile, int &version, std::bitset< 20 > &gasok, bool &is3d, std::vector< double > &mixture, std::vector< double > &efields, std::vector< double > &bfields, std::vector< double > &angles, std::vector< ExcLevel > &excLevels, std::vector< IonLevel > &ionLevels)
 
void ReadFooter (std::ifstream &gasfile, std::array< unsigned int, 13 > &extrapH, std::array< unsigned int, 13 > &extrapL, std::array< unsigned int, 13 > &interp, unsigned int &thrAlp, unsigned int &thrAtt, unsigned int &thrDis, double &ionDiffL, double &ionDiffT, double &pgas, double &tgas)
 
void ReadRecord3D (std::ifstream &gasfile, double &ve, double &vb, double &vx, double &dl, double &dt, double &alpha, double &alpha0, double &eta, double &mu, double &lor, double &dis, std::array< double, 6 > &dif, std::vector< double > &rexc, std::vector< double > &rion)
 
void ReadRecord1D (std::ifstream &gasfile, double &ve, double &vb, double &vx, double &dl, double &dt, double &alpha, double &alpha0, double &eta, double &mu, double &lor, double &dis, std::array< double, 6 > &dif, std::vector< double > &rexc, std::vector< double > &rion)
 
void InsertE (const int ie, const int ne, const int nb, const int na)
 
void InsertB (const int ib, const int ne, const int nb, const int na)
 
void InsertA (const int ia, const int ne, const int nb, const int na)
 
void ZeroRowE (const int ie, const int nb, const int na)
 
void ZeroRowB (const int ib, const int ne, const int na)
 
void ZeroRowA (const int ia, const int ne, const int nb)
 
bool GetMixture (const std::vector< double > &mixture, const int version, std::vector< std::string > &gasnames, std::vector< double > &percentages) const
 
void GetGasBits (std::bitset< 20 > &gasok) const
 
bool GetGasInfo (const std::string &gasname, double &a, double &z) const
 
std::string GetGasName (const int gasnumber, const int version) const
 
std::string GetGasName (std::string input) const
 
int GetGasNumberGasFile (const std::string &input) const
 
- Protected Member Functions inherited from Garfield::Medium
bool Velocity (const double ex, const double ey, const double ez, const double bx, const double by, const double bz, const std::vector< std::vector< std::vector< double > > > &velE, const std::vector< std::vector< std::vector< double > > > &velB, const std::vector< std::vector< std::vector< double > > > &velX, const double q, double &vx, double &vy, double &vz) const
 
bool Diffusion (const double ex, const double ey, const double ez, const double bx, const double by, const double bz, const std::vector< std::vector< std::vector< double > > > &difL, const std::vector< std::vector< std::vector< double > > > &difT, double &dl, double &dt) const
 
bool Diffusion (const double ex, const double ey, const double ez, const double bx, const double by, const double bz, const std::vector< std::vector< std::vector< std::vector< double > > > > &diff, double cov[3][3]) const
 
bool Alpha (const double ex, const double ey, const double ez, const double bx, const double by, const double bz, const std::vector< std::vector< std::vector< double > > > &tab, unsigned int intp, const unsigned int thr, const std::pair< unsigned int, unsigned int > &extr, double &alpha) const
 
double GetAngle (const double ex, const double ey, const double ez, const double bx, const double by, const double bz, const double e, const double b) const
 
bool Interpolate (const double e, const double b, const double a, const std::vector< std::vector< std::vector< double > > > &table, double &y, const unsigned int intp, const std::pair< unsigned int, unsigned int > &extr) const
 
double Interpolate1D (const double e, const std::vector< double > &table, const std::vector< double > &fields, const unsigned int intpMeth, const std::pair< unsigned int, unsigned int > &extr) const
 
bool SetEntry (const unsigned int i, const unsigned int j, const unsigned int k, const std::string &fcn, std::vector< std::vector< std::vector< double > > > &tab, const double val)
 
bool GetEntry (const unsigned int i, const unsigned int j, const unsigned int k, const std::string &fcn, const std::vector< std::vector< std::vector< double > > > &tab, double &val) const
 
void SetExtrapolationMethod (const std::string &low, const std::string &high, std::pair< unsigned int, unsigned int > &extr, const std::string &fcn)
 
bool GetExtrapolationIndex (std::string str, unsigned int &nb) const
 
unsigned int SetThreshold (const std::vector< std::vector< std::vector< double > > > &tab) const
 
void Clone (std::vector< std::vector< std::vector< double > > > &tab, const std::vector< double > &efields, const std::vector< double > &bfields, const std::vector< double > &angles, const unsigned int intp, const std::pair< unsigned int, unsigned int > &extr, const double init, const std::string &label)
 
void Clone (std::vector< std::vector< std::vector< std::vector< double > > > > &tab, const unsigned int n, const std::vector< double > &efields, const std::vector< double > &bfields, const std::vector< double > &angles, const unsigned int intp, const std::pair< unsigned int, unsigned int > &extr, const double init, const std::string &label)
 
void Init (const size_t nE, const size_t nB, const size_t nA, std::vector< std::vector< std::vector< double > > > &tab, const double val)
 
void Init (const size_t nE, const size_t nB, const size_t nA, const size_t nT, std::vector< std::vector< std::vector< std::vector< double > > > > &tab, const double val)
 
- Protected Attributes inherited from Garfield::MediumGas
std::array< std::string, m_nMaxGasesm_gas
 
std::array< double, m_nMaxGasesm_fraction
 
std::array< double, m_nMaxGasesm_atWeight
 
std::array< double, m_nMaxGasesm_atNum
 
bool m_usePenning = false
 
double m_rPenningGlobal = 0.
 
double m_lambdaPenningGlobal = 0.
 
std::array< double, m_nMaxGasesm_rPenningGas
 
std::array< double, m_nMaxGasesm_lambdaPenningGas
 
double m_pressureTable
 
double m_temperatureTable
 
std::vector< std::vector< std::vector< double > > > m_eAlp0
 
std::vector< std::vector< std::vector< std::vector< double > > > > m_excRates
 
std::vector< std::vector< std::vector< std::vector< double > > > > m_ionRates
 
std::vector< ExcLevelm_excLevels
 
std::vector< IonLevelm_ionLevels
 
std::pair< unsigned int, unsigned int > m_extrExc = {0, 1}
 
std::pair< unsigned int, unsigned int > m_extrIon = {0, 1}
 
unsigned int m_intpExc = 2
 
unsigned int m_intpIon = 2
 
- Protected Attributes inherited from Garfield::Medium
std::string m_className = "Medium"
 
int m_id
 
std::string m_name = ""
 
double m_temperature = 293.15
 
double m_pressure = 760.
 
double m_epsilon = 1.
 
unsigned int m_nComponents = 1
 
double m_z = 1.
 
double m_a = 0.
 
double m_density = 0.
 
bool m_driftable = false
 
bool m_microscopic = false
 
bool m_ionisable = false
 
double m_w = 0.
 
double m_fano = 0.
 
bool m_isChanged = true
 
bool m_debug = false
 
std::vector< double > m_eFields
 
std::vector< double > m_bFields
 
std::vector< double > m_bAngles
 
bool m_tab2d = false
 
std::vector< std::vector< std::vector< double > > > m_eVelE
 
std::vector< std::vector< std::vector< double > > > m_eVelX
 
std::vector< std::vector< std::vector< double > > > m_eVelB
 
std::vector< std::vector< std::vector< double > > > m_eDifL
 
std::vector< std::vector< std::vector< double > > > m_eDifT
 
std::vector< std::vector< std::vector< double > > > m_eAlp
 
std::vector< std::vector< std::vector< double > > > m_eAtt
 
std::vector< std::vector< std::vector< double > > > m_eLor
 
std::vector< std::vector< std::vector< std::vector< double > > > > m_eDifM
 
std::vector< std::vector< std::vector< double > > > m_hVelE
 
std::vector< std::vector< std::vector< double > > > m_hVelX
 
std::vector< std::vector< std::vector< double > > > m_hVelB
 
std::vector< std::vector< std::vector< double > > > m_hDifL
 
std::vector< std::vector< std::vector< double > > > m_hDifT
 
std::vector< std::vector< std::vector< double > > > m_hAlp
 
std::vector< std::vector< std::vector< double > > > m_hAtt
 
std::vector< std::vector< std::vector< std::vector< double > > > > m_hDifM
 
std::vector< std::vector< std::vector< double > > > m_iMob
 
std::vector< std::vector< std::vector< double > > > m_iDifL
 
std::vector< std::vector< std::vector< double > > > m_iDifT
 
std::vector< std::vector< std::vector< double > > > m_iDis
 
unsigned int m_eThrAlp = 0
 
unsigned int m_eThrAtt = 0
 
unsigned int m_hThrAlp = 0
 
unsigned int m_hThrAtt = 0
 
unsigned int m_iThrDis = 0
 
std::pair< unsigned int, unsigned int > m_extrVel = {0, 1}
 
std::pair< unsigned int, unsigned int > m_extrDif = {0, 1}
 
std::pair< unsigned int, unsigned int > m_extrAlp = {0, 1}
 
std::pair< unsigned int, unsigned int > m_extrAtt = {0, 1}
 
std::pair< unsigned int, unsigned int > m_extrLor = {0, 1}
 
std::pair< unsigned int, unsigned int > m_extrMob = {0, 1}
 
std::pair< unsigned int, unsigned int > m_extrDis = {0, 1}
 
unsigned int m_intpVel = 2
 
unsigned int m_intpDif = 2
 
unsigned int m_intpAlp = 2
 
unsigned int m_intpAtt = 2
 
unsigned int m_intpLor = 2
 
unsigned int m_intpMob = 2
 
unsigned int m_intpDis = 2
 
- Static Protected Attributes inherited from Garfield::MediumGas
static constexpr unsigned int m_nMaxGases = 6
 
- Static Protected Attributes inherited from Garfield::Medium
static int m_idCounter = -1
 

Detailed Description

Interface to Magboltz (version 11).

Definition at line 14 of file MediumMagboltz.hh.

Constructor & Destructor Documentation

◆ MediumMagboltz()

Garfield::MediumMagboltz::MediumMagboltz ( )

Constructor.

Definition at line 38 of file MediumMagboltz.cc.

39 : MediumGas(),
40 m_eMax(40.),
41 m_eStep(m_eMax / Magboltz::nEnergySteps),
42 m_eHigh(400.),
43 m_eHighLog(log(m_eHigh)),
44 m_lnStep(1.),
45 m_eFinalGamma(20.),
46 m_eStepGamma(m_eFinalGamma / nEnergyStepsGamma) {
47 m_className = "MediumMagboltz";
48
49 // Set physical constants in Magboltz common blocks.
50 Magboltz::cnsts_.echarg = ElementaryCharge * 1.e-15;
51 Magboltz::cnsts_.emass = ElectronMassGramme;
52 Magboltz::cnsts_.amu = AtomicMassUnit;
53 Magboltz::cnsts_.pir2 = BohrRadius * BohrRadius * Pi;
54 Magboltz::inpt_.ary = RydbergEnergy;
55
56 // Set parameters in Magboltz common blocks.
59 // Select the scattering model.
60 Magboltz::inpt_.nAniso = 2;
61 // Max. energy [eV]
62 Magboltz::inpt_.efinal = m_eMax;
63 // Energy step size [eV]
64 Magboltz::inpt_.estep = m_eStep;
65 // Temperature and pressure
66 Magboltz::inpt_.akt = BoltzmannConstant * m_temperature;
67 Magboltz::inpt_.tempc = m_temperature - ZeroCelsius;
69 // Disable Penning transfer.
70 Magboltz::inpt_.ipen = 0;
71
72 m_description.assign(Magboltz::nMaxLevels,
73 std::string(Magboltz::nCharDescr, ' '));
74
75 m_cfTot.assign(Magboltz::nEnergySteps, 0.);
76 m_cfTotLog.assign(nEnergyStepsLog, 0.);
77 m_cf.assign(Magboltz::nEnergySteps,
78 std::vector<double>(Magboltz::nMaxLevels, 0.));
79 m_cfLog.assign(nEnergyStepsLog,
80 std::vector<double>(Magboltz::nMaxLevels, 0.));
81
82 m_isChanged = true;
83
86 m_microscopic = true;
87
88 m_scaleExc.fill(1.);
89}
MediumGas()
Constructor.
Definition: MediumGas.cc:111
bool m_microscopic
Definition: Medium.hh:531
double m_pressure
Definition: Medium.hh:517
virtual void EnableDrift(const bool on=true)
Switch electron/ion/hole on/off.
Definition: Medium.hh:67
virtual void EnablePrimaryIonisation(const bool on=true)
Make the medium ionisable or non-ionisable.
Definition: Medium.hh:69
unsigned int m_nComponents
Definition: Medium.hh:521
std::string m_className
Definition: Medium.hh:506
bool m_isChanged
Definition: Medium.hh:540
double m_temperature
Definition: Medium.hh:515
constexpr unsigned int nEnergySteps
constexpr unsigned int nCharDescr
constexpr unsigned int nMaxLevels
struct Garfield::Magboltz::@1 inpt_
struct Garfield::Magboltz::@4 cnsts_

◆ ~MediumMagboltz()

virtual Garfield::MediumMagboltz::~MediumMagboltz ( )
inlinevirtual

Destructor.

Definition at line 19 of file MediumMagboltz.hh.

19{}

Member Function Documentation

◆ ComputeDeexcitation()

void Garfield::MediumMagboltz::ComputeDeexcitation ( int  iLevel,
int &  fLevel 
)

Definition at line 3099 of file MediumMagboltz.cc.

3099 {
3100 if (!m_useDeexcitation) {
3101 std::cerr << m_className << "::ComputeDeexcitation: Not enabled.\n";
3102 return;
3103 }
3104
3105 // Make sure that the tables are updated.
3106 if (m_isChanged) {
3107 if (!Mixer()) {
3108 PrintErrorMixer(m_className + "::ComputeDeexcitation");
3109 return;
3110 }
3111 m_isChanged = false;
3112 }
3113
3114 if (iLevel < 0 || iLevel >= (int)m_nTerms) {
3115 std::cerr << m_className << "::ComputeDeexcitation: Index out of range.\n";
3116 return;
3117 }
3118
3119 iLevel = m_iDeexcitation[iLevel];
3120 if (iLevel < 0 || iLevel >= (int)m_deexcitations.size()) {
3121 std::cerr << m_className << "::ComputeDeexcitation:\n"
3122 << " Level is not deexcitable.\n";
3123 return;
3124 }
3125
3126 ComputeDeexcitationInternal(iLevel, fLevel);
3127 if (fLevel >= 0 && fLevel < (int)m_deexcitations.size()) {
3128 fLevel = m_deexcitations[fLevel].level;
3129 }
3130}

◆ DisableDeexcitation()

void Garfield::MediumMagboltz::DisableDeexcitation ( )
inline

Switch off (microscopic) de-excitation handling.

Definition at line 53 of file MediumMagboltz.hh.

53{ m_useDeexcitation = false; }

◆ DisablePenningTransfer() [1/2]

void Garfield::MediumMagboltz::DisablePenningTransfer ( )
overridevirtual

Switch the simulation of Penning transfers off globally.

Reimplemented from Garfield::MediumGas.

Definition at line 279 of file MediumMagboltz.cc.

279 {
280
282 m_rPenning.fill(0.);
283 m_lambdaPenning.fill(0.);
284
285 m_usePenning = false;
286}
virtual void DisablePenningTransfer()
Switch the simulation of Penning transfers off globally.
Definition: MediumGas.cc:2450

◆ DisablePenningTransfer() [2/2]

bool Garfield::MediumMagboltz::DisablePenningTransfer ( std::string  gasname)
overridevirtual

Switch the simulation of Penning transfers off for a given component.

Reimplemented from Garfield::MediumGas.

Definition at line 288 of file MediumMagboltz.cc.

288 {
289
290 if (!MediumGas::DisablePenningTransfer(gasname)) return false;
291 // Get the "standard" name of this gas.
292 gasname = GetGasName(gasname);
293 if (gasname.empty()) return false;
294
295 // Look (again) for this gas in the present gas mixture.
296 int iGas = -1;
297 for (unsigned int i = 0; i < m_nComponents; ++i) {
298 if (m_gas[i] == gasname) {
299 iGas = i;
300 break;
301 }
302 }
303
304 if (iGas < 0) return false;
305
306 unsigned int nLevelsFound = 0;
307 for (unsigned int i = 0; i < m_nTerms; ++i) {
308 if (int(m_csType[i] / nCsTypes) == iGas) {
309 m_rPenning[i] = 0.;
310 m_lambdaPenning[i] = 0.;
311 } else {
312 if (m_csType[i] % nCsTypes == ElectronCollisionTypeExcitation &&
313 m_rPenning[i] > Small) {
314 ++nLevelsFound;
315 }
316 }
317 }
318
319 if (nLevelsFound == 0) {
320 // There are no more excitation levels with r > 0.
321 std::cout << m_className << "::DisablePenningTransfer:\n"
322 << " Penning transfer switched off for all excitations.\n";
323 m_usePenning = false;
324 }
325 return true;
326}
std::string GetGasName(const int gasnumber, const int version) const
Definition: MediumGas.cc:2740
std::array< std::string, m_nMaxGases > m_gas
Definition: MediumGas.hh:129

◆ DisableRadiationTrapping()

void Garfield::MediumMagboltz::DisableRadiationTrapping ( )
inline

Switch off discrete photoabsorption levels.

Definition at line 57 of file MediumMagboltz.hh.

57{ m_useRadTrap = false; }

◆ EnableAnisotropicScattering()

void Garfield::MediumMagboltz::EnableAnisotropicScattering ( const bool  on = true)
inline

Switch on/off anisotropic scattering (enabled by default)

Definition at line 38 of file MediumMagboltz.hh.

38 {
39 m_useAnisotropic = on;
40 m_isChanged = true;
41 }

◆ EnableAutoEnergyLimit()

void Garfield::MediumMagboltz::EnableAutoEnergyLimit ( const bool  on = true)
inline

Let Magboltz determine the upper energy limit (this is the default) or use the energy limit specified using SetMaxElectronEnergy).

Definition at line 136 of file MediumMagboltz.hh.

136{ m_autoEnergyLimit = on; }

◆ EnableCrossSectionOutput()

void Garfield::MediumMagboltz::EnableCrossSectionOutput ( const bool  on = true)
inline

Write the gas cross-section table to a file during the initialisation.

Definition at line 66 of file MediumMagboltz.hh.

66{ m_useCsOutput = on; }

◆ EnableDeexcitation()

void Garfield::MediumMagboltz::EnableDeexcitation ( )

Switch on (microscopic) de-excitation handling.

Definition at line 151 of file MediumMagboltz.cc.

151 {
152 if (m_usePenning) {
153 std::cout << m_className << "::EnableDeexcitation:\n"
154 << " Penning transfer will be switched off.\n";
155 }
156 // if (m_useRadTrap) {
157 // std::cout << " Radiation trapping is switched on.\n";
158 // } else {
159 // std::cout << " Radiation trapping is switched off.\n";
160 // }
161 m_usePenning = false;
162 m_useDeexcitation = true;
163 m_isChanged = true;
164 m_dxcProducts.clear();
165}

◆ EnableEnergyRangeAdjustment()

void Garfield::MediumMagboltz::EnableEnergyRangeAdjustment ( const bool  on)
inline

Switch on/off the automatic adjustment of the max. energy when an energy exceeding the present range is requested

Definition at line 35 of file MediumMagboltz.hh.

35{ m_useAutoAdjust = on; }

◆ EnablePenningTransfer() [1/2]

bool Garfield::MediumMagboltz::EnablePenningTransfer ( const double  r,
const double  lambda 
)
overridevirtual

Switch on simulation of Penning transfers by means of transfer probabilities, for all excitation levels in the mixture.

Parameters
rtransfer probability [0, 1]
lambdaparameter for sampling the distance of the Penning electron with respect to the excitation.

Reimplemented from Garfield::MediumGas.

Definition at line 177 of file MediumMagboltz.cc.

178 {
179
180 if (!MediumGas::EnablePenningTransfer(r, lambda)) return false;
181
182 m_rPenning.fill(0.);
183 m_lambdaPenning.fill(0.);
184
185 // Make sure that the collision rate table is updated.
186 if (m_isChanged) {
187 if (!Mixer()) {
188 PrintErrorMixer(m_className + "::EnablePenningTransfer");
189 return false;
190 }
191 m_isChanged = false;
192 }
193 unsigned int nLevelsFound = 0;
194 for (unsigned int i = 0; i < m_nTerms; ++i) {
195 if (m_csType[i] % nCsTypes == ElectronCollisionTypeExcitation) {
196 ++nLevelsFound;
197 }
198 m_rPenning[i] = m_rPenningGlobal;
199 m_lambdaPenning[i] = m_lambdaPenningGlobal;
200 }
201
202 if (nLevelsFound > 0) {
203 std::cout << m_className << "::EnablePenningTransfer:\n "
204 << "Updated Penning transfer parameters for " << nLevelsFound
205 << " excitation cross-sections.\n";
206 if (nLevelsFound != m_excLevels.size() && !m_excLevels.empty()) {
207 std::cerr << m_className << "::EnablePenningTransfer:\n Warning: "
208 << "mismatch between number of excitation cross-sections ("
209 << nLevelsFound << ")\n and number of excitation rates in "
210 << "the gas table (" << m_excLevels.size() << ").\n "
211 << "The gas table was probably calculated using a different "
212 << "version of Magboltz.\n";
213 }
214 } else {
215 std::cerr << m_className << "::EnablePenningTransfer:\n "
216 << "No excitation cross-sections in the present energy range.\n";
217 }
218
219 if (m_useDeexcitation) {
220 std::cout << m_className << "::EnablePenningTransfer:\n "
221 << "Deexcitation handling will be switched off.\n";
222 }
223 m_usePenning = true;
224 return true;
225}
double m_lambdaPenningGlobal
Definition: MediumGas.hh:140
std::vector< ExcLevel > m_excLevels
Definition: MediumGas.hh:166
virtual bool EnablePenningTransfer(const double r, const double lambda)
Definition: MediumGas.cc:2321

Referenced by GarfieldPhysics::InitializePhysics().

◆ EnablePenningTransfer() [2/2]

bool Garfield::MediumMagboltz::EnablePenningTransfer ( const double  r,
const double  lambda,
std::string  gasname 
)
overridevirtual

Switch on simulation of Penning transfers by means of transfer probabilities, for all excitations of a given component.

Reimplemented from Garfield::MediumGas.

Definition at line 227 of file MediumMagboltz.cc.

228 {
229
230 if (!MediumGas::EnablePenningTransfer(r, lambda, gasname)) return false;
231
232 // Get (again) the "standard" name of this gas.
233 gasname = GetGasName(gasname);
234 if (gasname.empty()) return false;
235
236 // Look (again) for this gas in the present mixture.
237 int iGas = -1;
238 for (unsigned int i = 0; i < m_nComponents; ++i) {
239 if (m_gas[i] == gasname) {
240 iGas = i;
241 break;
242 }
243 }
244
245 // Make sure that the collision rate table is updated.
246 if (m_isChanged) {
247 if (!Mixer()) {
248 PrintErrorMixer(m_className + "::EnablePenningTransfer");
249 return false;
250 }
251 m_isChanged = false;
252 }
253 unsigned int nLevelsFound = 0;
254 for (unsigned int i = 0; i < m_nTerms; ++i) {
255 if (int(m_csType[i] / nCsTypes) != iGas) continue;
256 if (m_csType[i] % nCsTypes == ElectronCollisionTypeExcitation) {
257 ++nLevelsFound;
258 }
259 m_rPenning[i] = m_rPenningGas[iGas];
260 m_lambdaPenning[i] = m_lambdaPenningGas[iGas];
261 }
262
263 if (nLevelsFound > 0) {
264 std::cout << m_className << "::EnablePenningTransfer:\n"
265 << " Penning transfer parameters for " << nLevelsFound
266 << " excitation levels set to:\n"
267 << " r = " << m_rPenningGas[iGas] << "\n"
268 << " lambda = " << m_lambdaPenningGas[iGas] << " cm\n";
269 } else {
270 std::cerr << m_className << "::EnablePenningTransfer:\n"
271 << " Specified gas (" << gasname
272 << ") has no excitation levels in the present energy range.\n";
273 }
274
275 m_usePenning = true;
276 return true;
277}
std::array< double, m_nMaxGases > m_rPenningGas
Definition: MediumGas.hh:142
std::array< double, m_nMaxGases > m_lambdaPenningGas
Definition: MediumGas.hh:144

◆ EnableRadiationTrapping()

void Garfield::MediumMagboltz::EnableRadiationTrapping ( )

Switch on discrete photoabsorption levels.

Definition at line 167 of file MediumMagboltz.cc.

167 {
168 m_useRadTrap = true;
169 if (!m_useDeexcitation) {
170 std::cout << m_className << "::EnableRadiationTrapping:\n "
171 << "Radiation trapping is enabled but de-excitation is not.\n";
172 } else {
173 m_isChanged = true;
174 }
175}

◆ EnableThermalMotion()

void Garfield::MediumMagboltz::EnableThermalMotion ( const bool  on = true)
inline

Take the thermal motion of the gas at the selected temperature into account in the calculations done by Magboltz. By the default, this feature is off (static gas at 0 K).

Definition at line 133 of file MediumMagboltz.hh.

133{ m_useGasMotion = on; }

◆ GenerateGasTable()

void Garfield::MediumMagboltz::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, magnetic fields, and angles in the currently set grid.

Definition at line 3493 of file MediumMagboltz.cc.

3493 {
3494 // Set the reference pressure and temperature.
3497
3498 // Initialize the parameter arrays.
3499 const unsigned int nEfields = m_eFields.size();
3500 const unsigned int nBfields = m_bFields.size();
3501 const unsigned int nAngles = m_bAngles.size();
3502 Init(nEfields, nBfields, nAngles, m_eVelE, 0.);
3503 Init(nEfields, nBfields, nAngles, m_eVelB, 0.);
3504 Init(nEfields, nBfields, nAngles, m_eVelX, 0.);
3505 Init(nEfields, nBfields, nAngles, m_eDifL, 0.);
3506 Init(nEfields, nBfields, nAngles, m_eDifT, 0.);
3507 Init(nEfields, nBfields, nAngles, m_eLor, 0.);
3508 Init(nEfields, nBfields, nAngles, m_eAlp, -30.);
3509 Init(nEfields, nBfields, nAngles, m_eAlp0, -30.);
3510 Init(nEfields, nBfields, nAngles, m_eAtt, -30.);
3511 Init(nEfields, nBfields, nAngles, 6, m_eDifM, 0.);
3512
3513 m_excRates.clear();
3514 m_ionRates.clear();
3515 m_excLevels.clear();
3516 m_ionLevels.clear();
3517 std::vector<unsigned int> excLevelIndex;
3518 std::vector<unsigned int> ionLevelIndex;
3519
3520 double vx = 0., vy = 0., vz = 0.;
3521 double difl = 0., dift = 0.;
3522 double alpha = 0., eta = 0.;
3523 double lor = 0.;
3524 double vxerr = 0., vyerr = 0., vzerr = 0.;
3525 double diflerr = 0., difterr = 0.;
3526 double alphaerr = 0., etaerr = 0.;
3527 double alphatof = 0.;
3528 double lorerr = 0.;
3529 std::array<double, 6> difftens;
3530
3531 // Run through the grid of E- and B-fields and angles.
3532 for (unsigned int i = 0; i < nEfields; ++i) {
3533 const double e = m_eFields[i];
3534 for (unsigned int j = 0; j < nAngles; ++j) {
3535 const double a = m_bAngles[j];
3536 for (unsigned int k = 0; k < nBfields; ++k) {
3537 const double b = m_bFields[k];
3538 std::cout << m_className << "::GenerateGasTable: E = " << e
3539 << " V/cm, B = " << b << " T, angle: " << a << " rad\n";
3540 RunMagboltz(e, b, a, numColl, verbose, vx, vy, vz, difl, dift, alpha,
3541 eta, lor, vxerr, vyerr, vzerr, diflerr, difterr, alphaerr,
3542 etaerr, lorerr, alphatof, difftens);
3543 m_eVelE[j][k][i] = vz;
3544 m_eVelX[j][k][i] = vy;
3545 m_eVelB[j][k][i] = vx;
3546 m_eDifL[j][k][i] = difl;
3547 m_eDifT[j][k][i] = dift;
3548 m_eLor[j][k][i] = lor;
3549 m_eAlp[j][k][i] = alpha > 0. ? log(alpha) : -30.;
3550 m_eAlp0[j][k][i] = alpha > 0. ? log(alpha) : -30.;
3551 m_eAtt[j][k][i] = eta > 0. ? log(eta) : -30.;
3552 for (unsigned int l = 0; l < 6; ++l) {
3553 m_eDifM[l][j][k][i] = difftens[l];
3554 }
3555 // If not done yet, retrieve the excitation and ionisation levels.
3556 if (m_excLevels.empty() && m_ionLevels.empty()) {
3557 for (long long il = 0; il < Magboltz::nMaxLevels; ++il) {
3558 if (Magboltz::large_.iarry[il] <= 0) break;
3559 // Skip levels that are not ionisations or inelastic collisions.
3560 const int cstype = (Magboltz::large_.iarry[il] - 1) % 5;
3561 if (cstype != 1 && cstype != 3) continue;
3562 const int igas = int((Magboltz::large_.iarry[il] - 1) / 5);
3563 std::string descr = GetDescription(il, Magboltz::scrip_.dscrpt);
3564 if (cstype == 3) {
3565 // Skip levels that are not excitations.
3566 if (!(descr[1] == 'E' && descr[2] == 'X') &&
3567 !(descr[0] == 'E' && descr[1] == 'X'))
3568 continue;
3569 }
3570 descr = m_gas[igas] + descr;
3571 if (cstype == 3) {
3572 ExcLevel exc;
3573 exc.label = descr;
3574 exc.energy = Magboltz::large_.ein[il];
3575 exc.prob = 0.;
3576 exc.rms = 0.;
3577 exc.dt = 0.;
3578 m_excLevels.push_back(std::move(exc));
3579 excLevelIndex.push_back(il);
3580 } else {
3581 IonLevel ion;
3582 ion.label = descr;
3583 ion.energy = Magboltz::large_.ein[il];
3584 m_ionLevels.push_back(std::move(ion));
3585 ionLevelIndex.push_back(il);
3586 }
3587 }
3588 std::cout << m_className << "::GenerateGasTable: Found "
3589 << m_excLevels.size() << " excitations and "
3590 << m_ionLevels.size() << " ionisations.\n";
3591 for (const auto& exc : m_excLevels) {
3592 std::cout << " " << exc.label << ", energy = " << exc.energy
3593 << " eV.\n";
3594 }
3595 for (const auto& ion : m_ionLevels) {
3596 std::cout << " " << ion.label << ", energy = " << ion.energy
3597 << " eV.\n";
3598 }
3599 if (!m_excLevels.empty()) {
3600 Init(nEfields, nBfields, nAngles, m_excLevels.size(),
3601 m_excRates, 0.);
3602 }
3603 if (!m_ionLevels.empty()) {
3604 Init(nEfields, nBfields, nAngles, m_ionLevels.size(),
3605 m_ionRates, 0.);
3606 }
3607 }
3608 // Retrieve the excitation and ionisation rates.
3609 const unsigned int nExc = m_excLevels.size();
3610 for (unsigned int ie = 0; ie < nExc; ++ie) {
3611 const unsigned int level = excLevelIndex[ie];
3612 m_excRates[ie][j][k][i] = Magboltz::outpt_.icoln[level];
3613 }
3614 const unsigned int nIon = m_ionLevels.size();
3615 for (unsigned int ii = 0; ii < nIon; ++ii) {
3616 const unsigned int level = ionLevelIndex[ii];
3617 m_ionRates[ii][j][k][i] = Magboltz::outpt_.icoln[level];
3618 }
3619 }
3620 }
3621 }
3622 // Set the threshold indices.
3625}
std::vector< std::vector< std::vector< std::vector< double > > > > m_excRates
Definition: MediumGas.hh:155
std::vector< IonLevel > m_ionLevels
Definition: MediumGas.hh:172
std::vector< std::vector< std::vector< std::vector< double > > > > m_ionRates
Definition: MediumGas.hh:156
double m_temperatureTable
Definition: MediumGas.hh:149
std::vector< std::vector< std::vector< double > > > m_eAlp0
Definition: MediumGas.hh:152
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)
std::vector< double > m_bFields
Definition: Medium.hh:547
unsigned int SetThreshold(const std::vector< std::vector< std::vector< double > > > &tab) const
Definition: Medium.cc:1146
std::vector< std::vector< std::vector< double > > > m_eAlp
Definition: Medium.hh:558
std::vector< std::vector< std::vector< double > > > m_eVelE
Definition: Medium.hh:553
std::vector< std::vector< std::vector< double > > > m_eVelX
Definition: Medium.hh:554
std::vector< std::vector< std::vector< double > > > m_eDifL
Definition: Medium.hh:556
void Init(const size_t nE, const size_t nB, const size_t nA, std::vector< std::vector< std::vector< double > > > &tab, const double val)
Definition: Medium.cc:1304
std::vector< double > m_eFields
Definition: Medium.hh:546
std::vector< std::vector< std::vector< double > > > m_eAtt
Definition: Medium.hh:559
std::vector< double > m_bAngles
Definition: Medium.hh:548
std::vector< std::vector< std::vector< double > > > m_eLor
Definition: Medium.hh:560
std::vector< std::vector< std::vector< double > > > m_eDifT
Definition: Medium.hh:557
std::vector< std::vector< std::vector< double > > > m_eVelB
Definition: Medium.hh:555
std::vector< std::vector< std::vector< std::vector< double > > > > m_eDifM
Definition: Medium.hh:562
struct Garfield::Magboltz::@8 scrip_
struct Garfield::Magboltz::@7 outpt_
struct Garfield::Magboltz::@9 large_

◆ GetDeexcitationProduct()

bool Garfield::MediumMagboltz::GetDeexcitationProduct ( const unsigned int  i,
double &  t,
double &  s,
int &  type,
double &  energy 
) const
overridevirtual

Reimplemented from Garfield::Medium.

Definition at line 808 of file MediumMagboltz.cc.

810 {
811 if (i >= m_dxcProducts.size() || !(m_useDeexcitation || m_usePenning)) {
812 return false;
813 }
814 t = m_dxcProducts[i].t;
815 s = m_dxcProducts[i].s;
816 type = m_dxcProducts[i].type;
817 energy = m_dxcProducts[i].energy;
818 return true;
819}

◆ GetElectronCollision()

bool Garfield::MediumMagboltz::GetElectronCollision ( const double  e,
int &  type,
int &  level,
double &  e1,
double &  dx,
double &  dy,
double &  dz,
std::vector< std::pair< int, double > > &  secondaries,
int &  ndxc,
int &  band 
)
overridevirtual

Sample the collision type.

Reimplemented from Garfield::Medium.

Definition at line 562 of file MediumMagboltz.cc.

565 {
566 ndxc = 0;
567 if (e <= 0.) {
568 std::cerr << m_className << "::GetElectronCollision: Invalid energy.\n";
569 return false;
570 }
571 // Check if the electron energy is within the currently set range.
572 if (e > m_eMax && m_useAutoAdjust) {
573 std::cerr << m_className << "::GetElectronCollision:\n Provided energy ("
574 << e << " eV) exceeds current energy range.\n"
575 << " Increasing energy range to " << 1.05 * e << " eV.\n";
576 SetMaxElectronEnergy(1.05 * e);
577 }
578
579 // If necessary, update the collision rates table.
580 if (m_isChanged) {
581 if (!Mixer()) {
582 PrintErrorMixer(m_className + "::GetElectronCollision");
583 return false;
584 }
585 m_isChanged = false;
586 }
587
588 if (m_debug && band > 0) {
589 std::cerr << m_className << "::GetElectronCollision: Band > 0.\n";
590 }
591
592 double angCut = 1.;
593 double angPar = 0.5;
594
595 if (e <= m_eHigh) {
596 // Linear binning
597 // Get the energy interval.
598 constexpr int iemax = Magboltz::nEnergySteps - 1;
599 const int iE = std::min(std::max(int(e / m_eStep), 0), iemax);
600
601 // Sample the scattering process.
602 const double r = RndmUniform();
603 if (r <= m_cf[iE][0]) {
604 level = 0;
605 } else if (r >= m_cf[iE][m_nTerms - 1]) {
606 level = m_nTerms - 1;
607 } else {
608 const auto begin = m_cf[iE].cbegin();
609 level = std::lower_bound(begin, begin + m_nTerms, r) - begin;
610 }
611 // Get the angular distribution parameters.
612 angCut = m_scatCut[iE][level];
613 angPar = m_scatPar[iE][level];
614 } else {
615 // Logarithmic binning
616 // Get the energy interval.
617 const int iE = std::min(std::max(int(log(e / m_eHigh) / m_lnStep), 0),
618 nEnergyStepsLog - 1);
619 // Sample the scattering process.
620 const double r = RndmUniform();
621 if (r <= m_cfLog[iE][0]) {
622 level = 0;
623 } else if (r >= m_cfLog[iE][m_nTerms - 1]) {
624 level = m_nTerms - 1;
625 } else {
626 const auto begin = m_cfLog[iE].cbegin();
627 level = std::lower_bound(begin, begin + m_nTerms, r) - begin;
628 }
629 // Get the angular distribution parameters.
630 angCut = m_scatCutLog[iE][level];
631 angPar = m_scatParLog[iE][level];
632 }
633
634 // Extract the collision type.
635 type = m_csType[level] % nCsTypes;
636 const int igas = int(m_csType[level] / nCsTypes);
637 // Increase the collision counters.
638 ++m_nCollisions[type];
639 ++m_nCollisionsDetailed[level];
640
641 // Get the energy loss for this process.
642 double loss = m_energyLoss[level];
643
644 if (type == ElectronCollisionTypeVirtual) return true;
645
646 if (type == ElectronCollisionTypeIonisation) {
647 // Sample the secondary electron energy according to
648 // the Opal-Beaty-Peterson parameterisation.
649 double esec = 0.;
650 if (e < loss) loss = e - 0.0001;
651 if (m_useOpalBeaty) {
652 // Get the splitting parameter.
653 const double w = m_wOpalBeaty[level];
654 esec = w * tan(RndmUniform() * atan(0.5 * (e - loss) / w));
655 // Rescaling (SST)
656 // esec = w * pow(esec / w, 0.9524);
657 } else if (m_useGreenSawada) {
658 const double gs = m_parGreenSawada[igas][0];
659 const double gb = m_parGreenSawada[igas][1];
660 const double w = gs * e / (e + gb);
661 const double ts = m_parGreenSawada[igas][2];
662 const double ta = m_parGreenSawada[igas][3];
663 const double tb = m_parGreenSawada[igas][4];
664 const double esec0 = ts - ta / (e + tb);
665 const double r = RndmUniform();
666 esec = esec0 +
667 w * tan((r - 1.) * atan(esec0 / w) +
668 r * atan((0.5 * (e - loss) - esec0) / w));
669 } else {
670 esec = RndmUniform() * (e - loss);
671 }
672 if (esec <= 0) esec = Small;
673 loss += esec;
674 // Add the secondary electron.
675 secondaries.emplace_back(std::make_pair(IonProdTypeElectron, esec));
676 // Add the ion.
677 secondaries.emplace_back(std::make_pair(IonProdTypeIon, 0.));
678 bool fluorescence = false;
679 if (m_yFluorescence[level] > Small) {
680 if (RndmUniform() < m_yFluorescence[level]) fluorescence = true;
681 }
682 // Add Auger and photo electrons (if any).
683 if (fluorescence) {
684 if (m_nAuger2[level] > 0) {
685 const double eav = m_eAuger2[level] / m_nAuger2[level];
686 for (unsigned int i = 0; i < m_nAuger2[level]; ++i) {
687 secondaries.emplace_back(std::make_pair(IonProdTypeElectron, eav));
688 }
689 }
690 if (m_nFluorescence[level] > 0) {
691 const double eav = m_eFluorescence[level] / m_nFluorescence[level];
692 for (unsigned int i = 0; i < m_nFluorescence[level]; ++i) {
693 secondaries.emplace_back(std::make_pair(IonProdTypeElectron, eav));
694 }
695 }
696 } else if (m_nAuger1[level] > 0) {
697 const double eav = m_eAuger1[level] / m_nAuger1[level];
698 for (unsigned int i = 0; i < m_nAuger1[level]; ++i) {
699 secondaries.emplace_back(std::make_pair(IonProdTypeElectron, eav));
700 }
701 }
702 } else if (type == ElectronCollisionTypeExcitation) {
703 // Follow the de-excitation cascade (if switched on).
704 if (m_useDeexcitation && m_iDeexcitation[level] >= 0) {
705 int fLevel = 0;
706 ComputeDeexcitationInternal(m_iDeexcitation[level], fLevel);
707 ndxc = m_dxcProducts.size();
708 } else if (m_usePenning) {
709 m_dxcProducts.clear();
710 // Simplified treatment of Penning ionisation.
711 // If the energy threshold of this level exceeds the
712 // ionisation potential of one of the gases,
713 // create a new electron (with probability rPenning).
714 if (m_debug) {
715 std::cout << m_className << "::GetElectronCollision:\n"
716 << " Level: " << level << "\n"
717 << " Ionization potential: " << m_minIonPot << "\n"
718 << " Excitation energy: " << loss * m_rgas[igas] << "\n"
719 << " Penning probability: " << m_rPenning[level] << "\n";
720 }
721 if (loss * m_rgas[igas] > m_minIonPot &&
722 RndmUniform() < m_rPenning[level]) {
723 // The energy of the secondary electron is assumed to be given by
724 // the difference of excitation and ionisation threshold.
725 double esec = loss * m_rgas[igas] - m_minIonPot;
726 if (esec <= 0) esec = Small;
727 // Add the secondary electron to the list.
728 dxcProd newDxcProd;
729 newDxcProd.t = 0.;
730 newDxcProd.s = 0.;
731 if (m_lambdaPenning[level] > Small) {
732 // Uniform distribution within a sphere of radius lambda
733 newDxcProd.s = m_lambdaPenning[level] * std::cbrt(RndmUniformPos());
734 }
735 newDxcProd.energy = esec;
736 newDxcProd.type = DxcProdTypeElectron;
737 m_dxcProducts.push_back(std::move(newDxcProd));
738 ndxc = 1;
739 ++m_nPenning;
740 }
741 }
742 }
743
744 if (e < loss) loss = e - 0.0001;
745
746 // Determine the scattering angle.
747 double ctheta0 = 1. - 2. * RndmUniform();
748 if (m_useAnisotropic) {
749 switch (m_scatModel[level]) {
750 case 0:
751 break;
752 case 1:
753 ctheta0 = 1. - RndmUniform() * angCut;
754 if (RndmUniform() > angPar) ctheta0 = -ctheta0;
755 break;
756 case 2:
757 ctheta0 = (ctheta0 + angPar) / (1. + angPar * ctheta0);
758 break;
759 default:
760 std::cerr << m_className << "::GetElectronCollision:\n"
761 << " Unknown scattering model.\n"
762 << " Using isotropic distribution.\n";
763 break;
764 }
765 }
766
767 const double s1 = m_rgas[igas];
768 const double s2 = (s1 * s1) / (s1 - 1.);
769 const double theta0 = acos(ctheta0);
770 const double arg = std::max(1. - s1 * loss / e, Small);
771 const double d = 1. - ctheta0 * sqrt(arg);
772
773 // Update the energy.
774 e1 = std::max(e * (1. - loss / (s1 * e) - 2. * d / s2), Small);
775 double q = std::min(sqrt((e / e1) * arg) / s1, 1.);
776 const double theta = asin(q * sin(theta0));
777 double ctheta = cos(theta);
778 if (ctheta0 < 0.) {
779 const double u = (s1 - 1.) * (s1 - 1.) / arg;
780 if (ctheta0 * ctheta0 > u) ctheta = -ctheta;
781 }
782 const double stheta = sin(theta);
783 // Calculate the direction after the collision.
784 dz = std::min(dz, 1.);
785 const double argZ = sqrt(dx * dx + dy * dy);
786
787 // Azimuth is chosen at random.
788 const double phi = TwoPi * RndmUniform();
789 const double cphi = cos(phi);
790 const double sphi = sin(phi);
791 if (argZ == 0.) {
792 dz = ctheta;
793 dx = cphi * stheta;
794 dy = sphi * stheta;
795 } else {
796 const double a = stheta / argZ;
797 const double dz1 = dz * ctheta + argZ * stheta * sphi;
798 const double dy1 = dy * ctheta + a * (dx * cphi - dy * dz * sphi);
799 const double dx1 = dx * ctheta - a * (dy * cphi + dx * dz * sphi);
800 dz = dz1;
801 dy = dy1;
802 dx = dx1;
803 }
804
805 return true;
806}
bool SetMaxElectronEnergy(const double e)
double RndmUniform()
Draw a random number uniformly distributed in the range [0, 1).
Definition: Random.hh:14
double RndmUniformPos()
Draw a random number uniformly distributed in the range (0, 1).
Definition: Random.hh:17
DoubleAc cos(const DoubleAc &f)
Definition: DoubleAc.cpp:432
DoubleAc acos(const DoubleAc &f)
Definition: DoubleAc.cpp:490
DoubleAc sin(const DoubleAc &f)
Definition: DoubleAc.cpp:384
DoubleAc asin(const DoubleAc &f)
Definition: DoubleAc.cpp:470
DoubleAc sqrt(const DoubleAc &f)
Definition: DoubleAc.cpp:314

◆ GetElectronCollisionRate() [1/2]

double Garfield::MediumMagboltz::GetElectronCollisionRate ( const double  e,
const int  band 
)
overridevirtual

Get the (real) collision rate [ns-1] at a given electron energy e [eV].

Reimplemented from Garfield::Medium.

Definition at line 477 of file MediumMagboltz.cc.

478 {
479 // Check if the electron energy is within the currently set range.
480 if (e <= 0.) {
481 std::cerr << m_className << "::GetElectronCollisionRate: Invalid energy.\n";
482 return m_cfTot[0];
483 }
484 if (e > m_eMax && m_useAutoAdjust) {
485 std::cerr << m_className << "::GetElectronCollisionRate:\n Rate at " << e
486 << " eV is not included in the current table.\n "
487 << "Increasing energy range to " << 1.05 * e << " eV.\n";
488 SetMaxElectronEnergy(1.05 * e);
489 }
490
491 // If necessary, update the collision rates table.
492 if (m_isChanged) {
493 if (!Mixer()) {
494 PrintErrorMixer(m_className + "::GetElectronCollisionRate");
495 return 0.;
496 }
497 m_isChanged = false;
498 }
499
500 if (m_debug && band > 0) {
501 std::cerr << m_className << "::GetElectronCollisionRate: Band > 0.\n";
502 }
503
504 // Get the energy interval.
505 if (e <= m_eHigh) {
506 // Linear binning
507 constexpr int iemax = Magboltz::nEnergySteps - 1;
508 const int iE = std::min(std::max(int(e / m_eStep), 0), iemax);
509 return m_cfTot[iE];
510 }
511
512 // Logarithmic binning
513 const double eLog = log(e);
514 int iE = int((eLog - m_eHighLog) / m_lnStep);
515 // Calculate the collision rate by log-log interpolation.
516 const double fmax = m_cfTotLog[iE];
517 const double fmin = iE == 0 ? log(m_cfTot.back()) : m_cfTotLog[iE - 1];
518 const double emin = m_eHighLog + iE * m_lnStep;
519 const double f = fmin + (eLog - emin) * (fmax - fmin) / m_lnStep;
520 return exp(f);
521}
DoubleAc exp(const DoubleAc &f)
Definition: DoubleAc.cpp:377

Referenced by GetElectronCollisionRate().

◆ GetElectronCollisionRate() [2/2]

double Garfield::MediumMagboltz::GetElectronCollisionRate ( const double  e,
const unsigned int  level,
const int  band 
)

Get the collision rate [ns-1] for a specific level.

Definition at line 523 of file MediumMagboltz.cc.

525 {
526 // Check if the electron energy is within the currently set range.
527 if (e <= 0.) {
528 std::cerr << m_className << "::GetElectronCollisionRate: Invalid energy.\n";
529 return 0.;
530 }
531
532 // Check if the level exists.
533 if (level >= m_nTerms) {
534 std::cerr << m_className << "::GetElectronCollisionRate: Invalid level.\n";
535 return 0.;
536 }
537
538 // Get the total scattering rate.
539 double rate = GetElectronCollisionRate(e, band);
540 // Get the energy interval.
541 if (e <= m_eHigh) {
542 // Linear binning
543 constexpr int iemax = Magboltz::nEnergySteps - 1;
544 const int iE = std::min(std::max(int(e / m_eStep), 0), iemax);
545 if (level == 0) {
546 rate *= m_cf[iE][0];
547 } else {
548 rate *= m_cf[iE][level] - m_cf[iE][level - 1];
549 }
550 } else {
551 // Logarithmic binning
552 const int iE = int((log(e) - m_eHighLog) / m_lnStep);
553 if (level == 0) {
554 rate *= m_cfLog[iE][0];
555 } else {
556 rate *= m_cfLog[iE][level] - m_cfLog[iE][level - 1];
557 }
558 }
559 return rate;
560}
double GetElectronCollisionRate(const double e, const int band) override
Get the (real) collision rate [ns-1] at a given electron energy e [eV].

◆ GetElectronNullCollisionRate()

double Garfield::MediumMagboltz::GetElectronNullCollisionRate ( const int  band)
overridevirtual

Get the overall null-collision rate [ns-1].

Reimplemented from Garfield::Medium.

Definition at line 460 of file MediumMagboltz.cc.

460 {
461 // If necessary, update the collision rates table.
462 if (m_isChanged) {
463 if (!Mixer()) {
464 PrintErrorMixer(m_className + "::GetElectronNullCollisionRate");
465 return 0.;
466 }
467 m_isChanged = false;
468 }
469
470 if (m_debug && band > 0) {
471 std::cerr << m_className << "::GetElectronNullCollisionRate: Band > 0.\n";
472 }
473
474 return m_cfNull;
475}

◆ GetLevel()

bool Garfield::MediumMagboltz::GetLevel ( const unsigned int  i,
int &  ngas,
int &  type,
std::string &  descr,
double &  e 
)

Get detailed information about a given cross-section term i.

Definition at line 988 of file MediumMagboltz.cc.

989 {
990 if (m_isChanged) {
991 if (!Mixer()) {
992 PrintErrorMixer(m_className + "::GetLevel");
993 return false;
994 }
995 m_isChanged = false;
996 }
997
998 if (i >= m_nTerms) {
999 std::cerr << m_className << "::GetLevel: Index out of range.\n";
1000 return false;
1001 }
1002
1003 // Collision type
1004 type = m_csType[i] % nCsTypes;
1005 ngas = int(m_csType[i] / nCsTypes);
1006 // Description (from Magboltz)
1007 descr = m_description[i];
1008 // Threshold energy
1009 e = m_rgas[ngas] * m_energyLoss[i];
1010 if (m_debug) {
1011 std::cout << m_className << "::GetLevel:\n"
1012 << " Level " << i << ": " << descr << "\n"
1013 << " Type " << type << "\n"
1014 << " Threshold energy: " << e << " eV\n";
1015 if (type == ElectronCollisionTypeExcitation && m_usePenning &&
1016 e > m_minIonPot) {
1017 std::cout << " Penning transfer coefficient: " << m_rPenning[i]
1018 << "\n";
1019 } else if (type == ElectronCollisionTypeExcitation && m_useDeexcitation) {
1020 const int idxc = m_iDeexcitation[i];
1021 if (idxc < 0 || idxc >= (int)m_deexcitations.size()) {
1022 std::cout << " Deexcitation cascade not implemented.\n";
1023 return true;
1024 }
1025 const auto& dxc = m_deexcitations[idxc];
1026 if (dxc.osc > 0.) {
1027 std::cout << " Oscillator strength: " << dxc.osc << "\n";
1028 }
1029 std::cout << " Decay channels:\n";
1030 const int nChannels = dxc.type.size();
1031 for (int j = 0; j < nChannels; ++j) {
1032 if (dxc.type[j] == DxcTypeRad) {
1033 std::cout << " Radiative decay to ";
1034 if (dxc.final[j] < 0) {
1035 std::cout << "ground state: ";
1036 } else {
1037 std::cout << m_deexcitations[dxc.final[j]].label << ": ";
1038 }
1039 } else if (dxc.type[j] == DxcTypeCollIon) {
1040 if (dxc.final[j] < 0) {
1041 std::cout << " Penning ionisation: ";
1042 } else {
1043 std::cout << " Associative ionisation: ";
1044 }
1045 } else if (dxc.type[j] == DxcTypeCollNonIon) {
1046 if (dxc.final[j] >= 0) {
1047 std::cout << " Collision-induced transition to "
1048 << m_deexcitations[dxc.final[j]].label << ": ";
1049 } else {
1050 std::cout << " Loss: ";
1051 }
1052 }
1053 const double br = j == 0 ? dxc.p[j] : dxc.p[j] - dxc.p[j - 1];
1054 std::cout << std::setprecision(5) << br * 100. << "%\n";
1055 }
1056 }
1057 }
1058
1059 return true;
1060}

◆ GetMaxElectronEnergy()

double Garfield::MediumMagboltz::GetMaxElectronEnergy ( ) const
inline

Get the highest electron energy in the table of scattering rates.

Definition at line 25 of file MediumMagboltz.hh.

25{ return m_eMax; }

◆ GetMaxPhotonEnergy()

double Garfield::MediumMagboltz::GetMaxPhotonEnergy ( ) const
inline

Get the highest photon energy in the table of scattering rates.

Definition at line 31 of file MediumMagboltz.hh.

31{ return m_eFinalGamma; }

◆ GetNumberOfDeexcitationProducts()

unsigned int Garfield::MediumMagboltz::GetNumberOfDeexcitationProducts ( ) const
inlineoverridevirtual

Reimplemented from Garfield::Medium.

Definition at line 91 of file MediumMagboltz.hh.

91 {
92 return m_dxcProducts.size();
93 }

◆ GetNumberOfElectronCollisions() [1/3]

unsigned int Garfield::MediumMagboltz::GetNumberOfElectronCollisions ( ) const

Get the total number of electron collisions.

Definition at line 958 of file MediumMagboltz.cc.

958 {
959 return std::accumulate(std::begin(m_nCollisions), std::end(m_nCollisions), 0);
960}

◆ GetNumberOfElectronCollisions() [2/3]

unsigned int Garfield::MediumMagboltz::GetNumberOfElectronCollisions ( const unsigned int  level) const

Get the number of collisions for a specific cross-section term.

Definition at line 1062 of file MediumMagboltz.cc.

1063 {
1064 if (level >= m_nTerms) {
1065 std::cerr << m_className << "::GetNumberOfElectronCollisions: "
1066 << "Level " << level << " does not exist.\n";
1067 return 0;
1068 }
1069 return m_nCollisionsDetailed[level];
1070}

◆ GetNumberOfElectronCollisions() [3/3]

unsigned int Garfield::MediumMagboltz::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.

Definition at line 962 of file MediumMagboltz.cc.

965 {
966 nElastic = m_nCollisions[ElectronCollisionTypeElastic];
967 nIonisation = m_nCollisions[ElectronCollisionTypeIonisation];
968 nAttachment = m_nCollisions[ElectronCollisionTypeAttachment];
969 nInelastic = m_nCollisions[ElectronCollisionTypeInelastic];
970 nExcitation = m_nCollisions[ElectronCollisionTypeExcitation];
971 nSuperelastic = m_nCollisions[ElectronCollisionTypeSuperelastic];
972 return nElastic + nIonisation + nAttachment + nInelastic + nExcitation +
973 nSuperelastic;
974}

◆ GetNumberOfLevels()

unsigned int Garfield::MediumMagboltz::GetNumberOfLevels ( )

Get the number of cross-section terms.

Definition at line 976 of file MediumMagboltz.cc.

976 {
977 if (m_isChanged) {
978 if (!Mixer()) {
979 PrintErrorMixer(m_className + "::GetNumberOfLevels");
980 return 0;
981 }
982 m_isChanged = false;
983 }
984
985 return m_nTerms;
986}

◆ GetNumberOfPenningTransfers()

unsigned int Garfield::MediumMagboltz::GetNumberOfPenningTransfers ( ) const
inline

Get the number of Penning transfers that occured since the last reset.

Definition at line 121 of file MediumMagboltz.hh.

121{ return m_nPenning; }

◆ GetNumberOfPhotonCollisions() [1/2]

unsigned int Garfield::MediumMagboltz::GetNumberOfPhotonCollisions ( ) const

Get the total number of photon collisions.

Definition at line 1072 of file MediumMagboltz.cc.

1072 {
1073 return std::accumulate(std::begin(m_nPhotonCollisions),
1074 std::end(m_nPhotonCollisions), 0);
1075}

◆ GetNumberOfPhotonCollisions() [2/2]

unsigned int Garfield::MediumMagboltz::GetNumberOfPhotonCollisions ( unsigned int &  nElastic,
unsigned int &  nIonising,
unsigned int &  nInelastic 
) const

Get number of photon collisions by collision type.

Definition at line 1077 of file MediumMagboltz.cc.

1079 {
1080 nElastic = m_nPhotonCollisions[0];
1081 nIonising = m_nPhotonCollisions[1];
1082 nInelastic = m_nPhotonCollisions[2];
1083 return nElastic + nIonising + nInelastic;
1084}

◆ GetPhotonCollision()

bool Garfield::MediumMagboltz::GetPhotonCollision ( const double  e,
int &  type,
int &  level,
double &  e1,
double &  ctheta,
int &  nsec,
double &  esec 
)
overridevirtual

Reimplemented from Garfield::Medium.

Definition at line 858 of file MediumMagboltz.cc.

860 {
861 if (e <= 0.) {
862 std::cerr << m_className << "::GetPhotonCollision: Invalid energy.\n";
863 return false;
864 }
865 if (e > m_eFinalGamma && m_useAutoAdjust) {
866 std::cerr << m_className << "::GetPhotonCollision:\n Provided energy ("
867 << e << " eV) exceeds current energy range.\n"
868 << " Increasing energy range to " << 1.05 * e << " eV.\n";
869 SetMaxPhotonEnergy(1.05 * e);
870 }
871
872 if (m_isChanged) {
873 if (!Mixer()) {
874 PrintErrorMixer(m_className + "::GetPhotonCollision");
875 return false;
876 }
877 m_isChanged = false;
878 }
879
880 // Energy interval
881 const int iE =
882 std::min(std::max(int(e / m_eStepGamma), 0), nEnergyStepsGamma - 1);
883
884 double r = m_cfTotGamma[iE];
885 if (m_useDeexcitation && m_useRadTrap && !m_deexcitations.empty()) {
886 int nLines = 0;
887 std::vector<double> pLine(0);
888 std::vector<int> iLine(0);
889 // Loop over the excitations.
890 const unsigned int nDeexcitations = m_deexcitations.size();
891 for (unsigned int i = 0; i < nDeexcitations; ++i) {
892 const auto& dxc = m_deexcitations[i];
893 if (dxc.cf > 0. && fabs(e - dxc.energy) <= dxc.width) {
894 r += dxc.cf *
895 TMath::Voigt(e - dxc.energy, dxc.sDoppler, 2 * dxc.gPressure);
896 pLine.push_back(r);
897 iLine.push_back(i);
898 ++nLines;
899 }
900 }
901 r *= RndmUniform();
902 if (nLines > 0 && r >= m_cfTotGamma[iE]) {
903 // Photon is absorbed by a discrete line.
904 for (int i = 0; i < nLines; ++i) {
905 if (r <= pLine[i]) {
906 ++m_nPhotonCollisions[PhotonCollisionTypeExcitation];
907 int fLevel = 0;
908 ComputeDeexcitationInternal(iLine[i], fLevel);
909 type = PhotonCollisionTypeExcitation;
910 nsec = m_dxcProducts.size();
911 return true;
912 }
913 }
914 std::cerr << m_className << "::GetPhotonCollision:\n";
915 std::cerr << " Random sampling of deexcitation line failed.\n";
916 std::cerr << " Program bug!\n";
917 return false;
918 }
919 } else {
920 r *= RndmUniform();
921 }
922
923 if (r <= m_cfGamma[iE][0]) {
924 level = 0;
925 } else if (r >= m_cfGamma[iE][m_nPhotonTerms - 1]) {
926 level = m_nPhotonTerms - 1;
927 } else {
928 const auto begin = m_cfGamma[iE].cbegin();
929 level = std::lower_bound(begin, begin + m_nPhotonTerms, r) - begin;
930 }
931
932 nsec = 0;
933 esec = e1 = 0.;
934 type = csTypeGamma[level];
935 // Collision type
936 type = type % nCsTypesGamma;
937 int ngas = int(csTypeGamma[level] / nCsTypesGamma);
938 ++m_nPhotonCollisions[type];
939 // Ionising collision
940 if (type == 1) {
941 esec = std::max(e - m_ionPot[ngas], Small);
942 nsec = 1;
943 }
944
945 // Determine the scattering angle
946 ctheta = 2 * RndmUniform() - 1.;
947
948 return true;
949}
bool SetMaxPhotonEnergy(const double e)
DoubleAc fabs(const DoubleAc &f)
Definition: DoubleAc.h:615

◆ GetPhotonCollisionRate()

double Garfield::MediumMagboltz::GetPhotonCollisionRate ( const double  e)
overridevirtual

Reimplemented from Garfield::Medium.

Definition at line 821 of file MediumMagboltz.cc.

821 {
822 if (e <= 0.) {
823 std::cerr << m_className << "::GetPhotonCollisionRate: Invalid energy.\n";
824 return m_cfTotGamma[0];
825 }
826 if (e > m_eFinalGamma && m_useAutoAdjust) {
827 std::cerr << m_className << "::GetPhotonCollisionRate:\n Rate at " << e
828 << " eV is not included in the current table.\n"
829 << " Increasing energy range to " << 1.05 * e << " eV.\n";
830 SetMaxPhotonEnergy(1.05 * e);
831 }
832
833 if (m_isChanged) {
834 if (!Mixer()) {
835 PrintErrorMixer(m_className + "::GetPhotonCollisionRate");
836 return 0.;
837 }
838 m_isChanged = false;
839 }
840
841 const int iE =
842 std::min(std::max(int(e / m_eStepGamma), 0), nEnergyStepsGamma - 1);
843
844 double cfSum = m_cfTotGamma[iE];
845 if (m_useDeexcitation && m_useRadTrap && !m_deexcitations.empty()) {
846 // Loop over the excitations.
847 for (const auto& dxc : m_deexcitations) {
848 if (dxc.cf > 0. && fabs(e - dxc.energy) <= dxc.width) {
849 cfSum += dxc.cf *
850 TMath::Voigt(e - dxc.energy, dxc.sDoppler, 2 * dxc.gPressure);
851 }
852 }
853 }
854
855 return cfSum;
856}

◆ Initialise()

bool Garfield::MediumMagboltz::Initialise ( const bool  verbose = false)

Initialise the table of scattering rates (called internally when a collision rate is requested and the gas mixture or other parameters have changed).

Definition at line 362 of file MediumMagboltz.cc.

362 {
363 if (!m_isChanged) {
364 if (m_debug) {
365 std::cerr << m_className << "::Initialise: Nothing changed.\n";
366 }
367 return true;
368 }
369 if (!Mixer(verbose)) {
370 PrintErrorMixer(m_className + "::Initialise");
371 return false;
372 }
373 m_isChanged = false;
374 return true;
375}

Referenced by GarfieldPhysics::InitializePhysics(), and PrintGas().

◆ PrintGas()

void Garfield::MediumMagboltz::PrintGas ( )
overridevirtual

Print information about the present gas mixture and available data.

Reimplemented from Garfield::MediumGas.

Definition at line 377 of file MediumMagboltz.cc.

377 {
379
380 if (m_isChanged) {
381 if (!Initialise()) return;
382 }
383
384 std::cout << " Electron cross-sections:\n";
385 int igas = -1;
386 for (unsigned int i = 0; i < m_nTerms; ++i) {
387 // Collision type
388 int type = m_csType[i] % nCsTypes;
389 if (igas != int(m_csType[i] / nCsTypes)) {
390 igas = int(m_csType[i] / nCsTypes);
391 std::cout << " " << m_gas[igas] << "\n";
392 }
393 // Description (from Magboltz)
394 // Threshold energy
395 double e = m_rgas[igas] * m_energyLoss[i];
396 std::cout << " Level " << i << ": " << m_description[i] << "\n";
397 std::cout << " Type " << type;
398 if (type == ElectronCollisionTypeElastic) {
399 std::cout << " (elastic)\n";
400 } else if (type == ElectronCollisionTypeIonisation) {
401 std::cout << " (ionisation). Ionisation threshold: " << e << " eV.\n";
402 } else if (type == ElectronCollisionTypeAttachment) {
403 std::cout << " (attachment)\n";
404 } else if (type == ElectronCollisionTypeInelastic) {
405 std::cout << " (inelastic). Energy loss: " << e << " eV.\n";
406 } else if (type == ElectronCollisionTypeExcitation) {
407 std::cout << " (excitation). Excitation energy: " << e << " eV.\n";
408 } else if (type == ElectronCollisionTypeSuperelastic) {
409 std::cout << " (super-elastic). Energy gain: " << -e << " eV.\n";
410 } else if (type == ElectronCollisionTypeVirtual) {
411 std::cout << " (virtual)\n";
412 } else {
413 std::cout << " (unknown)\n";
414 }
415 if (type == ElectronCollisionTypeExcitation && m_usePenning &&
416 e > m_minIonPot) {
417 std::cout << " Penning transfer coefficient: "
418 << m_rPenning[i] << "\n";
419 } else if (type == ElectronCollisionTypeExcitation && m_useDeexcitation) {
420 const int idxc = m_iDeexcitation[i];
421 if (idxc < 0 || idxc >= (int)m_deexcitations.size()) {
422 std::cout << " Deexcitation cascade not implemented.\n";
423 continue;
424 }
425 const auto& dxc = m_deexcitations[idxc];
426 if (dxc.osc > 0.) {
427 std::cout << " Oscillator strength: " << dxc.osc << "\n";
428 }
429 std::cout << " Decay channels:\n";
430 const int nChannels = dxc.type.size();
431 for (int j = 0; j < nChannels; ++j) {
432 if (dxc.type[j] == DxcTypeRad) {
433 std::cout << " Radiative decay to ";
434 if (dxc.final[j] < 0) {
435 std::cout << "ground state: ";
436 } else {
437 std::cout << m_deexcitations[dxc.final[j]].label << ": ";
438 }
439 } else if (dxc.type[j] == DxcTypeCollIon) {
440 if (dxc.final[j] < 0) {
441 std::cout << " Penning ionisation: ";
442 } else {
443 std::cout << " Associative ionisation: ";
444 }
445 } else if (dxc.type[j] == DxcTypeCollNonIon) {
446 if (dxc.final[j] >= 0) {
447 std::cout << " Collision-induced transition to "
448 << m_deexcitations[dxc.final[j]].label << ": ";
449 } else {
450 std::cout << " Loss: ";
451 }
452 }
453 const double br = j == 0 ? dxc.p[j] : dxc.p[j] - dxc.p[j - 1];
454 std::cout << std::setprecision(5) << br * 100. << "%\n";
455 }
456 }
457 }
458}
virtual void PrintGas()
Print information about the present gas mixture and available data.
Definition: MediumGas.cc:2067
bool Initialise(const bool verbose=false)

◆ ResetCollisionCounters()

void Garfield::MediumMagboltz::ResetCollisionCounters ( )

Reset the collision counters.

Definition at line 951 of file MediumMagboltz.cc.

951 {
952 m_nCollisions.fill(0);
953 m_nCollisionsDetailed.assign(m_nTerms, 0);
954 m_nPenning = 0;
955 m_nPhotonCollisions.fill(0);
956}

◆ RunMagboltz()

void Garfield::MediumMagboltz::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 
)

Run Magboltz for a given electric field, magnetic field and angle.

Parameters
[in]eelectric field
[in]bmagnetic field
[in]bthetaangle between electric and magnetic field
[in]ncollnumber of collisions (in multiples of 107) to be simulated
[in]verboseverbosity flag
[out]vx,vy,vzdrift velocity vector
[out]dl,dtdiffusion cofficients
[out]alphaTownsend cofficient
[out]etaattachment cofficient
[out]lorLorentz angle
[out]vxerr,vyerr,vzerrerrors on drift velocity
[out]dlerr,dterrerrors on diffusion coefficients
[out]alphaerr,etaerrerrors on Townsend/attachment coefficients
[out]lorerrerror on Lorentz angle
[out]alphatofeffective Townsend coefficient $(\alpha - \eta)$ calculated using time-of-flight method
[out]difftenscomponents of the diffusion tensor (zz, xx, yy, xz, yz, xy)

Definition at line 3365 of file MediumMagboltz.cc.

3371 {
3372 // Initialize the values.
3373 vx = vy = vz = 0.;
3374 dl = dt = 0.;
3375 alpha = eta = alphatof = 0.;
3376 lor = 0.;
3377 vxerr = vyerr = vzerr = 0.;
3378 dlerr = dterr = 0.;
3379 alphaerr = etaerr = 0.;
3380 lorerr = 0.;
3381
3382 // Set input parameters in Magboltz common blocks.
3384 Magboltz::inpt_.nStep = 4000;
3385 Magboltz::inpt_.nAniso = 2;
3386 if (m_autoEnergyLimit) {
3387 Magboltz::inpt_.efinal = 0.;
3388 } else {
3389 Magboltz::inpt_.efinal = std::min(m_eMax, m_eHigh);
3390 Magboltz::inpt_.estep = m_eStep;
3391 }
3392 Magboltz::inpt_.tempc = m_temperature - ZeroCelsius;
3394 Magboltz::inpt_.ipen = 0;
3395 Magboltz::setp_.nmax = ncoll;
3396
3397 Magboltz::thrm_.ithrm = m_useGasMotion ? 1 : 0;
3398
3399 Magboltz::setp_.efield = e;
3400 // Convert from Tesla to kGauss.
3401 Magboltz::bfld_.bmag = bmag * 10.;
3402 // Convert from radians to degree.
3403 Magboltz::bfld_.btheta = btheta * RadToDegree;
3404
3405 // Set the gas composition in Magboltz.
3406 for (unsigned int i = 0; i < m_nComponents; ++i) {
3407 const int ng = GetGasNumberMagboltz(m_gas[i]);
3408 if (ng <= 0) {
3409 std::cerr << m_className << "::RunMagboltz:\n Gas " << m_gas[i]
3410 << " does not have a gas number in Magboltz.\n";
3411 return;
3412 }
3413 Magboltz::gasn_.ngasn[i] = ng;
3414 Magboltz::ratio_.frac[i] = 100 * m_fraction[i];
3415 }
3416
3417 // Run Magboltz.
3419
3420 // Velocities. Convert to cm / ns.
3421 vx = Magboltz::vel_.wx * 1.e-9;
3422 vxerr = Magboltz::velerr_.dwx;
3423 vy = Magboltz::vel_.wy * 1.e-9;
3424 vyerr = Magboltz::velerr_.dwy;
3425 vz = Magboltz::vel_.wz * 1.e-9;
3426 vzerr = Magboltz::velerr_.dwz;
3427
3428 // Calculate the Lorentz angle.
3429 const double vt = sqrt(vx * vx + vy * vy);
3430 const double v2 = (vx * vx + vy * vy + vz * vz);
3431 lor = atan2(vt, vz);
3432 if (vt > 0. && v2 > 0. && fabs(lor) > 0.) {
3433 const double dvx = vx * vxerr;
3434 const double dvy = vy * vyerr;
3435 const double dvz = vz * vzerr;
3436 const double a = vz / vt;
3437 lorerr = sqrt(a * a * (vx * vx * dvx * dvx + vy * vy * dvy * dvy) +
3438 vt * vt * dvz * dvz) /
3439 v2;
3440 lorerr /= lor;
3441 }
3442
3443 // Diffusion coefficients.
3444 dt = sqrt(0.2 * 0.5 * (Magboltz::diflab_.difxx + Magboltz::diflab_.difyy) /
3445 vz) *
3446 1.e-4;
3447 dterr = 0.5 * sqrt(Magboltz::diferl_.dfter * Magboltz::diferl_.dfter +
3448 vzerr * vzerr);
3449 dl = sqrt(0.2 * Magboltz::diflab_.difzz / vz) * 1.e-4;
3450 dlerr = 0.5 * sqrt(Magboltz::diferl_.dfler * Magboltz::diferl_.dfler +
3451 vzerr * vzerr);
3452 // Diffusion tensor.
3453 difftens[0] = 0.2e-4 * Magboltz::diflab_.difzz / vz;
3454 difftens[1] = 0.2e-4 * Magboltz::diflab_.difxx / vz;
3455 difftens[2] = 0.2e-4 * Magboltz::diflab_.difyy / vz;
3456 difftens[3] = 0.2e-4 * Magboltz::diflab_.difxz / vz;
3457 difftens[4] = 0.2e-4 * Magboltz::diflab_.difyz / vz;
3458 difftens[5] = 0.2e-4 * Magboltz::diflab_.difxy / vz;
3459 // Townsend and attachment coefficients.
3460 alpha = Magboltz::ctowns_.alpha;
3461 alphaerr = Magboltz::ctwner_.alper;
3462 eta = Magboltz::ctowns_.att;
3463 etaerr = Magboltz::ctwner_.atter;
3464
3465 // Calculate effective Townsend SST coefficient from TOF results.
3466 if (fabs(Magboltz::tofout_.tofdl) > 0.) {
3467 const double wrzn = 1.e5 * Magboltz::tofout_.tofwr;
3468 const double fc1 = 0.5 * wrzn / Magboltz::tofout_.tofdl;
3469 const double fc2 = (Magboltz::tofout_.ralpha -
3470 Magboltz::tofout_.rattof) * 1.e12 /
3471 Magboltz::tofout_.tofdl;
3472 alphatof = fc1 - sqrt(fc1 * fc1 - fc2);
3473 }
3474 // Print the results.
3475 if (!(m_debug || verbose)) return;
3476 std::cout << m_className << "::RunMagboltz: Results:\n";
3477 printf(" Drift velocity along E: %12.8f cm/ns +/- %5.2f%%\n", vz, vzerr);
3478 printf(" Drift velocity along Bt: %12.8f cm/ns +/- %5.2f%%\n", vx, vxerr);
3479 printf(" Drift velocity along ExB: %12.8f cm/ns +/- %5.2f%%\n", vy, vyerr);
3480 printf(" Lorentz angle: %12.3f degree\n", lor * RadToDegree);
3481 printf(" Longitudinal diffusion: %12.8f cm1/2 +/- %5.2f%%\n", dl, dlerr);
3482 printf(" Transverse diffusion: %12.8f cm1/2 +/- %5.2f%%\n", dt, dterr);
3483 printf(" Townsend coefficient: %12.4f cm-1 +/- %5.2f%%\n", alpha,
3484 alphaerr);
3485 printf(" Attachment coefficient: %12.4f cm-1 +/- %5.2f%%\n", eta,
3486 etaerr);
3487 if (alphatof > 0.) {
3488 printf(" TOF effective Townsend: %12.4f cm-1 (alpha - eta)\n",
3489 alphatof);
3490 }
3491}
std::array< double, m_nMaxGases > m_fraction
Definition: MediumGas.hh:130
struct Garfield::Magboltz::@13 velerr_
struct Garfield::Magboltz::@19 ctwner_
struct Garfield::Magboltz::@11 ratio_
struct Garfield::Magboltz::@0 bfld_
struct Garfield::Magboltz::@2 setp_
struct Garfield::Magboltz::@12 vel_
struct Garfield::Magboltz::@10 gasn_
struct Garfield::Magboltz::@3 thrm_
struct Garfield::Magboltz::@17 diferl_
struct Garfield::Magboltz::@14 diflab_
struct Garfield::Magboltz::@20 tofout_
struct Garfield::Magboltz::@18 ctowns_

Referenced by GenerateGasTable().

◆ SetExcitationScaling()

void Garfield::MediumMagboltz::SetExcitationScaling ( const double  r,
std::string  gasname 
)

Multiply all excitation cross-sections by a uniform scaling factor.

Definition at line 328 of file MediumMagboltz.cc.

328 {
329 if (r <= 0.) {
330 std::cerr << m_className << "::SetExcitationScaling: Incorrect value.\n";
331 return;
332 }
333
334 // Get the "standard" name of this gas.
335 gasname = GetGasName(gasname);
336 if (gasname.empty()) {
337 std::cerr << m_className << "::SetExcitationScaling: Unknown gas name.\n";
338 return;
339 }
340
341 // Look for this gas in the present gas mixture.
342 bool found = false;
343 for (unsigned int i = 0; i < m_nComponents; ++i) {
344 if (m_gas[i] == gasname) {
345 m_scaleExc[i] = r;
346 found = true;
347 break;
348 }
349 }
350
351 if (!found) {
352 std::cerr << m_className << "::SetExcitationScaling:\n"
353 << " Specified gas (" << gasname
354 << ") is not part of the present gas mixture.\n";
355 return;
356 }
357
358 // Make sure that the collision rate table is updated.
359 m_isChanged = true;
360}

◆ SetMaxElectronEnergy()

bool Garfield::MediumMagboltz::SetMaxElectronEnergy ( const double  e)

Set the highest electron energy to be included in the table of scattering rates.

Definition at line 91 of file MediumMagboltz.cc.

91 {
92 if (e <= Small) {
93 std::cerr << m_className << "::SetMaxElectronEnergy: Invalid energy.\n";
94 return false;
95 }
96 m_eMax = e;
97
98 // Determine the energy interval size.
99 m_eStep = std::min(m_eMax, m_eHigh) / Magboltz::nEnergySteps;
100
101 // Force recalculation of the scattering rates table.
102 m_isChanged = true;
103
104 return true;
105}

Referenced by GetElectronCollision(), and GetElectronCollisionRate().

◆ SetMaxPhotonEnergy()

bool Garfield::MediumMagboltz::SetMaxPhotonEnergy ( const double  e)

Set the highest photon energy to be included in the table of scattering rates.

Definition at line 107 of file MediumMagboltz.cc.

107 {
108 if (e <= Small) {
109 std::cerr << m_className << "::SetMaxPhotonEnergy: Invalid energy.\n";
110 return false;
111 }
112 m_eFinalGamma = e;
113
114 // Determine the energy interval size.
115 m_eStepGamma = m_eFinalGamma / nEnergyStepsGamma;
116
117 // Force recalculation of the scattering rates table.
118 m_isChanged = true;
119
120 return true;
121}

Referenced by GetPhotonCollision(), and GetPhotonCollisionRate().

◆ SetSplittingFunctionFlat()

void Garfield::MediumMagboltz::SetSplittingFunctionFlat ( )

Sample the secondary electron energy from a flat distribution.

Definition at line 146 of file MediumMagboltz.cc.

146 {
147 m_useOpalBeaty = false;
148 m_useGreenSawada = false;
149}

◆ SetSplittingFunctionGreenSawada()

void Garfield::MediumMagboltz::SetSplittingFunctionGreenSawada ( )

Sample the secondary electron energy according to the Green-Sawada model.

Definition at line 128 of file MediumMagboltz.cc.

128 {
129 m_useOpalBeaty = false;
130 m_useGreenSawada = true;
131 if (m_isChanged) return;
132
133 bool allset = true;
134 for (unsigned int i = 0; i < m_nComponents; ++i) {
135 if (!m_hasGreenSawada[i]) {
136 if (allset) {
137 std::cout << m_className << "::SetSplittingFunctionGreenSawada:\n";
138 allset = false;
139 }
140 std::cout << " Fit parameters for " << m_gas[i] << " not available.\n"
141 << " Using Opal-Beaty formula instead.\n";
142 }
143 }
144}

◆ SetSplittingFunctionOpalBeaty()

void Garfield::MediumMagboltz::SetSplittingFunctionOpalBeaty ( )

Sample the secondary electron energy according to the Opal-Beaty model.

Definition at line 123 of file MediumMagboltz.cc.

123 {
124 m_useOpalBeaty = true;
125 m_useGreenSawada = false;
126}

The documentation for this class was generated from the following files: