53 fReducedXSTable(nullptr),fEffectiveZSq(nullptr),fSamplingTable(nullptr),
54 fPBcut(nullptr),fVerbosity(verbosity)
58 {1.0e-12,0.025e0,0.05e0,0.075e0,0.1e0,0.15e0,0.2e0,0.25e0,
59 0.3e0,0.35e0,0.4e0,0.45e0,0.5e0,0.55e0,0.6e0,0.65e0,0.7e0,
60 0.75e0,0.8e0,0.85e0,0.9e0,0.925e0,0.95e0,0.97e0,0.99e0,
61 0.995e0,0.999e0,0.9995e0,0.9999e0,0.99995e0,0.99999e0,1.0e0};
63 for (std::size_t ix=0;ix<fNBinsX;++ix)
64 theXGrid[ix] = tempvector[ix];
66 for (std::size_t i=0;i<fNBinsE;++i)
69 fElementData =
new std::map<G4int,G4DataVector*>;
187 G4Exception(
"G4PenelopeBremsstrahlungFS::BuildScaledXSTable()",
192 G4cout <<
"Entering in G4PenelopeBremsstrahlungFS::BuildScaledXSTable for " <<
194 G4cout <<
"Threshold = " << cut/keV <<
" keV, isMaster= " << isMaster <<
201 new std::map< std::pair<const G4Material*,G4double> ,
G4PhysicsTable*>;
207 if (!fReducedXSTable)
208 fReducedXSTable =
new std::map< std::pair<const G4Material*,G4double> ,
211 fEffectiveZSq =
new std::map<const G4Material*,G4double>;
216 std::vector<G4double> *StechiometricFactors =
new std::vector<G4double>;
220 for (std::size_t i=0;i<nElements;i++)
222 G4double fraction = fractionVector[i];
223 G4double atomicWeigth = (*elementVector)[i]->GetA()/(g/mole);
224 StechiometricFactors->push_back(fraction/atomicWeigth);
227 G4double MaxStechiometricFactor = 0.;
228 for (std::size_t i=0;i<nElements;i++)
230 if ((*StechiometricFactors)[i] > MaxStechiometricFactor)
231 MaxStechiometricFactor = (*StechiometricFactors)[i];
234 for (std::size_t i=0;i<nElements;i++)
235 if (MaxStechiometricFactor > 0.)
236 (*StechiometricFactors)[i] /= MaxStechiometricFactor;
240 for (std::size_t i=0;i<nElements;i++)
242 G4double Z = (*elementVector)[i]->GetZ();
243 sumz2 += (*StechiometricFactors)[i]*Z*Z;
244 sums += (*StechiometricFactors)[i];
248 fEffectiveZSq->insert(std::make_pair(material,ZBR2));
256 for (std::size_t iel=0;iel<nElements;iel++)
258 G4double Z = (*elementVector)[iel]->GetZ();
260 G4double wgt = (*StechiometricFactors)[iel]*Z*Z/ZBR2;
263 if (!fElementData->count(iZ))
266 if (!fElementData->count(iZ))
269 ed <<
"Error in G4PenelopeBremsstrahlungFS::BuildScaledXSTable" <<
G4endl;
270 ed <<
"Unable to retrieve data for element " << iZ <<
G4endl;
271 G4Exception(
"G4PenelopeBremsstrahlungFS::BuildScaledXSTable()",
276 G4DataVector* atomData = fElementData->find(iZ)->second;
278 for (std::size_t ie=0;ie<fNBinsE;++ie)
280 (*tempData)[ie] += wgt*(*atomData)[ie*(fNBinsX+1)+fNBinsX];
281 for (std::size_t ix=0;ix<fNBinsX;++ix)
282 (*tempMatrix)[ie*fNBinsX+ix] += wgt*(*atomData)[ie*(fNBinsX+1)+ix];
290 for (std::size_t ie=0;ie<fNBinsE;++ie)
294 for (std::size_t ix=0;ix<fNBinsX;++ix)
295 tempData2[ix] = (*tempMatrix)[ie*fNBinsX+ix];
298 G4double fact = millibarn*(theEGrid[ie]+electron_mass_c2)*(1./fine_structure_const)/
299 (classic_electr_radius*classic_electr_radius*(theEGrid[ie]+2.0*electron_mass_c2));
300 G4double fnorm = (*tempData)[ie]/(rsum*fact);
301 G4double TST = 100.*std::fabs(fnorm-1.0);
305 ed <<
"G4PenelopeBremsstrahlungFS. Corrupted data files?" <<
G4endl;
306 G4cout <<
"TST= " << TST <<
"; fnorm = " << fnorm <<
G4endl;
309 G4cout << ie <<
" " << theEGrid[ie]/keV <<
" " << (*tempData)[ie]/barn <<
G4endl;
310 G4Exception(
"G4PenelopeBremsstrahlungFS::BuildScaledXSTable()",
313 for (std::size_t ix=0;ix<fNBinsX;++ix)
314 (*tempMatrix)[ie*fNBinsX+ix] *= fnorm;
328 for (std::size_t i=0;i<fNBinsX;++i)
331 for (std::size_t ix=0;ix<fNBinsX;++ix)
335 for (std::size_t ie=0;ie<fNBinsE;++ie)
338 G4double aValue = (*tempMatrix)[ie*fNBinsX+ix];
339 if (aValue < 1e-20*millibarn)
340 aValue = 1e-20*millibarn;
347 G4double val1eV = (*theVec)[1]+derivative*(log1eV-theVec->
Energy(1));
351 std::pair<const G4Material*,G4double> theKey = std::make_pair(material,cut);
352 fReducedXSTable->insert(std::make_pair(theKey,thePhysicsTable));
354 delete StechiometricFactors;
359 if (!(fSamplingTable->count(theKey)))
360 InitializeEnergySampling(material,cut);
445 std::size_t size = fNBinsX;
449 if (momOrder<-1 || size<2 || theXGrid[0]<0)
451 G4Exception(
"G4PenelopeBremsstrahlungFS::GetMomentumIntegral()",
455 for (std::size_t i=1;i<size;++i)
457 if (theXGrid[i]<0 || theXGrid[i]<theXGrid[i-1])
460 ed <<
"Invalid call for bin " << i <<
G4endl;
461 G4Exception(
"G4PenelopeBremsstrahlungFS::GetMomentumIntegral()",
468 if (xup < theXGrid[0])
471 G4double xt = std::min(xup,theXGrid[size-1]);
473 for (std::size_t i=0;i<size-1;++i)
475 G4double x1 = std::max(theXGrid[i],eps);
477 G4double x2 = std::max(theXGrid[i+1],eps);
489 if (std::fabs(dx)>1e-14*std::fabs(dy))
494 ds = a*
G4Log(xtc/x1)+b*(xtc-x1);
495 else if (momOrder == 0)
496 ds = a*(xtc-x1) + 0.5*b*(xtc*xtc-x1*x1);
498 ds = a*(std::pow(xtc,momOrder+1)-std::pow(x1,momOrder+1))/((
G4double) (momOrder + 1))
499 + b*(std::pow(xtc,momOrder+2)-std::pow(x1,momOrder+2))/((
G4double) (momOrder + 2));
502 ds = 0.5*(y1+y2)*(xtc-x1)*std::pow(xtc,momOrder);
607 std::pair<const G4Material*,G4double> theKey = std::make_pair(mat,cut);
608 if (!(fSamplingTable->count(theKey)) || !(fPBcut->count(theKey)) ||
609 !(fReducedXSTable->count(theKey)))
612 ed <<
"Unable to retrieve the SamplingTable for " << mat->
GetName() <<
G4endl;
613 G4Exception(
"G4PenelopeBremsstrahlungFS::SampleGammaEnergy()",
617 const G4PhysicsTable* theTableInte = fSamplingTable->find(theKey)->second;
618 const G4PhysicsTable* theTableRed = fReducedXSTable->find(theKey)->second;
621 std::size_t eBin = 0;
622 G4bool firstOrLastBin =
false;
624 if (energy < theEGrid[0])
627 firstOrLastBin =
true;
629 else if (energy > theEGrid[fNBinsE-1])
632 firstOrLastBin =
true;
637 std::size_t j=fNBinsE-1;
640 std::size_t k = (i+j)/2;
641 if (energy > theEGrid[k])
661 fCache.Put(theTempVec);
665 G4cout <<
"Creating new instance of G4PhysicsFreeVector() on the worker" <<
G4endl;
673 for (std::size_t iloop=0;iloop<fNBinsX;++iloop)
675 G4double val = (*theVec1)[iloop]+(((*theVec2)[iloop]-(*theVec1)[iloop]))*
676 (energy-theEGrid[eBin])/(theEGrid[eBin+1]-theEGrid[eBin]);
677 theTempVec->
PutValues(iloop,theXGrid[iloop],val);
682 for (std::size_t iloop=0;iloop<fNBinsX;++iloop)
683 theTempVec->
PutValues(iloop,theXGrid[iloop],(*theVec1)[iloop]);
687 G4double pbcut = (*(fPBcut->find(theKey)->second))[eBin];
691 pbcut = (*(fPBcut->find(theKey)->second))[eBin] +
692 ((*(fPBcut->find(theKey)->second))[eBin+1]-(*(fPBcut->find(theKey)->second))[eBin])*
693 (energy-theEGrid[eBin])/(theEGrid[eBin+1]-theEGrid[eBin]);
696 G4double pCumulative = (*theTempVec)[fNBinsX-1];
699 G4int nIterations = 0;
706 std::size_t ibin = 0;
707 if (pt < (*theTempVec)[0])
709 else if (pt > (*theTempVec)[fNBinsX-1])
713 G4double delta = pt-(*theTempVec)[fNBinsX-1];
714 if (delta < pt*1e-10)
718 ed <<
"Found that (pt > (*theTempVec)[fNBinsX-1]) with pt = " << pt <<
719 " , (*theTempVec)[fNBinsX-1] = " << (*theTempVec)[fNBinsX-1] <<
" and delta = " <<
720 (pt-(*theTempVec)[fNBinsX-1]) <<
G4endl;
721 ed <<
"Possible symptom of problem with numerical precision" <<
G4endl;
722 G4Exception(
"G4PenelopeBremsstrahlungFS::SampleGammaEnergy()",
728 ed <<
"Crash at (pt > (*theTempVec)[fNBinsX-1]) with pt = " << pt <<
729 " , (*theTempVec)[fNBinsX-1]=" << (*theTempVec)[fNBinsX-1] <<
" and fNBinsX = " <<
731 ed <<
"Material: " << mat->
GetName() <<
", energy = " << energy/keV <<
" keV" <<
733 G4Exception(
"G4PenelopeBremsstrahlungFS::SampleGammaEnergy()",
740 std::size_t j=fNBinsX-1;
743 std::size_t k = (i+j)/2;
744 if (pt > (*theTempVec)[k])
767 G4double wbcut = (cut < energy) ? cut/energy : 1.0;
769 wbcut = (cut < theEGrid[eBin]) ? cut/theEGrid[eBin] : 1.0;
782 ed <<
"Warning in G4PenelopeBremsstrahlungFS::SampleX()" <<
G4endl;
783 ed <<
"Conflicting end-point values: w1=" << w1 <<
"; w2 = " << w2 <<
G4endl;
784 ed <<
"wbcut = " << wbcut <<
" energy= " << energy/keV <<
" keV" <<
G4endl;
785 ed <<
"cut = " << cut/keV <<
" keV" <<
G4endl;
786 G4Exception(
"G4PenelopeBremsstrahlungFS::SampleGammaEnergy()",
"em2015",
802 if (nIterations > 100)
804 }
while(eGamma < cut);