63const std::string G4GSMottCorrection::gElemSymbols[] = {
"H",
"He",
"Li",
"Be",
"B" ,
64 "C" ,
"N" ,
"O" ,
"F" ,
"Ne",
"Na",
"Mg",
"Al",
"Si",
"P" ,
"S",
"Cl",
"Ar",
"K" ,
"Ca",
"Sc",
65 "Ti",
"V" ,
"Cr",
"Mn",
"Fe",
"Co",
"Ni",
"Cu",
"Zn",
"Ga",
"Ge",
"As",
"Se",
"Br",
"Kr",
"Rb",
66 "Sr",
"Y" ,
"Zr",
"Nb",
"Mo",
"Tc",
"Ru",
"Rh",
"Pd",
"Ag",
"Cd",
"In",
"Sn",
"Sb",
"Te",
"I" ,
67 "Xe",
"Cs",
"Ba",
"La",
"Ce",
"Pr",
"Nd",
"Pm",
"Sm",
"Eu",
"Gd",
"Tb",
"Dy",
"Ho",
"Er",
"Tm",
68 "Yb",
"Lu",
"Hf",
"Ta",
"W" ,
"Re",
"Os",
"Ir",
"Pt",
"Au",
"Hg",
"Tl",
"Pb",
"Bi",
"Po",
"At",
69 "Rn",
"Fr",
"Ra",
"Ac",
"Th",
"Pa",
"U" ,
"Np",
"Pu",
"Am",
"Cm",
"Bk",
"Cf"};
73 fMaxEkin = CLHEP::electron_mass_c2*(1./std::sqrt(1.-gMaxBeta2)-1.);
74 fLogMinEkin =
G4Log(gMinEkin);
75 fInvLogDelEkin = (gNumEkin-gNumBeta2)/
G4Log(gMidEkin/gMinEkin);
76 G4double pt2 = gMidEkin*(gMidEkin+2.0*CLHEP::electron_mass_c2);
77 fMinBeta2 = pt2/(pt2+CLHEP::electron_mass_c2*CLHEP::electron_mass_c2);
78 fInvDelBeta2 = (gNumBeta2-1.)/(gMaxBeta2-fMinBeta2);
79 fInvDelDelta = (gNumDelta-1.)/gMaxDelta;
80 fInvDelAngle = gNumAngle-1.;
85 ClearMCDataPerElement();
86 ClearMCDataPerMaterial();
92 G4int ekinIndxLow = 0;
94 if (beta2>=gMaxBeta2) {
95 ekinIndxLow = gNumEkin - 1;
97 }
else if (beta2>=fMinBeta2) {
98 remRfaction = (beta2 - fMinBeta2) * fInvDelBeta2;
99 ekinIndxLow = (
G4int)remRfaction;
100 remRfaction -= ekinIndxLow;
101 ekinIndxLow += (gNumEkin - gNumBeta2);
102 }
else if (logekin>=fLogMinEkin) {
103 remRfaction = (logekin - fLogMinEkin) * fInvLogDelEkin;
104 ekinIndxLow = (
G4int)remRfaction;
105 remRfaction -= ekinIndxLow;
108 DataPerEkin *perEkinLow = fMCDataPerMaterial[matindx]->fDataPerEkin[ekinIndxLow];
109 mcToScr = perEkinLow->fMCScreening;
110 mcToQ1 = perEkinLow->fMCFirstMoment;
111 mcToG2PerG1 = perEkinLow->fMCSecondMoment;
112 if (remRfaction>0.) {
113 DataPerEkin *perEkinHigh = fMCDataPerMaterial[matindx]->fDataPerEkin[ekinIndxLow+1];
114 mcToScr += remRfaction*(perEkinHigh->fMCScreening - perEkinLow->fMCScreening);
115 mcToQ1 += remRfaction*(perEkinHigh->fMCFirstMoment - perEkinLow->fMCFirstMoment);
116 mcToG2PerG1 += remRfaction*(perEkinHigh->fMCSecondMoment - perEkinLow->fMCSecondMoment);
127 if (delta>=gMaxDelta) {
133 G4int ekinIndxLow = 0;
135 if (beta2>gMaxBeta2) {
136 ekinIndxLow = gNumEkin - 1;
138 }
else if (beta2>=fMinBeta2) {
139 probIndxHigh = (beta2 - fMinBeta2) * fInvDelBeta2;
140 ekinIndxLow = (
G4int)probIndxHigh;
141 probIndxHigh -= ekinIndxLow;
142 ekinIndxLow += (gNumEkin - gNumBeta2);
143 }
else if (logekin>fLogMinEkin) {
144 probIndxHigh = (logekin - fLogMinEkin) * fInvLogDelEkin;
145 ekinIndxLow = (
G4int)probIndxHigh;
146 probIndxHigh -= ekinIndxLow;
154 ekindx = ekinIndxLow;
160 G4double probIndxHigh = delta*fInvDelDelta;
162 probIndxHigh -= deltIndxLow;
168 deltindx = deltIndxLow;
172 DataPerDelta *perDelta = fMCDataPerMaterial[matindx]->fDataPerEkin[ekindx]->fDataPerDelta[deltindx];
175 G4double ang = std::sqrt(0.5*(1.-cost));
176 G4double remRfaction = ang*fInvDelAngle;
178 remRfaction -= angIndx;
179 if (angIndx<gNumAngle-2) {
180 val = remRfaction*(perDelta->fRejFuntion[angIndx+1]-perDelta->fRejFuntion[angIndx]) + perDelta->fRejFuntion[angIndx];
182 G4double dum = ang-1.+1./fInvDelAngle;
183 val = perDelta->fSA + dum*(perDelta->fSB + dum*(perDelta->fSC + dum*perDelta->fSD));
191 InitMCDataPerElement();
193 ClearMCDataPerMaterial();
195 InitMCDataPerMaterials();
199void G4GSMottCorrection::InitMCDataPerElement() {
201 if (fMCDataPerElement.size()<gMaxZet+1) {
202 fMCDataPerElement.resize(gMaxZet+1,
nullptr);
208 for (
size_t imc=0; imc<numMatCuts; ++imc) {
216 size_t numElems = elemVect->size();
217 for (
size_t ielem=0; ielem<numElems; ++ielem) {
218 const G4Element *elem = (*elemVect)[ielem];
223 if (!fMCDataPerElement[izet]) {
224 LoadMCDataElement(elem);
231void G4GSMottCorrection::InitMCDataPerMaterials() {
234 if (fMCDataPerMaterial.size()!=numMaterials) {
235 fMCDataPerMaterial.resize(numMaterials);
240 for (
size_t imc=0; imc<numMatCuts; ++imc) {
246 if (!fMCDataPerMaterial[mat->
GetIndex()]) {
247 InitMCDataMaterial(mat);
254void G4GSMottCorrection::LoadMCDataElement(
const G4Element *elem) {
260 DataPerMaterial *perElem =
new DataPerMaterial();
261 AllocateDataPerMaterial(perElem);
262 fMCDataPerElement[izet] = perElem;
265 char* tmppath = std::getenv(
"G4LEDATA");
267 G4Exception(
"G4GSMottCorrection::LoadMCDataElement()",
"em0006",
269 "Environment variable G4LEDATA not defined");
272 std::string path(tmppath);
274 path +=
"/msc_GS/MottCor/el/";
276 path +=
"/msc_GS/MottCor/pos/";
278 std::string fname = path+
"rej_"+gElemSymbols[izet-1];
279 std::istringstream infile(std::ios::in);
280 ReadCompressedFile(fname, infile);
282 for (
G4int iek=0; iek<gNumEkin; ++iek) {
283 DataPerEkin *perEkin = perElem->fDataPerEkin[iek];
285 infile >> perEkin->fMCScreening;
286 infile >> perEkin->fMCFirstMoment;
287 infile >> perEkin->fMCSecondMoment;
289 for (
G4int idel=0; idel<gNumDelta; ++idel) {
290 DataPerDelta *perDelta = perEkin->fDataPerDelta[idel];
292 for (
G4int iang=0; iang<gNumAngle; ++iang) {
293 infile >> perDelta->fRejFuntion[iang];
296 infile >> perDelta->fSA;
297 infile >> perDelta->fSB;
298 infile >> perDelta->fSC;
299 infile >> perDelta->fSD;
305void G4GSMottCorrection::ReadCompressedFile(std::string fname, std::istringstream &iss) {
306 std::string *dataString =
nullptr;
307 std::string compfilename(fname+
".z");
309 std::ifstream in(compfilename, std::ios::binary | std::ios::ate);
312 int fileSize = in.tellg();
314 in.seekg(0,std::ios::beg);
316 Bytef *compdata =
new Bytef[fileSize];
318 in.read((
char*)compdata, fileSize);
321 uLongf complen = (uLongf)(fileSize*4);
322 Bytef *uncompdata =
new Bytef[complen];
323 while (
Z_OK!=
uncompress(uncompdata, &complen, compdata, fileSize)) {
327 uncompdata =
new Bytef[complen];
332 dataString =
new std::string((
char*)uncompdata, (
long)complen);
334 delete [] uncompdata;
336 std::string msg =
" Problem while trying to read " + compfilename +
" data file.\n";
342 iss.str(*dataString);
349void G4GSMottCorrection::InitMCDataMaterial(
const G4Material *mat) {
352 constexpr G4double finstrc2 = 5.325135453E-5;
354 G4double constFactor = CLHEP::electron_mass_c2*CLHEP::fine_structure_const/0.88534;
355 constFactor *= constFactor;
357 DataPerMaterial *perMat =
new DataPerMaterial();
358 AllocateDataPerMaterial(perMat);
359 fMCDataPerMaterial[mat->
GetIndex()] = perMat;
375 for (
G4int ielem=0; ielem<numElems; ++ielem) {
376 G4double zet = (*elemVect)[ielem]->GetZ();
380 G4double iwa = (*elemVect)[ielem]->GetN();
381 G4double ipz = nbAtomsPerVolVect[ielem]/totNbAtomsPerVol;
384 ze += dum*(-2.0/3.0)*
G4Log(zet);
385 zx += dum*
G4Log(1.0+3.34*finstrc2*zet*zet);
390 moliereBc = const1*density*zs/sa*
G4Exp(ze/zs)/
G4Exp(zx/zs);
391 moliereXc2 = const2*density*zs/sa;
393 moliereBc *= 1.0/CLHEP::cm;
394 moliereXc2 *= CLHEP::MeV*CLHEP::MeV/CLHEP::cm;
397 for (
G4int iek=0; iek<gNumEkin; ++iek) {
400 G4double pt2 = ekin*(ekin+2.0*CLHEP::electron_mass_c2);
402 G4double b2 = fMinBeta2+(iek-(gNumEkin-gNumBeta2))/fInvDelBeta2;
403 ekin = CLHEP::electron_mass_c2*(1./std::sqrt(1.-b2)-1.);
404 pt2 = ekin*(ekin+2.0*CLHEP::electron_mass_c2);
407 for (
G4int ielem=0; ielem<numElems; ++ielem) {
408 const G4Element *elem = (*elemVect)[ielem];
415 G4double nZZPlus1 = nbAtomsPerVolVect[ielem]*zet*(zet+1.0)/totNbAtomsPerVol;
418 DataPerEkin *perElemPerEkin = fMCDataPerElement[izet]->fDataPerEkin[iek];
419 DataPerEkin *perMatPerEkin = perMat->fDataPerEkin[iek];
422 G4double mcScrCF = perElemPerEkin->fMCScreening;
427 perMatPerEkin->fMCScreening += nZZPlus1*
G4Log(Z23*mcScrCF);
430 mcScrCF *= constFactor*Z23/(4.*pt2);
440 perMatPerEkin->fMCFirstMoment += nZZPlus1*(
G4Log(1.+1./mcScrCF)-1./(1.+mcScrCF))*perElemPerEkin->fMCFirstMoment;
445 perMatPerEkin->fMCSecondMoment += nZZPlus1*perElemPerEkin->fMCSecondMoment;
449 for (
G4int idel=0; idel<gNumDelta; ++idel) {
450 DataPerDelta *perMatPerDelta = perMatPerEkin->fDataPerDelta[idel];
451 DataPerDelta *perElemPerDelta = perElemPerEkin->fDataPerDelta[idel];
453 for (
G4int iang=0; iang<gNumAngle; ++iang) {
454 perMatPerDelta->fRejFuntion[iang] += nZZPlus1*perElemPerDelta->fRejFuntion[iang];
457 perMatPerDelta->fSA += nZZPlus1*perElemPerDelta->fSA;
458 perMatPerDelta->fSB += nZZPlus1*perElemPerDelta->fSB;
459 perMatPerDelta->fSC += nZZPlus1*perElemPerDelta->fSC;
460 perMatPerDelta->fSD += nZZPlus1*perElemPerDelta->fSD;
464 if (ielem==numElems-1) {
469 perMatPerEkin->fMCScreening = constFactor*dumScr*moliereBc/moliereXc2;
473 G4double scrCorTed = constFactor*dumScr/(4.*pt2);
475 perMatPerEkin->fMCFirstMoment = perMatPerEkin->fMCFirstMoment/(zs*(dum0-1./(1.+scrCorTed)));
479 G4double G2PerG1 = 3.*(1.+scrCorTed)*((1.+2.*scrCorTed)*dum0-2.)/((1.+scrCorTed)*dum0-1.);
480 perMatPerEkin->fMCSecondMoment = perMatPerEkin->fMCSecondMoment/(zs*G2PerG1);
484 for (
G4int idel=0; idel<gNumDelta; ++idel) {
485 DataPerDelta *perMatPerDelta = perMatPerEkin->fDataPerDelta[idel];
488 for (
G4int iang=0; iang<gNumAngle; ++iang) {
489 if (perMatPerDelta->fRejFuntion[iang]>maxVal)
490 maxVal = perMatPerDelta->fRejFuntion[iang];
492 for (
G4int iang=0; iang<gNumAngle; ++iang) {
493 perMatPerDelta->fRejFuntion[iang] /=maxVal;
495 perMatPerDelta->fSA /= maxVal;
496 perMatPerDelta->fSB /= maxVal;
497 perMatPerDelta->fSC /= maxVal;
498 perMatPerDelta->fSD /= maxVal;
506void G4GSMottCorrection::AllocateDataPerMaterial(DataPerMaterial *data) {
507 data->fDataPerEkin =
new DataPerEkin*[gNumEkin]();
508 for (
G4int iek=0; iek<gNumEkin; ++iek) {
509 DataPerEkin *perEkin =
new DataPerEkin();
510 perEkin->fDataPerDelta =
new DataPerDelta*[gNumDelta]();
511 for (
G4int idel=0; idel<gNumDelta; ++idel) {
512 DataPerDelta *perDelta =
new DataPerDelta();
513 perDelta->fRejFuntion =
new double[gNumAngle]();
514 perEkin->fDataPerDelta[idel] = perDelta;
516 data->fDataPerEkin[iek] = perEkin;
520void G4GSMottCorrection::DeAllocateDataPerMaterial(DataPerMaterial *data) {
521 for (
G4int iek=0; iek<gNumEkin; ++iek) {
522 DataPerEkin *perEkin = data->fDataPerEkin[iek];
523 for (
G4int idel=0; idel<gNumDelta; ++idel) {
524 DataPerDelta *perDelta = perEkin->fDataPerDelta[idel];
525 delete [] perDelta->fRejFuntion;
528 delete [] perEkin->fDataPerDelta;
531 delete [] data->fDataPerEkin;
535void G4GSMottCorrection::ClearMCDataPerElement() {
536 for (
size_t i=0; i<fMCDataPerElement.size(); ++i) {
537 if (fMCDataPerElement[i]) {
538 DeAllocateDataPerMaterial(fMCDataPerElement[i]);
539 delete fMCDataPerElement[i];
542 fMCDataPerElement.clear();
545void G4GSMottCorrection::ClearMCDataPerMaterial() {
546 for (
size_t i=0; i<fMCDataPerMaterial.size(); ++i) {
547 if (fMCDataPerMaterial[i]) {
548 DeAllocateDataPerMaterial(fMCDataPerMaterial[i]);
549 delete fMCDataPerMaterial[i];
552 fMCDataPerMaterial.clear();
std::vector< G4Element * > G4ElementVector
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
G4double G4Log(G4double x)
G4GSMottCorrection(G4bool iselectron=true)
void GetMottCorrectionFactors(G4double logekin, G4double beta2, G4int matindx, G4double &mcToScr, G4double &mcToQ1, G4double &mcToG2PerG1)
G4double GetMottRejectionValue(G4double logekin, G4double G4beta2, G4double q1, G4double cost, G4int matindx, G4int &ekindx, G4int &deltindx)
const G4Material * GetMaterial() const
G4double GetDensity() const
const G4ElementVector * GetElementVector() const
G4double GetTotNbOfAtomsPerVolume() const
static size_t GetNumberOfMaterials()
size_t GetNumberOfElements() const
const G4double * GetVecNbOfAtomsPerVolume() const
const G4MaterialCutsCouple * GetMaterialCutsCouple(G4int i) const
std::size_t GetTableSize() const
static G4ProductionCutsTable * GetProductionCutsTable()
int ZEXPORT uncompress(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen)