ATLAS Offline Software
Loading...
Searching...
No Matches
TRT_PAI_effectiveGas Class Reference

Effective gas: All quantities necessary to calculate PAI ionisation for gas mixture. More...

#include <TRT_PAI_effectiveGas.h>

Inheritance diagram for TRT_PAI_effectiveGas:
Collaboration diagram for TRT_PAI_effectiveGas:

Public Member Functions

 TRT_PAI_effectiveGas (TRT_PAI_gasMixture *gm, double Emin, double Emax, double tempK, double eps)
void GasTab (const std::vector< float > &gamvec, std::vector< float > &EArray, std::vector< std::vector< float > > &fnArray, std::vector< float > &dndx)
 Tabulate double differential distribution.
bool msgLvl (const MSG::Level lvl) const
 Test the output level.
MsgStream & msg () const
 The standard message stream.
MsgStream & msg (const MSG::Level lvl) const
 The standard message stream.
void setLevel (MSG::Level lvl)
 Change the current logging level.

Private Member Functions

double XSigma (double lnE, double dummy)
double XFReal (double lnD, double lnE)
double XGInt (double(TRT_PAI_effectiveGas::*pt2Func)(double, double), double lnLo, double lnHi, const double eps, double extraParameter)
double dndedx (double lgE, double gamma)
void initMessaging () const
 Initialize our message level and MessageSvc.

Private Attributes

std::vector< float > m_lnELvls
std::vector< float > m_lnFosc
std::vector< float > m_lnIntegratedSigmas
std::vector< float > m_lnEpsR
std::vector< float > m_lnEpsI
const double m_lnEmin {}
const double m_lnEmax {}
const double m_eps {}
double m_S1 {}
double m_Wp2 {}
double m_S2 {}
double m_ne {}
std::string m_nm
 Message source name.
boost::thread_specific_ptr< MsgStream > m_msg_tls
 MsgStream instance (a std::cout like with print-out levels)
std::atomic< IMessageSvc * > m_imsg { nullptr }
 MessageSvc pointer.
std::atomic< MSG::Level > m_lvl { MSG::NIL }
 Current logging level.
std::atomic_flag m_initialized ATLAS_THREAD_SAFE = ATOMIC_FLAG_INIT
 Messaging initialized (initMessaging)

Detailed Description

Effective gas: All quantities necessary to calculate PAI ionisation for gas mixture.

Definition at line 18 of file TRT_PAI_effectiveGas.h.

Constructor & Destructor Documentation

◆ TRT_PAI_effectiveGas()

TRT_PAI_effectiveGas::TRT_PAI_effectiveGas ( TRT_PAI_gasMixture * gm,
double Emin,
double Emax,
double tempK,
double eps )
Parameters
gmgas mixture
Eminminimum energy transfer considered in calculations [eV]
Emaxmaximum energy transfer considered in calculations [ev]
tempKgas temperature [Kelvin]
epsepsilon for numeric integration
mlogMessage stream

Definition at line 24 of file TRT_PAI_effectiveGas.cxx.

