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 (
size_t ix=0;ix<
fNBinsX;ix++)
98 G4Exception(
"G4PenelopeBremsstrahlungFS::ClearTables()",
153 ed <<
"The container for the <Z^2> values is not initialized" <<
G4endl;
154 G4Exception(
"G4PenelopeBremsstrahlungFS::GetEffectiveZSquared()",
164 ed <<
"The value of <Z^2> is not properly set for material " <<
167 G4Exception(
"G4PenelopeBremsstrahlungFS::GetEffectiveZSquared()",
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*>;
208 fReducedXSTable =
new std::map< std::pair<const G4Material*,G4double> ,
216 std::vector<G4double> *StechiometricFactors =
new std::vector<G4double>;
220 for (
G4int 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 (
G4int i=0;i<nElements;i++)
230 if ((*StechiometricFactors)[i] > MaxStechiometricFactor)
231 MaxStechiometricFactor = (*StechiometricFactors)[i];
234 for (
G4int i=0;i<nElements;i++)
235 (*StechiometricFactors)[i] /= MaxStechiometricFactor;
239 for (
G4int i=0;i<nElements;i++)
241 G4double Z = (*elementVector)[i]->GetZ();
242 sumz2 += (*StechiometricFactors)[i]*
Z*
Z;
243 sums += (*StechiometricFactors)[i];
255 for (
G4int iel=0;iel<nElements;iel++)
257 G4double Z = (*elementVector)[iel]->GetZ();
259 G4double wgt = (*StechiometricFactors)[iel]*
Z*
Z/ZBR2;
268 ed <<
"Error in G4PenelopeBremsstrahlungFS::BuildScaledXSTable" <<
G4endl;
269 ed <<
"Unable to retrieve data for element " << iZ <<
G4endl;
270 G4Exception(
"G4PenelopeBremsstrahlungFS::BuildScaledXSTable()",
277 for (
size_t ie=0;ie<
fNBinsE;ie++)
280 for (
size_t ix=0;ix<
fNBinsX;ix++)
281 (*tempMatrix)[ie*
fNBinsX+ix] += wgt*(*atomData)[ie*(
fNBinsX+1)+ix];
289 for (
size_t ie=0;ie<
fNBinsE;ie++)
293 for (
size_t ix=0;ix<
fNBinsX;ix++)
294 tempData2[ix] = (*tempMatrix)[ie*
fNBinsX+ix];
299 G4double fnorm = (*tempData)[ie]/(rsum*fact);
300 G4double TST = 100.*std::fabs(fnorm-1.0);
304 ed <<
"G4PenelopeBremsstrahlungFS. Corrupted data files?" <<
G4endl;
305 G4cout <<
"TST= " << TST <<
"; fnorm = " << fnorm <<
G4endl;
309 G4Exception(
"G4PenelopeBremsstrahlungFS::BuildScaledXSTable()",
312 for (
size_t ix=0;ix<
fNBinsX;ix++)
313 (*tempMatrix)[ie*
fNBinsX+ix] *= fnorm;
330 for (
size_t ix=0;ix<
fNBinsX;ix++)
334 for (
size_t ie=0;ie<
fNBinsE;ie++)
346 G4double val1eV = (*theVec)[1]+derivative*(log1eV-theVec->
Energy(1));
350 std::pair<const G4Material*,G4double> theKey = std::make_pair(
material,cut);
353 delete StechiometricFactors;
368 char* path = std::getenv(
"G4LEDATA");
371 G4String excep =
"G4PenelopeBremsstrahlungFS - G4LEDATA environment variable not set!";
372 G4Exception(
"G4PenelopeBremsstrahlungFS::ReadDataFile()",
379 std::ostringstream ost;
381 ost << path <<
"/penelope/bremsstrahlung/pdebr" <<
Z <<
".p08";
383 ost << path <<
"/penelope/bremsstrahlung/pdebr0" <<
Z <<
".p08";
384 std::ifstream
file(ost.str().c_str());
387 G4String excep =
"G4PenelopeBremsstrahlungFS - data file " +
388 G4String(ost.str()) +
" not found!";
389 G4Exception(
"G4PenelopeBremsstrahlungFS::ReadDataFile()",
401 ed <<
"Corrupted data file for Z=" <<
Z <<
G4endl;
402 G4Exception(
"G4PenelopeBremsstrahlungFS::ReadDataFile()",
409 for (
size_t ie=0;ie<
fNBinsE;ie++)
416 for (
size_t ix=0;ix<
fNBinsX;ix++)
444 size_t size = fNBinsX;
448 if (momOrder<-1 || size<2 || theXGrid[0]<0)
450 G4Exception(
"G4PenelopeBremsstrahlungFS::GetMomentumIntegral()",
454 for (
size_t i=1;i<size;i++)
456 if (theXGrid[i]<0 || theXGrid[i]<theXGrid[i-1])
459 ed <<
"Invalid call for bin " << i <<
G4endl;
460 G4Exception(
"G4PenelopeBremsstrahlungFS::GetMomentumIntegral()",
467 if (xup < theXGrid[0])
472 for (
size_t i=0;i<size-1;i++)
488 if (std::fabs(dx)>1e-14*std::fabs(dy))
493 ds = a*
G4Log(xtc/x1)+b*(xtc-x1);
494 else if (momOrder == 0)
495 ds = a*(xtc-x1) + 0.5*b*(xtc*xtc-x1*x1);
497 ds = a*(std::pow(xtc,momOrder+1)-std::pow(x1,momOrder+1))/((
G4double) (momOrder + 1))
498 + b*(std::pow(xtc,momOrder+2)-std::pow(x1,momOrder+2))/((
G4double) (momOrder + 2));
501 ds = 0.5*(y1+y2)*(xtc-x1)*std::pow(xtc,momOrder);
515 std::pair<const G4Material*,G4double> theKey = std::make_pair(mat,cut);
519 G4Exception(
"G4PenelopeBremsstrahlungFS::GetScaledXSTable()",
520 "em2013",
FatalException,
"Unable to retrieve the cross section table");
532 G4cout <<
"Entering in G4PenelopeBremsstrahlungFS::InitializeEnergySampling() for " <<
536 std::pair<const G4Material*,G4double> theKey = std::make_pair(
material,cut);
550 G4Exception(
"G4PenelopeBremsstrahlungFS::InitializeEnergySampling()",
551 "em2013",
FatalException,
"Unable to retrieve the cross section table");
554 for (
size_t ie=0;ie<
fNBinsE;ie++)
561 for (
size_t ix=1;ix<
fNBinsX;ix++)
584 for (
size_t ix=0;ix<
fNBinsX;ix++)
587 tempData[ix] =
G4Exp((*vv)[ie+1]);
597 fPBcut->insert(std::make_pair(theKey,thePBvec));
606 std::pair<const G4Material*,G4double> theKey = std::make_pair(mat,cut);
610 ed <<
"Unable to retrieve the SamplingTable: " <<
613 G4Exception(
"G4PenelopeBremsstrahlungFS::SampleGammaEnergy()",
621 G4bool firstOrLastBin =
false;
626 firstOrLastBin =
true;
631 firstOrLastBin =
true;
664 G4cout <<
"Creating new instance of G4PhysicsFreeVector() on the worker" <<
G4endl;
672 for (
size_t iloop=0;iloop<
fNBinsX;iloop++)
674 G4double val = (*theVec1)[iloop]+(((*theVec2)[iloop]-(*theVec1)[iloop]))*
681 for (
size_t iloop=0;iloop<
fNBinsX;iloop++)
690 pbcut = (*(
fPBcut->find(theKey)->second))[eBin] +
691 ((*(
fPBcut->find(theKey)->second))[eBin+1]-(*(
fPBcut->find(theKey)->second))[eBin])*
698 G4int nIterations = 0;
706 if (pt < (*theTempVec)[0])
708 else if (pt > (*theTempVec)[
fNBinsX-1])
713 if (delta < pt*1e-10)
717 ed <<
"Found that (pt > (*theTempVec)[fNBinsX-1]) with pt = " << pt <<
718 " , (*theTempVec)[fNBinsX-1] = " << (*theTempVec)[
fNBinsX-1] <<
" and delta = " <<
720 ed <<
"Possible symptom of problem with numerical precision" <<
G4endl;
721 G4Exception(
"G4PenelopeBremsstrahlungFS::SampleGammaEnergy()",
727 ed <<
"Crash at (pt > (*theTempVec)[fNBinsX-1]) with pt = " << pt <<
728 " , (*theTempVec)[fNBinsX-1]=" << (*theTempVec)[
fNBinsX-1] <<
" and fNBinsX = " <<
730 ed <<
"Material: " << mat->
GetName() <<
", energy = " <<
energy/
keV <<
" keV" <<
732 G4Exception(
"G4PenelopeBremsstrahlungFS::SampleGammaEnergy()",
743 if (pt > (*theTempVec)[k])
781 ed <<
"Warning in G4PenelopeBremsstrahlungFS::SampleX()" <<
G4endl;
782 ed <<
"Conflicting end-point values: w1=" << w1 <<
"; w2 = " << w2 <<
G4endl;
783 ed <<
"wbcut = " << wbcut <<
" energy= " <<
energy/
keV <<
" keV" <<
G4endl;
784 ed <<
"cut = " << cut/
keV <<
" keV" <<
G4endl;
785 G4Exception(
"G4PenelopeBremsstrahlungFS::SampleGammaEnergy()",
"em2015",
801 if (nIterations > 100)
803 }
while(eGamma < cut);
G4double B(G4double temperature)
static const G4double eps
std::vector< const G4Element * > G4ElementVector
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
G4double G4Log(G4double x)
static constexpr double mole
static constexpr double barn
static constexpr double millibarn
static constexpr double keV
static constexpr double eV
static constexpr double g
G4GLOB_DLL std::ostream G4cout
void Put(const value_type &val) const
const G4String & GetName() const
void BuildScaledXSTable(const G4Material *material, G4double cut, G4bool isMaster)
std::map< const G4Material *, G4double > * fEffectiveZSq
std::map< G4int, G4DataVector * > * fElementData
static const size_t fNBinsE
G4double GetEffectiveZSquared(const G4Material *mat) const
const G4PhysicsTable * GetScaledXSTable(const G4Material *, const G4double cut) const
std::map< std::pair< const G4Material *, G4double >, G4PhysicsTable * > * fSamplingTable
void ClearTables(G4bool isMaster=true)
Reserved for the master model: they build and handle tables.
void ReadDataFile(G4int Z)
G4double SampleGammaEnergy(G4double energy, const G4Material *, const G4double cut) const
std::map< std::pair< const G4Material *, G4double >, G4PhysicsFreeVector * > * fPBcut
~G4PenelopeBremsstrahlungFS()
void InitializeEnergySampling(const G4Material *, G4double cut)
G4double GetMomentumIntegral(G4double *y, G4double up, G4int momOrder) const
G4PenelopeBremsstrahlungFS(G4int verbosity=0)
Only master models are supposed to create instances.
std::map< std::pair< const G4Material *, G4double >, G4PhysicsTable * > * fReducedXSTable
G4double theEGrid[fNBinsE]
G4double theXGrid[fNBinsX]
static const size_t fNBinsX
G4Cache< G4PhysicsFreeVector * > fCache
void PutValues(const std::size_t index, const G4double energy, const G4double value)
void push_back(G4PhysicsVector *)
G4double Energy(const std::size_t index) const
G4double energy(const ThreeVector &p, const G4double m)
T max(const T t1, const T t2)
brief Return the largest of the two arguments
T min(const T t1, const T t2)
brief Return the smallest of the two arguments
int classic_electr_radius