ATLAS Offline Software
Toggle main menu visibility
Loading...
Searching...
No Matches
InnerDetector
InDetSimUtils
TRT_PAI_Process
src
TRT_PAI_effectiveGas.cxx
Go to the documentation of this file.
1
/*
2
Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3
*/
4
5
#include "
TRT_PAI_Process.h
"
6
#include "
TRT_PAI_effectiveGas.h
"
7
#include "
TRT_PAI_gasMixture.h
"
8
#include "
TRT_PAI_gasComponent.h
"
9
#include "
TRT_PAI_element.h
"
10
#include "
TRT_PAI_utils.h
"
11
#include "
TRT_PAI_physicsConstants.h
"
12
#include "
CxxUtils/trapping_fp.h
"
13
14
#include <vector>
15
#include <iostream>
16
#include <complex>
17
#include <cmath>
18
#include <algorithm>
//for std::max, std::clamp
19
#include <limits>
20
#include "CLHEP/Units/SystemOfUnits.h"
21
22
//____________________________________________________________________________
23
24
TRT_PAI_effectiveGas::TRT_PAI_effectiveGas
(
TRT_PAI_gasMixture
* gm,
25
double
Emin,
26
double
Emax,
27
double
tempK,
28
double
eps)
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.
35
CXXUTILS_TRAPPING_FP
;
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 = std::numeric_limits<double>::min();
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];
137
dsigma =
XGInt
( &
TRT_PAI_effectiveGas::XSigma
,
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];
156
float
xint =
XGInt
(&
TRT_PAI_effectiveGas::XFReal
,
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
}
165
166
//____________________________________________________________________________
167
168
double
TRT_PAI_effectiveGas::XSigma
(
double
lnE,
double
dummy) {
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
}
177
178
//____________________________________________________________________________
179
180
double
TRT_PAI_effectiveGas::XFReal
(
double
lnD,
double
lnE) {
181
182
double
fp = 0.;
183
if
( lnE+lnD >
m_lnEmin
) {
184
fp =
TRT_PAI_utils::Interpolate
(lnE+lnD,
m_lnELvls
,
m_lnFosc
);
185
fp = std::exp(std::max(fp, -99.0));
186
}
187
188
double
fm = 0.;
189
if
(lnE-lnD >
m_lnEmin
) {
190
fm =
TRT_PAI_utils::Interpolate
(lnE-lnD,
m_lnELvls
,
m_lnFosc
);
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
}
197
198
//____________________________________________________________________________
199
200
double
TRT_PAI_effectiveGas::XGInt
(
double
(
TRT_PAI_effectiveGas
::*pt2Func)(
double
,
double
),
201
double
lnLo,
202
double
lnHi,
203
const
double
eps,
204
double
extraParameter ) {
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
}
241
242
//____________________________________________________________________________
243
244
double
TRT_PAI_effectiveGas::dndedx
(
double
lnE,
double
gamma) {
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
;
261
x
=
Interpolate
(lnE,
m_lnELvls
,
m_lnIntegratedSigmas
);
262
x
=
m_S2
/betaSq * E * ( -2.*imag(C2)/(
m_Wp2
*
M_PI
) + (1.-std::exp(
x
))/(E*E) );
263
264
return
x
;
265
}
266
267
//____________________________________________________________________________
268
269
void
TRT_PAI_effectiveGas::GasTab
(
const
std::vector<float> & gamvec,
270
std::vector<float>& lnEarray,
271
std::vector< std::vector<float> >& fnArray,
272
std::vector<float>& dndx)
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 =
XGInt
( &
TRT_PAI_effectiveGas::dndedx
, lnEi, lnEo,
m_eps
, gamvec[ig]);
302
fnArray[ig][nEVals] += ds;
303
}
304
if
( std::abs(lnEs-lnEi) > Rener || ie==0 ) {
305
lnEs = lnEi;
306
lnEarray.push_back( lnEs );
307
if
( ie>0 ) {
308
for
(
int
ig=0; ig<nGamVals; ++ig ) {
309
fnArray[ig].push_back( fnArray[ig][nEVals] );
310
}
311
}
312
nEVals++;
313
}
314
}
315
if
(nEVals == 0) {
316
return
;
317
}
318
const
auto
lastEval = nEVals - 1;
319
// Copy the total integral into auxillary vector
320
dndx.resize(nGamVals);
321
for
(
int
ig = 0; ig < nGamVals; ++ig ) {
322
dndx[ig] = fnArray[ig][lastEval];
323
}
324
325
return
;
326
}
327
M_PI
#define M_PI
Definition
ActiveFraction.h:14
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition
AthMsgStreamMacros.h:33
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition
AthMsgStreamMacros.h:32
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition
AthMsgStreamMacros.h:29
sort
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
Definition
DVL_algorithms.h:554
TRT_PAI_Process.h
TRT_PAI_effectiveGas.h
TRT_PAI_element.h
TRT_PAI_gasComponent.h
TRT_PAI_gasMixture.h
TRT_PAI_physicsConstants.h
TRT_PAI_utils.h
x
#define x
AthMessaging::AthMessaging
AthMessaging(IMessageSvc *msgSvc, const std::string &name)
Constructor.
Definition
AthMessaging.cxx:13
TRT_PAI_effectiveGas::m_lnEpsI
std::vector< float > m_lnEpsI
Definition
TRT_PAI_effectiveGas.h:59
TRT_PAI_effectiveGas::XFReal
double XFReal(double lnD, double lnE)
Definition
TRT_PAI_effectiveGas.cxx:180
TRT_PAI_effectiveGas::m_S1
double m_S1
Definition
TRT_PAI_effectiveGas.h:63
TRT_PAI_effectiveGas::XGInt
double XGInt(double(TRT_PAI_effectiveGas::*pt2Func)(double, double), double lnLo, double lnHi, const double eps, double extraParameter)
Definition
TRT_PAI_effectiveGas.cxx:200
TRT_PAI_effectiveGas::m_lnELvls
std::vector< float > m_lnELvls
Definition
TRT_PAI_effectiveGas.h:55
TRT_PAI_effectiveGas::XSigma
double XSigma(double lnE, double dummy)
Definition
TRT_PAI_effectiveGas.cxx:168
TRT_PAI_effectiveGas::m_lnIntegratedSigmas
std::vector< float > m_lnIntegratedSigmas
Definition
TRT_PAI_effectiveGas.h:57
TRT_PAI_effectiveGas::GasTab
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.
Definition
TRT_PAI_effectiveGas.cxx:269
TRT_PAI_effectiveGas::m_lnEpsR
std::vector< float > m_lnEpsR
Definition
TRT_PAI_effectiveGas.h:58
TRT_PAI_effectiveGas::m_eps
const double m_eps
Definition
TRT_PAI_effectiveGas.h:62
TRT_PAI_effectiveGas::m_Wp2
double m_Wp2
Definition
TRT_PAI_effectiveGas.h:64
TRT_PAI_effectiveGas::m_lnFosc
std::vector< float > m_lnFosc
Definition
TRT_PAI_effectiveGas.h:56
TRT_PAI_effectiveGas::m_S2
double m_S2
Definition
TRT_PAI_effectiveGas.h:65
TRT_PAI_effectiveGas::m_ne
double m_ne
Definition
TRT_PAI_effectiveGas.h:66
TRT_PAI_effectiveGas::dndedx
double dndedx(double lgE, double gamma)
Definition
TRT_PAI_effectiveGas.cxx:244
TRT_PAI_effectiveGas::m_lnEmin
const double m_lnEmin
Definition
TRT_PAI_effectiveGas.h:60
TRT_PAI_effectiveGas::m_lnEmax
const double m_lnEmax
Definition
TRT_PAI_effectiveGas.h:61
TRT_PAI_effectiveGas::TRT_PAI_effectiveGas
TRT_PAI_effectiveGas(TRT_PAI_gasMixture *gm, double Emin, double Emax, double tempK, double eps)
Definition
TRT_PAI_effectiveGas.cxx:24
TRT_PAI_element
Chemical element.
Definition
TRT_PAI_element.h:14
TRT_PAI_gasMixture
Gas mixture = mixture of gas components.
Definition
TRT_PAI_gasMixture.h:18
TRT_PAI_gasMixture::getElement
TRT_PAI_element * getElement(unsigned int n)
Get element no.
Definition
TRT_PAI_gasMixture.cxx:136
TRT_PAI_gasMixture::getElemWeight
double getElemWeight(unsigned int n)
Get weight of element no.
Definition
TRT_PAI_gasMixture.cxx:148
TRT_PAI_gasMixture::getNElements
int getNElements()
Get number of different element in this gas mixture.
Definition
TRT_PAI_gasMixture.h:60
TRT_PAI_physicsConstants
Physics constants.
Definition
TRT_PAI_physicsConstants.h:13
TRT_PAI_physicsConstants::erg
const double erg
1 ev to erg {erg}
Definition
TRT_PAI_physicsConstants.h:16
TRT_PAI_physicsConstants::mb
const double mb
1mb to cm2
Definition
TRT_PAI_physicsConstants.h:17
TRT_PAI_physicsConstants::MeeV
const double MeeV
same in ev
Definition
TRT_PAI_physicsConstants.h:19
TRT_PAI_physicsConstants::Nav
const double Nav
Avagadro constant.
Definition
TRT_PAI_physicsConstants.h:15
TRT_PAI_physicsConstants::he
const double he
same in ev
Definition
TRT_PAI_physicsConstants.h:24
TRT_PAI_physicsConstants::Qe
const double Qe
Electron charge{ESU}.
Definition
TRT_PAI_physicsConstants.h:21
TRT_PAI_physicsConstants::r0
const double r0
electron radius{cm}
Definition
TRT_PAI_physicsConstants.h:22
TRT_PAI_utils
Utilities.
Definition
TRT_PAI_utils.h:13
TRT_PAI_utils::Interpolate
float Interpolate(float xval, const std::vector< float > &xtabulated, const std::vector< float > &ytabulated)
Interpolation function.
Definition
TRT_PAI_utils.cxx:14
std
STL namespace.
unlikely
#define unlikely(x)
Definition
pythonic_coracool.cxx:9
trapping_fp.h
Tell the compiler to optimize assuming that FP may trap.
CXXUTILS_TRAPPING_FP
#define CXXUTILS_TRAPPING_FP
Definition
trapping_fp.h:24
Generated on
for ATLAS Offline Software by
1.17.0