29 : AthMessaging("TRT_PAI_effectiveGas"),
30 m_lnEmin(std::log(Emin)),
31 m_lnEmax(std::log(Emax)),
32 m_eps(eps)
33{
34 // Tell clang to optimize assuming that FP may trap.
36
37 using namespace TRT_PAI_physicsConstants;
38
39 TRT_PAI_element* pe;
40 double rho = 0.;
41 double Zeff = 0.;
42 double Aeff = 0.;
43 double w = 0.;
44 double wtot = 0.;
45 int Nelem = gm->getNElements();
46
47 for ( int k=0; k<Nelem; k++ ) {
48 pe = gm->getElement(k);
49 w = gm->getElemWeight(k);
50 wtot += w;
51 rho += w * pe->getDensity(tempK);
52 Aeff += w * pe->getAtomicA();
53 Zeff += w * pe->getAtomicZ();
54 }
55 if (wtot == 0.)[[unlikely]]{
56 ATH_MSG_ERROR("TRT_PAI_effectiveGas::TRT_PAI_effectiveGas: wtot is zero.");
57 return;
58 }
59 Aeff /= wtot;
60 Zeff /= wtot;
61
62 m_ne = Nav*rho*Zeff/Aeff; // Electron density
63 m_Wp2 = 4.*M_PI*r0*m_ne*he*he; // plasma freq**2 {ev}
64 m_S1 = mb/(2.*M_PI*M_PI*r0*he*Zeff); // x-section to F.osc
65 m_S2 = 2.*M_PI*r0*m_ne*Qe*Qe/erg; // dN/dx scale
66
67 ATH_MSG_DEBUG ( "effectiveGas: Electron density " << m_ne );
68 ATH_MSG_DEBUG ( "effectiveGas: Plasma freq**2 {eV} " << m_Wp2 );
69 ATH_MSG_DEBUG ( "effectiveGas: x-section to F.osc " << m_S1 );
70 ATH_MSG_DEBUG ( "effectiveGas: dN/dx scale " << m_S2 );
71
72 // Merge all energy levels into ELvls
73 std::vector<float> tempv;
74 for ( int k=0; k<Nelem; k++ ) {
75 pe = gm->getElement(k);
76 tempv = pe->getLnELvls();
77 m_lnELvls.insert( m_lnELvls.end(), tempv.begin(), tempv.end() );
78 }
79
80 // Insert also Emin and Emax into ELvls, then sort
81 m_lnELvls.push_back(m_lnEmin);
82 m_lnELvls.push_back(m_lnEmax);
83 sort(m_lnELvls.begin(),m_lnELvls.end());
84
85 std::vector<float>::iterator vit;
86
87 // Remove duplicate energies
88 vit = unique(m_lnELvls.begin(), m_lnELvls.end());
89 m_lnELvls.erase(vit, m_lnELvls.end());
90
91 // Remove everything below Emin
92 vit = lower_bound(m_lnELvls.begin(), m_lnELvls.end(), m_lnEmin);
93 m_lnELvls.erase(m_lnELvls.begin(), vit);
94
95 // Remove everything above Emax
96 vit = upper_bound(m_lnELvls.begin(), m_lnELvls.end(), m_lnEmax)-1;
97 m_lnELvls.erase(vit, m_lnELvls.end());
98
99 int NLvls = m_lnELvls.size();
100
101
102 // Expand vectors to correct dimension
103 m_lnFosc.resize(NLvls);
104 m_lnIntegratedSigmas.resize(NLvls);
105 m_lnEpsI.resize(NLvls);
106 m_lnEpsR.resize(NLvls);
107
108 // create array of effective cross sections (Fosc).
109
110 for ( int i=0; i<NLvls; i++ ) {
111 double fosc = 0.;
112 // all atoms with an absorbtion energylevel low enough contribute.
113 for ( int k=0; k<Nelem; k++ ) {
114 pe = gm->getElement(k);
115 if ( m_lnELvls[i] >= pe->getLnELvls()[0] ) {
116 double lnSig = TRT_PAI_utils::Interpolate( m_lnELvls[i],
117 pe->getLnELvls(),
118 pe->getLnSigmas() );
119 fosc += std::exp(lnSig) * gm->getElemWeight(k);
120 }
121 }
122 //clamp, just in case
123 fosc = std::clamp(fosc, 1e-300,1e+300);
124 m_lnFosc[i] = std::log(fosc);
125 }
126
127 // Create array of integrated cross-sections
128 double sigma = 0.;
129 double lnSigma = 0.;
130 double lnEHigh;
131 double lnELow = m_lnEmax;
132 double dsigma;
133
134 for ( int i=NLvls-1; i>=0; --i) {
135 lnEHigh = lnELow;
136 lnELow = m_lnELvls[i];
138 lnELow,
139 lnEHigh,
140 m_eps,
141 0.);
142 sigma += dsigma;
143 lnSigma = std::log(sigma);
144 m_lnIntegratedSigmas[i] = lnSigma;
145 }
146
147 // Normalize
148 for ( int i=0; i<NLvls; i++) {
149 m_lnFosc[i] -= lnSigma;
150 m_lnIntegratedSigmas[i] -= lnSigma;
151 }
152
153 double cnst = std::log(M_PI_2*m_Wp2);
154 for (int i=0; i<NLvls; i++) {
155 m_lnEpsI[i] = cnst - m_lnELvls[i] + m_lnFosc[i];
157 0.,
158 m_lnEmax,
159 m_eps,
160 m_lnELvls[i] );
161 m_lnEpsR[i] = m_Wp2 * std::exp(m_lnELvls[i]) * xint;
162 }
163 return;
164}
#define M_PI
#define ATH_MSG_ERROR(x)
#define ATH_MSG_DEBUG(x)
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
AthMessaging()
Default constructor:
std::vector< float > m_lnEpsI
double XFReal(double lnD, double lnE)
double XGInt(double(TRT_PAI_effectiveGas::*pt2Func)(double, double), double lnLo, double lnHi, const double eps, double extraParameter)
std::vector< float > m_lnELvls
double XSigma(double lnE, double dummy)
std::vector< float > m_lnIntegratedSigmas
std::vector< float > m_lnEpsR
std::vector< float > m_lnFosc
TRT_PAI_element * getElement(unsigned int n)
Get element no.
double getElemWeight(unsigned int n)
Get weight of element no.
int getNElements()
Get number of different element in this gas mixture.
#define unlikely(x)
Definition dictionary.h:41
const double erg
1 ev to erg {erg}
const double Nav
Avagadro constant.
const double Qe
Electron charge{ESU}.
const double r0
electron radius{cm}
float Interpolate(const float &xval, const std::vector< float > &xtabulated, const std::vector< float > &ytabulated)
Interpolation function.
DataModel_detail::iterator< DVL > unique(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of unique for DataVector/List.
#define CXXUTILS_TRAPPING_FP
Definition trapping_fp.h:24

Member Function Documentation

◆ dndedx()

double TRT_PAI_effectiveGas::dndedx ( double lgE,
double gamma )
private

Definition at line 244 of file TRT_PAI_effectiveGas.cxx.

244 {
245
246 using namespace TRT_PAI_physicsConstants;
247 using namespace TRT_PAI_utils;
248
249 double E = std::exp(lnE);
250 double gammaSq = gamma*gamma;
251 double betaSq = 1.-1./gammaSq;
252
253 double er = Interpolate(lnE, m_lnELvls, m_lnEpsR);
254 double ei = Interpolate(lnE, m_lnELvls, m_lnEpsI);
255
256 std::complex<double> Ceps1(er/(E*E), std::exp(ei));
257 std::complex<double> C1 = 1./gammaSq - Ceps1*betaSq;
258 std::complex<double> C2 = C1/(1.+Ceps1) * std::log(2.*betaSq*MeeV/(E*C1));
259
260 double x;
262 x = m_S2/betaSq * E * ( -2.*imag(C2)/(m_Wp2*M_PI) + (1.-std::exp(x))/(E*E) );
263
264 return x;
265}
#define x

◆ GasTab()

void TRT_PAI_effectiveGas::GasTab ( const std::vector< float > & gamvec,
std::vector< float > & EArray,
std::vector< std::vector< float > > & fnArray,
std::vector< float > & dndx )

Tabulate double differential distribution.

Parameters
gamvecvector of gamma values for which to tabulate
Earrayvector of energy transfer values
fnArraydouble differential distribution
dndxThis array effectively contains the inverse of the mean free path as function of binned energy variable

Definition at line 269 of file TRT_PAI_effectiveGas.cxx.

273{
274 // For a given gamma factor, return dn/dx
275 // (by integrating dn^2/dEdx with respect to E)
276 // and tabulated values of dn^2/dEdx(?)....
277
278 double Rener = 0.05;
279
280 int NLvls = m_lnELvls.size();
281 int nGamVals = gamvec.size();
282
283 double lnEi = m_lnEmax;
284 double lnEo;
285 double lnEs = -99999999.;
286
287 fnArray.resize(nGamVals);
288 int nEVals = 0;
289
290 // Initialize
291 for ( int ig=0; ig<nGamVals; ++ig ) {
292 fnArray[ig].push_back(0.);
293 }
294
295 // Calculate integral from above and store the cumulative values in fnArray
296
297 for ( int ie=NLvls-1; ie>=0; --ie ) {
298 lnEo = lnEi;
299 lnEi = m_lnELvls[ie];
300 for ( int ig=0; ig<nGamVals; ++ig ) {
301 double ds =
302 XGInt( &TRT_PAI_effectiveGas::dndedx, lnEi, lnEo, m_eps, gamvec[ig]);
303 fnArray[ig][nEVals] += ds;
304 }
305 if ( std::abs(lnEs-lnEi) > Rener || ie==0 ) {
306 lnEs = lnEi;
307 lnEarray.push_back( lnEs );
308 if ( ie>0 ) {
309 for ( int ig=0; ig<nGamVals; ++ig ) {
310 fnArray[ig].push_back( fnArray[ig][nEVals] );
311 }
312 }
313 nEVals++;
314 }
315 }
316
317 // Copy the total integral into auxillary vector
318 dndx.resize(nGamVals);
319 for ( int ig = 0; ig < nGamVals; ++ig ) {
320 dndx[ig] = fnArray[ig][nEVals-1];
321 }
322
323 return;
324}
double dndedx(double lgE, double gamma)

◆ initMessaging()

void AthMessaging::initMessaging ( ) const
privateinherited

Initialize our message level and MessageSvc.

This method should only be called once.

Definition at line 39 of file AthMessaging.cxx.

40{
42 // If user did not set an explicit level, set a default
43 if (m_lvl == MSG::NIL) {
44 m_lvl = m_imsg ?
45 static_cast<MSG::Level>( m_imsg.load()->outputLevel(m_nm) ) :
46 MSG::INFO;
47 }
48}
std::string m_nm
Message source name.
std::atomic< IMessageSvc * > m_imsg
MessageSvc pointer.
std::atomic< MSG::Level > m_lvl
Current logging level.
IMessageSvc * getMessageSvc(bool quiet=false)

◆ msg() [1/2]

MsgStream & AthMessaging::msg ( ) const
inlineinherited

The standard message stream.

Returns a reference to the default message stream May not be invoked before sysInitialize() has been invoked.

Definition at line 163 of file AthMessaging.h.

164{
165 MsgStream* ms = m_msg_tls.get();
166 if (!ms) {
167 if (!m_initialized.test_and_set()) initMessaging();
168 ms = new MsgStream(m_imsg,m_nm);
169 m_msg_tls.reset( ms );
170 }
171
172 ms->setLevel (m_lvl);
173 return *ms;
174}
boost::thread_specific_ptr< MsgStream > m_msg_tls
MsgStream instance (a std::cout like with print-out levels)
void initMessaging() const
Initialize our message level and MessageSvc.

◆ msg() [2/2]

MsgStream & AthMessaging::msg ( const MSG::Level lvl) const
inlineinherited

The standard message stream.

Returns a reference to the default message stream May not be invoked before sysInitialize() has been invoked.

Definition at line 178 of file AthMessaging.h.

179{ return msg() << lvl; }
MsgStream & msg() const
The standard message stream.

◆ msgLvl()

bool AthMessaging::msgLvl ( const MSG::Level lvl) const
inlineinherited

Test the output level.

Parameters
lvlThe message level to test against
Returns
boolean Indicating if messages at given level will be printed
Return values
trueMessages at level "lvl" will be printed

Definition at line 151 of file AthMessaging.h.

152{
153 if (m_lvl <= lvl) {
154 msg() << lvl;
155 return true;
156 } else {
157 return false;
158 }
159}

◆ setLevel()

void AthMessaging::setLevel ( MSG::Level lvl)
inherited

Change the current logging level.

Use this rather than msg().setLevel() for proper operation with MT.

Definition at line 28 of file AthMessaging.cxx.

29{
30 m_lvl = lvl;
31}

◆ XFReal()

double TRT_PAI_effectiveGas::XFReal ( double lnD,
double lnE )
private

Definition at line 180 of file TRT_PAI_effectiveGas.cxx.

180 {
181
182 double fp = 0.;
183 if ( lnE+lnD > m_lnEmin ) {
185 fp = std::exp(std::max(fp, -99.0));
186 }
187
188 double fm = 0.;
189 if (lnE-lnD > m_lnEmin ) {
191 fm = std::exp(std::max(fm, -99.0));
192 }
193
194 double x = std::exp(lnD);
195 return x/(x*x-1.)*(fp-fm);
196}

◆ XGInt()

double TRT_PAI_effectiveGas::XGInt ( double(TRT_PAI_effectiveGas::* pt2Func )(double, double),
double lnLo,
double lnHi,
const double eps,
double extraParameter )
private

Definition at line 200 of file TRT_PAI_effectiveGas.cxx.

204 {
205 //
206 // Pavel Nevskis "famous integration procedure"
207 //
208 // Applies the Gauss-Legendre Quadrature method with n=4
209
210 // These constants belong to the Gauss-Legendre quadrature method:
211 const int M = 4; // 4 points
212 const double U[M]={-.8611363,-.3399810, .3399810 ,.8611363}; // abscissas
213 const double W[M]={ .3478548, .6521452, .6521452, .3478548}; // weights
214
215 int N=10;
216 double OTB=0,Y,D,result;
217
218 double Dt = 0.5*(lnHi-lnLo);
219
220 do {
221 Y = OTB;
222 OTB = 0.;
223 D = Dt/N;
224 for (int i=1; i<=N; i++) {
225 for (int k=0; k<M; k++) {
226 double arg = lnLo + D*(2*i-1+U[k]);
227 OTB += W[k] * (this->*pt2Func)(arg, extraParameter );
228 }
229 }
230 OTB *= D;
231 result = OTB;
232 N *= 2;
233 if ( N>100000 ) {
234 ATH_MSG_WARNING( "effectiveGas::XGInt: integrate Divergence! " << std::abs(OTB-Y) << " " << std::abs(eps*OTB) );
235 break;
236 }
237 } while ( (std::abs(OTB-Y) > std::abs(eps*OTB)) && (eps>0) );
238
239 return result;
240}
#define ATH_MSG_WARNING(x)

◆ XSigma()

double TRT_PAI_effectiveGas::XSigma ( double lnE,
double dummy )
private

Definition at line 168 of file TRT_PAI_effectiveGas.cxx.

168 {
169 double xsig = dummy;
170 xsig = TRT_PAI_utils::Interpolate(std::max(lnE,m_lnEmin),
171 m_lnELvls,
172 m_lnFosc);
173 xsig = std::max(xsig,-99.);
174 xsig = std::exp( xsig + lnE );
175 return xsig;
176}

Member Data Documentation

◆ ATLAS_THREAD_SAFE

std::atomic_flag m_initialized AthMessaging::ATLAS_THREAD_SAFE = ATOMIC_FLAG_INIT
mutableprivateinherited

Messaging initialized (initMessaging)

Definition at line 141 of file AthMessaging.h.

◆ m_eps

const double TRT_PAI_effectiveGas::m_eps {}
private

Definition at line 62 of file TRT_PAI_effectiveGas.h.

62{}; // epsilon for numerical integration.

◆ m_imsg

std::atomic<IMessageSvc*> AthMessaging::m_imsg { nullptr }
mutableprivateinherited

MessageSvc pointer.

Definition at line 135 of file AthMessaging.h.

135{ nullptr };

◆ m_lnELvls

std::vector<float> TRT_PAI_effectiveGas::m_lnELvls
private

Definition at line 55 of file TRT_PAI_effectiveGas.h.

◆ m_lnEmax

const double TRT_PAI_effectiveGas::m_lnEmax {}
private

Definition at line 61 of file TRT_PAI_effectiveGas.h.

61{};

◆ m_lnEmin

const double TRT_PAI_effectiveGas::m_lnEmin {}
private

Definition at line 60 of file TRT_PAI_effectiveGas.h.

60{};

◆ m_lnEpsI

std::vector<float> TRT_PAI_effectiveGas::m_lnEpsI
private

Definition at line 59 of file TRT_PAI_effectiveGas.h.

◆ m_lnEpsR

std::vector<float> TRT_PAI_effectiveGas::m_lnEpsR
private

Definition at line 58 of file TRT_PAI_effectiveGas.h.

◆ m_lnFosc

std::vector<float> TRT_PAI_effectiveGas::m_lnFosc
private

Definition at line 56 of file TRT_PAI_effectiveGas.h.

◆ m_lnIntegratedSigmas

std::vector<float> TRT_PAI_effectiveGas::m_lnIntegratedSigmas
private

Definition at line 57 of file TRT_PAI_effectiveGas.h.

◆ m_lvl

std::atomic<MSG::Level> AthMessaging::m_lvl { MSG::NIL }
mutableprivateinherited

Current logging level.

Definition at line 138 of file AthMessaging.h.

138{ MSG::NIL };

◆ m_msg_tls

boost::thread_specific_ptr<MsgStream> AthMessaging::m_msg_tls
mutableprivateinherited

MsgStream instance (a std::cout like with print-out levels)

Definition at line 132 of file AthMessaging.h.

◆ m_ne

double TRT_PAI_effectiveGas::m_ne {}
private

Definition at line 66 of file TRT_PAI_effectiveGas.h.

66{} ; // Electron density

◆ m_nm

std::string AthMessaging::m_nm
privateinherited

Message source name.

Definition at line 129 of file AthMessaging.h.

◆ m_S1

double TRT_PAI_effectiveGas::m_S1 {}
private

Definition at line 63 of file TRT_PAI_effectiveGas.h.

63{} ; // x-section to F.osc

◆ m_S2

double TRT_PAI_effectiveGas::m_S2 {}
private

Definition at line 65 of file TRT_PAI_effectiveGas.h.

65{} ; // dN/dx scale

◆ m_Wp2

double TRT_PAI_effectiveGas::m_Wp2 {}
private

Definition at line 64 of file TRT_PAI_effectiveGas.h.

64{}; // plasma freq**2 {ev}

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