Geant4  v4-10.4-release
 모두 클래스 네임스페이스들 파일들 함수 변수 타입정의 열거형 타입 열거형 멤버 Friends 매크로 그룹들 페이지들
G4GSPWACorrections.cc
이 파일의 문서화 페이지로 가기
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 // $Id: $
27 //
28 // ----------------------------------------------------------------------------
29 //
30 //
31 // File name: G4GSPWACorrections
32 //
33 // Author: Mihaly Novak
34 //
35 // Creation date: 17.10.2017
36 //
37 // Modifications:
38 // 02.02.2018 M.Novak: fixed initialization of first moment correction.
39 //
40 // Class description: see the header file.
41 //
42 // -----------------------------------------------------------------------------
43 
44 #include "G4GSPWACorrections.hh"
45 
46 #include "G4PhysicalConstants.hh"
47 #include "G4Log.hh"
48 #include "G4Exp.hh"
49 
50 #include "G4ProductionCutsTable.hh"
51 #include "G4MaterialCutsCouple.hh"
52 #include "G4Material.hh"
53 #include "G4ElementVector.hh"
54 #include "G4Element.hh"
55 
56 
57 const std::string G4GSPWACorrections::gElemSymbols[] = {"H","He","Li","Be","B" ,
58  "C" ,"N" ,"O" ,"F" ,"Ne","Na","Mg","Al","Si","P" , "S","Cl","Ar","K" ,"Ca","Sc",
59  "Ti","V" ,"Cr","Mn","Fe","Co","Ni","Cu","Zn","Ga","Ge","As","Se","Br","Kr","Rb",
60  "Sr","Y" ,"Zr","Nb","Mo","Tc","Ru","Rh","Pd","Ag","Cd","In","Sn","Sb","Te","I" ,
61  "Xe","Cs","Ba","La","Ce","Pr","Nd","Pm","Sm","Eu","Gd","Tb","Dy","Ho","Er","Tm",
62  "Yb","Lu","Hf","Ta","W" ,"Re","Os","Ir","Pt","Au","Hg","Tl","Pb","Bi","Po","At",
63  "Rn","Fr","Ra","Ac","Th","Pa","U" ,"Np","Pu","Am","Cm","Bk","Cf"};
64 
65 G4GSPWACorrections::G4GSPWACorrections(G4bool iselectron) : fIsElectron(iselectron) {
66  // init grids related data member values
67  fMaxEkin = CLHEP::electron_mass_c2*(1./std::sqrt(1.-gMaxBeta2)-1.);
73 }
74 
75 
79 }
80 
81 
83  G4double &corToScr, G4double &corToQ1, G4double &corToG2PerG1) {
84  G4int ekinIndxLow = 0;
85  G4double remRfaction = 0.;
86  if (beta2>=gMaxBeta2) {
87  ekinIndxLow = gNumEkin - 1;
88  // remRfaction = -1.
89  } else if (beta2>=fMinBeta2) { // linear interpolation on \beta^2
90  remRfaction = (beta2 - fMinBeta2) * fInvDelBeta2;
91  ekinIndxLow = (G4int)remRfaction;
92  remRfaction -= ekinIndxLow;
93  ekinIndxLow += (gNumEkin - gNumBeta2);
94  } else if (logekin>=fLogMinEkin) {
95  remRfaction = (logekin - fLogMinEkin) * fInvLogDelEkin;
96  ekinIndxLow = (G4int)remRfaction;
97  remRfaction -= ekinIndxLow;
98  } // the defaults otherwise i.e. use the lowest energy values when ekin is smaller than the minum ekin
99  //
101  corToScr = data->fCorScreening[ekinIndxLow];
102  corToQ1 = data->fCorFirstMoment[ekinIndxLow];
103  corToG2PerG1 = data->fCorSecondMoment[ekinIndxLow];
104  if (remRfaction>0.) {
105  corToScr += remRfaction*(data->fCorScreening[ekinIndxLow+1] - data->fCorScreening[ekinIndxLow]);
106  corToQ1 += remRfaction*(data->fCorFirstMoment[ekinIndxLow+1] - data->fCorFirstMoment[ekinIndxLow]);
107  corToG2PerG1 += remRfaction*(data->fCorSecondMoment[ekinIndxLow+1] - data->fCorSecondMoment[ekinIndxLow]);
108  }
109 }
110 
111 
113  // load PWA correction data for each elements that belongs to materials that are used in the detector
115  // clear PWA correction data per material
117  // initialise PWA correction data for the materials that are used in the detector
119 }
120 
121 
123  // do it only once
124  if (fDataPerElement.size()<gMaxZet+1) {
125  fDataPerElement.resize(gMaxZet+1,nullptr);
126  }
127  // loop over all materials, for those that are used check the list of elements and load data from file if the
128  // corresponding data has not been loaded yet
130  size_t numMatCuts = thePCTable->GetTableSize();
131  for (size_t imc=0; imc<numMatCuts; ++imc) {
132  const G4MaterialCutsCouple *matCut = thePCTable->GetMaterialCutsCouple(imc);
133  if (!matCut->IsUsed()) {
134  continue;
135  }
136  const G4Material *mat = matCut->GetMaterial();
137  const G4ElementVector *elemVect = mat->GetElementVector();
138  //
139  size_t numElems = elemVect->size();
140  for (size_t ielem=0; ielem<numElems; ++ielem) {
141  const G4Element *elem = (*elemVect)[ielem];
142  G4int izet = G4lrint(elem->GetZ());
143  if (izet>gMaxZet) {
144  izet = gMaxZet;
145  }
146  if (!fDataPerElement[izet]) {
147  LoadDataElement(elem);
148  }
149  }
150  }
151 }
152 
153 
155  // prepare size of the container
156  size_t numMaterials = G4Material::GetNumberOfMaterials();
157  if (fDataPerMaterial.size()!=numMaterials) {
158  fDataPerMaterial.resize(numMaterials);
159  }
160  // init. PWA correction data for the Materials that are used in the geometry
162  size_t numMatCuts = thePCTable->GetTableSize();
163  for (size_t imc=0; imc<numMatCuts; ++imc) {
164  const G4MaterialCutsCouple *matCut = thePCTable->GetMaterialCutsCouple(imc);
165  if (!matCut->IsUsed()) {
166  continue;
167  }
168  const G4Material *mat = matCut->GetMaterial();
169  if (!fDataPerMaterial[mat->GetIndex()]) {
170  InitDataMaterial(mat);
171  }
172  }
173 }
174 
175 
176 // it's called only if data has not been loaded for this element yet
178  // allocate memory
179  G4int izet = G4lrint(elem->GetZ());
180  if (izet>gMaxZet) {
181  izet = gMaxZet;
182  }
183  // load data from file
184  char* tmppath = getenv("G4LEDATA");
185  if (!tmppath) {
186  G4Exception("G4GSPWACorrection::LoadDataElement()","em0006",
188  "Environment variable G4LEDATA not defined");
189  return;
190  }
191  std::string path(tmppath);
192  if (fIsElectron) {
193  path += "/msc_GS/PWACor/el/";
194  } else {
195  path += "/msc_GS/PWACor/pos/";
196  }
197  std::string fname = path+"cf_"+gElemSymbols[izet-1];
198  std::ifstream infile(fname,std::ios::in);
199  if (!infile.is_open()) {
200  std::string msg = " Problem while trying to read " + fname + " data file.\n";
201  G4Exception("G4GSPWACorrection::LoadDataElement","em0006", FatalException,msg.c_str());
202  return;
203  }
204  // allocate data structure
205  DataPerMaterial *perElem = new DataPerMaterial();
206  perElem->fCorScreening.resize(gNumEkin,0.0);
207  perElem->fCorFirstMoment.resize(gNumEkin,0.0);
208  perElem->fCorSecondMoment.resize(gNumEkin,0.0);
209  fDataPerElement[izet] = perElem;
210  G4double dum0;
211  for (G4int iek=0; iek<gNumEkin; ++iek) {
212  infile >> dum0;
213  infile >> perElem->fCorScreening[iek];
214  infile >> perElem->fCorFirstMoment[iek];
215  infile >> perElem->fCorSecondMoment[iek];
216  }
217  infile.close();
218 }
219 
220 
222  constexpr G4double const1 = 7821.6; // [cm2/g]
223  constexpr G4double const2 = 0.1569; // [cm2 MeV2 / g]
224  constexpr G4double finstrc2 = 5.325135453E-5; // fine-structure const. square
225 
227  constFactor *= constFactor; // (mc^2)^2\alpha^2/( C_{TF}^2)
228  // allocate memory
229  DataPerMaterial *perMat = new DataPerMaterial();
230  perMat->fCorScreening.resize(gNumEkin,0.0);
231  perMat->fCorFirstMoment.resize(gNumEkin,0.0);
232  perMat->fCorSecondMoment.resize(gNumEkin,0.0);
233  fDataPerMaterial[mat->GetIndex()] = perMat;
234  //
235  const G4ElementVector* elemVect = mat->GetElementVector();
236  const G4int numElems = mat->GetNumberOfElements();
237  const G4double* nbAtomsPerVolVect = mat->GetVecNbOfAtomsPerVolume();
238  G4double totNbAtomsPerVol = mat->GetTotNbOfAtomsPerVolume();
239  //
240  // 1. Compute material dependent part of Moliere's b_c \chi_c^2
241  // (with \xi=1 (i.e. total sub-threshold scattering power correction)
242  G4double moliereBc = 0.0;
243  G4double moliereXc2 = 0.0;
244  G4double zs = 0.0;
245  G4double ze = 0.0;
246  G4double zx = 0.0;
247  G4double sa = 0.0;
248  G4double xi = 1.0;
249  for (G4int ielem=0; ielem<numElems; ++ielem) {
250  G4double zet = (*elemVect)[ielem]->GetZ();
251  if (zet>gMaxZet) {
252  zet = (G4double)gMaxZet;
253  }
254  G4double iwa = (*elemVect)[ielem]->GetN();
255  G4double ipz = nbAtomsPerVolVect[ielem]/totNbAtomsPerVol;
256  G4double dum = ipz*zet*(zet+xi);
257  zs += dum;
258  ze += dum*(-2.0/3.0)*G4Log(zet);
259  zx += dum*G4Log(1.0+3.34*finstrc2*zet*zet);
260  sa += ipz*iwa;
261  }
262  G4double density = mat->GetDensity()*CLHEP::cm3/CLHEP::g; // [g/cm3]
263  //
264  moliereBc = const1*density*zs/sa*G4Exp(ze/zs)/G4Exp(zx/zs); //[1/cm]
265  moliereXc2 = const2*density*zs/sa; // [MeV2/cm]
266  // change to Geant4 internal units of 1/length and energ2/length
267  moliereBc *= 1.0/CLHEP::cm;
268  moliereXc2 *= CLHEP::MeV*CLHEP::MeV/CLHEP::cm;
269  //
270  // 2. loop over the kinetic energy grid
271  for (G4int iek=0; iek<gNumEkin; ++iek) {
272  // 2./a. set current kinetic energy and pt2 value
274  G4double pt2 = ekin*(ekin+2.0*CLHEP::electron_mass_c2);
275  if (ekin>gMidEkin) {
276  G4double b2 = fMinBeta2+(iek-(gNumEkin-gNumBeta2))/fInvDelBeta2;
277  ekin = CLHEP::electron_mass_c2*(1./std::sqrt(1.-b2)-1.);
278  pt2 = ekin*(ekin+2.0*CLHEP::electron_mass_c2);
279  }
280  // 2./b. loop over the elements at the current kinetic energy point
281  for (G4int ielem=0; ielem<numElems; ++ielem) {
282  const G4Element *elem = (*elemVect)[ielem];
283  G4double zet = elem->GetZ();
284  if (zet>gMaxZet) {
285  zet = (G4double)gMaxZet;
286  }
287  G4int izet = G4lrint(zet);
288  // loaded PWA corrections for the current element
289  DataPerMaterial *perElem = fDataPerElement[izet];
290  //
291  // xi should be one i.e. z(z+1) since total sub-threshold scattering power correction
292  G4double nZZPlus1 = nbAtomsPerVolVect[ielem]*zet*(zet+1.0)/totNbAtomsPerVol;
293  G4double Z23 = std::pow(zet,2./3.);
294  //
295  // 2./b./(i) Add the 3 PWA correction factors
296  G4double mcScrCF = perElem->fCorScreening[iek]; // \kappa_i[1.13+3.76(\alpha Z_i)^2] with \kappa_i=scr_mc/scr_sr
297  // compute the screening parameter correction factor (Z_i contribution to the material)
298  // src_{mc} = C \exp\left[ \frac{ \sum_i n_i Z_i(Z_i+1)\ln[Z_{i}^{2/3}\kappa_i(1.13+3.76(\alpha Z_i)^2)] } {\sum_i n_i Z_i(Z_i+1)}
299  // with C = \frac{(mc^2)^\alpha^2} {4(pc)^2 C_{TF}^2} = constFactor/(4*(pc)^2)
300  // here we compute the \sum_i n_i Z_i(Z_i+1)\ln[Z_{i}^{2/3}\kappa_i(1.13+3.76(\alpha Z_i)^2)] part
301  perMat->fCorScreening[iek] += nZZPlus1*G4Log(Z23*mcScrCF);
302  // compute the corrected screening parameter for the current Z_i and E_{kin}
303  // src(Z_i)_{mc} = \frac{(mc^2)^\alpha^2 Z_i^{2/3}} {4(pc)^2 C_{TF}^2} \kappa_i[1.13+3.76(\alpha Z_i)^2]
304  mcScrCF *= constFactor*Z23/(4.*pt2);
305  // compute first moment correction factor
306  // q1_{mc} = \frac{ \sum_i n_i Z_i(Z_i+1) A_i B_i } {\sum_i n_i Z_i(Z_i+1)} \frac{1}{C}
307  // where:
308  // A_i(src(Z_i)_{mc}) = [\ln(1+1/src(Z_i)_{mc}) - 1/(1+src(Z_i)_{mc})]; where \sigma(Z_i)_{tr1}^(sr) = A_i(src(Z_i)_{mc}) [2\pi r_0 Z_i mc^2/(pc)\beta]^2
309  // B_i = \beta_i \gamma_i with beta_i(Z_i) = \sigma(Z_i)_{tr1}^(PWA)/\sigma(Z_i,src(Z_i)_{mc})_{tr1}^(sr)
310  // and \gamma_i = \sigma(Z_i)_{el}^(MC-DCS)/\sigma(Z_i,src(Z_i)_{mc})_{el}^(sr)
311  // C(src_{mc}) = [\ln(1+1/src_{mc}) - 1/(1+src_{mc})]; where \sigma_{tr1}^(sr) = C(src_{mc}) [2\pi r_0 Z_i mc^2/(pc)\beta]^2
312  // A_i x B_i is stored in file per e-/e+, E_{kin} and Z_i
313  // here we compute the \sum_i n_i Z_i(Z_i+1) A_i B_i part
314  perMat->fCorFirstMoment[iek] += nZZPlus1*(G4Log(1.+1./mcScrCF)-1./(1.+mcScrCF))*perElem->fCorFirstMoment[iek];
315  // compute the second moment correction factor
316  // [G2/G1]_{mc} = \frac{ \sum_i n_i Z_i(Z_i+1) A_i } {\sum_i n_i Z_i(Z_i+1)} \frac{1}{C}
317  // with A_i(Z_i) = G2(Z_i)^{PWA}/G1(Z_i)^{PWA} and C=G2(Z_i,scr_{mc})^{sr}/G1(Z_i,scr_{mc})^{sr}}
318  // here we compute the \sum_i n_i Z_i(Z_i+1) A_i part
319  perMat->fCorSecondMoment[iek] += nZZPlus1*perElem->fCorSecondMoment[iek];
320  //
321  // 2./b./(ii) When the last element has been added:
322  if (ielem==numElems-1) {
323  //
324  // 1. the remaining part of the sreening correction and divide the corrected screening par. with Moliere's one:
325  // (Moliere screening parameter = moliereXc2/(4(pc)^2 moliereBc) )
326  G4double dumScr = G4Exp(perMat->fCorScreening[iek]/zs);
327  perMat->fCorScreening[iek] = constFactor*dumScr*moliereBc/moliereXc2;
328  //
329  // 2. the remaining part of the first moment correction and divide by the one computed by using the corrected
330  // screening parameter (= (mc^2)^\alpha^2/(4(pc)^2C_{TF}^2) dumScr
331  G4double scrCorTed = constFactor*dumScr/(4.*pt2);
332  G4double dum0 = G4Log(1.+1./scrCorTed);
333  perMat->fCorFirstMoment[iek] = perMat->fCorFirstMoment[iek]/(zs*(dum0-1./(1.+scrCorTed)));
334  //
335  // 3. the remaining part of the second moment correction and divide by the one computed by using the corrected
336  // screening parameter
337  G4double G2PerG1 = 3.*(1.+scrCorTed)*((1.+2.*scrCorTed)*dum0-2.)/((1.+scrCorTed)*dum0-1.);
338  perMat->fCorSecondMoment[iek] = perMat->fCorSecondMoment[iek]/(zs*G2PerG1);
339  }
340  }
341  }
342 }
343 
344 
345 
347  for (size_t i=0; i<fDataPerElement.size(); ++i) {
348  if (fDataPerElement[i]) {
349  fDataPerElement[i]->fCorScreening.clear();
350  fDataPerElement[i]->fCorFirstMoment.clear();
351  fDataPerElement[i]->fCorSecondMoment.clear();
352  delete fDataPerElement[i];
353  }
354  }
355  fDataPerElement.clear();
356 }
357 
358 
360  for (size_t i=0; i<fDataPerMaterial.size(); ++i) {
361  if (fDataPerMaterial[i]) {
362  fDataPerMaterial[i]->fCorScreening.clear();
363  fDataPerMaterial[i]->fCorFirstMoment.clear();
364  fDataPerMaterial[i]->fCorSecondMoment.clear();
365  delete fDataPerMaterial[i];
366  }
367  }
368  fDataPerMaterial.clear();
369 }
static constexpr G4double gMaxBeta2
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
Definition: G4Exp.hh:183
static size_t GetNumberOfMaterials()
Definition: G4Material.cc:600
static constexpr double cm3
G4GSPWACorrections(G4bool iselectron=true)
static constexpr double g
size_t GetIndex() const
Definition: G4Material.hh:262
const G4ElementVector * GetElementVector() const
Definition: G4Material.hh:191
std::vector< DataPerMaterial * > fDataPerMaterial
static constexpr G4double gMinEkin
const G4double * GetVecNbOfAtomsPerVolume() const
Definition: G4Material.hh:207
void GetPWACorrectionFactors(G4double logekin, G4double beta2, G4int matindx, G4double &corToScr, G4double &corToQ1, G4double &corToG2PerG1)
G4double G4Log(G4double x)
Definition: G4Log.hh:230
static constexpr G4int gMaxZet
const XML_Char const XML_Char * data
Definition: expat.h:268
static constexpr double cm
Definition: SystemOfUnits.h:99
double G4double
Definition: G4Types.hh:76
bool G4bool
Definition: G4Types.hh:79
static constexpr double electron_mass_c2
static constexpr double MeV
Float_t mat
static constexpr G4int gNumBeta2
static constexpr G4int gNumEkin
static G4ProductionCutsTable * GetProductionCutsTable()
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.hh:65
std::vector< G4double > fCorSecondMoment
int G4lrint(double ad)
Definition: templates.hh:151
std::vector< G4Element * > G4ElementVector
int G4int
Definition: G4Types.hh:78
ifstream in
Definition: comparison.C:7
void LoadDataElement(const G4Element *)
static const std::string gElemSymbols[]
std::vector< G4double > fCorFirstMoment
void InitDataMaterial(const G4Material *)
const G4MaterialCutsCouple * GetMaterialCutsCouple(G4int i) const
G4double GetZ() const
Definition: G4Element.hh:131
const G4Material * GetMaterial() const
G4double GetTotNbOfAtomsPerVolume() const
Definition: G4Material.hh:210
static constexpr double fine_structure_const
size_t GetNumberOfElements() const
Definition: G4Material.hh:187
static constexpr G4double gMidEkin
G4double GetDensity() const
Definition: G4Material.hh:181
std::vector< DataPerMaterial * > fDataPerElement