78const G4int G4eBremsstrahlungRelModel::gMaxZet = 120;
82 = 16. * CLHEP::fine_structure_const * CLHEP::classic_electr_radius
83 * CLHEP::classic_electr_radius/3.;
87 = 4. * CLHEP::pi * CLHEP::classic_electr_radius
88 * CLHEP::electron_Compton_length * CLHEP::electron_Compton_length;
91const G4double G4eBremsstrahlungRelModel::gLPMconstant
92 = CLHEP::fine_structure_const * CLHEP::electron_mass_c2
93 * CLHEP::electron_mass_c2 / (4. * CLHEP::pi * CLHEP::hbarc);
97const G4double G4eBremsstrahlungRelModel::gXGL[] = {
98 1.98550718e-02, 1.01666761e-01, 2.37233795e-01, 4.08282679e-01,
99 5.91717321e-01, 7.62766205e-01, 8.98333239e-01, 9.80144928e-01
101const G4double G4eBremsstrahlungRelModel::gWGL[] = {
102 5.06142681e-02, 1.11190517e-01, 1.56853323e-01, 1.81341892e-01,
103 1.81341892e-01, 1.56853323e-01, 1.11190517e-01, 5.06142681e-02
108const G4double G4eBremsstrahlungRelModel::gFelLowZet [] = {
109 0.0, 5.3104, 4.7935, 4.7402, 4.7112, 4.6694, 4.6134, 4.5520
111const G4double G4eBremsstrahlungRelModel::gFinelLowZet[] = {
112 0.0, 5.9173, 5.6125, 5.5377, 5.4728, 5.4174, 5.3688, 5.3236
116std::shared_ptr<G4eBremsstrahlungRelModel::LPMFuncs> G4eBremsstrahlungRelModel::gLPMFuncs()
125 static auto _instance = std::make_shared<G4eBremsstrahlungRelModel::LPMFuncs>();
130std::shared_ptr<std::vector<G4eBremsstrahlungRelModel::ElementData*>> G4eBremsstrahlungRelModel::gElementData()
133 static auto _instance = std::make_shared<std::vector<G4eBremsstrahlungRelModel::ElementData*>>();
137static std::once_flag applyOnce;
146:
G4VEmModel(nam), fLPMFuncs(gLPMFuncs()), fElementData(gElementData())
153 fLPMEnergyThreshold = 1.e+39;
164 if (fIsInitializer) {
166 for (
auto const & ptr : *fElementData) {
delete ptr; }
167 fElementData->clear();
169 if (fLPMFuncs->fIsInitialized) {
170 fLPMFuncs->fLPMFuncG.clear();
171 fLPMFuncs->fLPMFuncPhi.clear();
172 fLPMFuncs->fIsInitialized =
false;
188 std::call_once(applyOnce, [
this]() { fIsInitializer =
true; });
191 if (fIsInitializer || fElementData->empty()) {
193 if (fElementData->empty()) {
194 fElementData->resize(gMaxZet+1,
nullptr);
196 InitialiseElementData();
236 fLPMEnergy = gLPMconstant*mat->
GetRadlen();
241 fLPMEnergyThreshold = 1.e+39;
275 G4double tmax = std::min(cutEnergy, kineticEnergy);
284 const std::size_t numberOfElements = theElemVector->size();
287 for (std::size_t ie = 0; ie < numberOfElements; ++ie) {
289 G4int zet = (*theElemVector)[ie]->GetZasInt();
291 dedx += (zet*zet)*theAtomNumDensVector[ie]*ComputeBremLoss(tmax);
295 return std::max(dedx,0.);
324 for (
G4int l = 0; l < nSub; ++l) {
325 for (
G4int igl = 0; igl < 8; ++igl) {
330 ? ComputeRelDXSectionPerAtom(k)
340 return std::max(dedxInteg,0.);
361 const G4double tmin = std::min(cut, kineticEnergy);
362 const G4double tmax = std::min(maxEnergy, kineticEnergy);
370 crossSection = ComputeXSectionPerAtom(tmin);
375 if (tmax < kineticEnergy) {
376 crossSection -= ComputeXSectionPerAtom(tmax);
380 return std::max(crossSection, 0.);
406 const G4int nSub = std::max((
G4int)(0.45*alphaMax), 0) + 4;
410 for (
G4int l = 0; l < nSub; ++l) {
411 for (
G4int igl = 0; igl < 8; ++igl) {
416 ? ComputeRelDXSectionPerAtom(k)
427 return std::max(xSection, 0.);
454G4eBremsstrahlungRelModel::ComputeRelDXSectionPerAtom(
G4double gammaEnergy)
457 if (gammaEnergy < 0.) {
465 ComputeLPMfunctions(funcXiS, funcGS, funcPhiS, gammaEnergy);
466 const ElementData* elDat = (*fElementData)[
fCurrentIZ];
467 const G4double term1 = funcXiS*(dum0*funcGS+(onemy+2.0*dum0)*funcPhiS);
468 dxsec = term1*elDat->fZFactor1+onemy*elDat->fZFactor2;
472 fNucTerm = term1*elDat->fZFactor11 + onemy/12.;
474 return std::max(dxsec,0.0);
504 if (gammaEnergy < 0.) {
509 const G4double dum0 = onemy+0.75*y*y;
510 const ElementData* elDat = (*fElementData)[
fCurrentIZ];
512 if (
fCurrentIZ < 5 || fIsUseCompleteScreening) {
513 dxsec = dum0*elDat->fZFactor1;
514 dxsec += onemy*elDat->fZFactor2;
517 fNucTerm = dum0*elDat->fZFactor11+onemy/12.;
526 const G4double gamma = dum1*elDat->fGammaFactor;
529 G4double phi1, phi1m2, psi1, psi1m2;
530 ComputeScreeningFunctions(phi1, phi1m2, psi1, psi1m2, gamma,
epsilon);
531 dxsec = dum0*((0.25*phi1-Fz) + (0.25*psi1-2.*logZ/3.)*invZ);
532 dxsec += 0.125*onemy*(phi1m2 + psi1m2*invZ);
535 fNucTerm = dum0*(0.25*phi1-Fz) + 0.125*onemy*phi1m2;
538 return std::max(dxsec,0.0);
547void G4eBremsstrahlungRelModel::ComputeScreeningFunctions(
G4double& phi1,
555 phi1 = 16.863-2.0*
G4Log(1.0+0.311877*gam2)+2.4*
G4Exp(-0.9*gam)
556 +1.6*
G4Exp(-1.5*gam);
557 phi1m2 = 2.0/(3.0+19.5*gam+18.0*gam2);
559 psi1 = 24.34-2.0*
G4Log(1.0+13.111641*eps2)+2.8*
G4Exp(-8.0*eps)
560 +1.2*
G4Exp(-29.2*eps);
561 psi1m2 = 2.0/(3.0+120.0*eps+1200.0*eps2);
576 const G4double tmin = std::min(cutEnergy, kineticEnergy);
577 const G4double tmax = std::min(maxEnergy, kineticEnergy);
587 const ElementData* elDat = (*fElementData)[
fCurrentIZ];
588 const G4double funcMax = elDat->fZFactor1+elDat->fZFactor2;
600 ? ComputeRelDXSectionPerAtom(gammaEnergy)
612 }
while (funcVal < funcMax*rndm[1]);
627 vdp->push_back(gamma);
630 const G4double totMomentum = std::sqrt(kineticEnergy*(
634 const G4double finalE = kineticEnergy-gammaEnergy;
650void G4eBremsstrahlungRelModel::InitialiseElementData()
654 for (
auto const &
elem : *elemTable) {
656 const G4int izet = std::min(
elem->GetZasInt(), gMaxZet);
657 if (
nullptr == (*fElementData)[izet]) {
658 auto elemData =
new ElementData();
662 elemData->fLogZ =
G4Log(zet);
663 elemData->fFz = elemData->fLogZ/3.+fc;
665 Fel = gFelLowZet[izet];
666 Finel = gFinelLowZet[izet];
668 Fel =
G4Log(184.15) - elemData->fLogZ/3.;
669 Finel =
G4Log(1194) - 2.*elemData->fLogZ/3.;
673 elemData->fZFactor1 = (Fel-fc)+Finel/zet;
674 elemData->fZFactor11 = (Fel-fc);
675 elemData->fZFactor2 = (1.+1./zet)/12.;
676 elemData->fVarS1 = z23/(184.15*184.15);
677 elemData->fILVarS1Cond = 1./(
G4Log(std::sqrt(2.0)*elemData->fVarS1));
678 elemData->fILVarS1 = 1./
G4Log(elemData->fVarS1);
679 elemData->fGammaFactor = 100.0*electron_mass_c2/z13;
680 elemData->fEpsilonFactor = 100.0*electron_mass_c2/z23;
681 (*fElementData)[izet] = elemData;
686void G4eBremsstrahlungRelModel::ComputeLPMfunctions(
G4double& funcXiS,
691 static const G4double sqrt2 = std::sqrt(2.);
693 const G4double varSprime = std::sqrt(0.125*redegamma*fLPMEnergy/
695 const ElementData* elDat = (*fElementData)[
fCurrentIZ];
696 const G4double varS1 = elDat->fVarS1;
699 if (varSprime > 1.0) {
702 const G4double ilVarS1Cond = elDat->fILVarS1Cond;
704 funcXiSprime = 1.0 + funcHSprime - 0.08*(1.0-funcHSprime)*funcHSprime
705 *(2.0-funcHSprime)*ilVarS1Cond;
707 const G4double varS = varSprime/std::sqrt(funcXiSprime);
713 }
else if (varShat > varS1) {
714 funcXiS = 1.0+
G4Log(varShat)*elDat->fILVarS1;
716 GetLPMFunctions(funcGS, funcPhiS, varShat);
720 if (funcXiS*funcPhiS > 1. || varShat > 0.57) {
725void G4eBremsstrahlungRelModel::ComputeLPMGsPhis(
G4double& funcGS,
729 if (varShat < 0.01) {
730 funcPhiS = 6.0*varShat*(1.0-CLHEP::pi*varShat);
731 funcGS = 12.0*varShat-2.0*funcPhiS;
733 const G4double varShat2 = varShat*varShat;
734 const G4double varShat3 = varShat*varShat2;
735 const G4double varShat4 = varShat2*varShat2;
737 if (varShat < 0.415827) {
738 funcPhiS = 1.0-
G4Exp(-6.0*varShat*(1.0+varShat*(3.0-CLHEP::pi))
739 + varShat3/(0.623+0.796*varShat+0.658*varShat2));
742 - 8.0*varShat2/(1.0+3.936*varShat+4.97*varShat2
743 - 0.05*varShat3 + 7.5*varShat4));
745 funcGS = 3.0*funcPsiS - 2.0*funcPhiS;
746 }
else if (varShat<1.55) {
747 funcPhiS = 1.0-
G4Exp(-6.0*varShat*(1.0+varShat*(3.0-CLHEP::pi))
748 + varShat3/(0.623+0.796*varShat+0.658*varShat2));
749 const G4double dum0 = -0.160723 + 3.755030*varShat
750 -1.798138*varShat2 + 0.672827*varShat3
752 funcGS = std::tanh(dum0);
754 funcPhiS = 1.0-0.011905/varShat4;
755 if (varShat<1.9156) {
756 const G4double dum0 = -0.160723 + 3.755030*varShat
757 -1.798138*varShat2 + 0.672827*varShat3
759 funcGS = std::tanh(dum0);
761 funcGS = 1.0-0.023065/varShat4;
768void G4eBremsstrahlungRelModel::InitLPMFunctions()
770 if (!fLPMFuncs->fIsInitialized) {
771 const G4int num = fLPMFuncs->fSLimit*fLPMFuncs->fISDelta+1;
772 fLPMFuncs->fLPMFuncG.resize(num);
773 fLPMFuncs->fLPMFuncPhi.resize(num);
774 for (
G4int i = 0; i < num; ++i) {
775 const G4double sval=i/fLPMFuncs->fISDelta;
776 ComputeLPMGsPhis(fLPMFuncs->fLPMFuncG[i],fLPMFuncs->fLPMFuncPhi[i],sval);
778 fLPMFuncs->fIsInitialized =
true;
782void G4eBremsstrahlungRelModel::GetLPMFunctions(
G4double& lpmGs,
786 if (sval < fLPMFuncs->fSLimit) {
787 G4double val = sval*fLPMFuncs->fISDelta;
790 lpmGs = (fLPMFuncs->fLPMFuncG[ilow+1]-fLPMFuncs->fLPMFuncG[ilow])*val
791 + fLPMFuncs->fLPMFuncG[ilow];
792 lpmPhis = (fLPMFuncs->fLPMFuncPhi[ilow+1]-fLPMFuncs->fLPMFuncPhi[ilow])*val
793 + fLPMFuncs->fLPMFuncPhi[ilow];
797 lpmPhis = 1.0-0.01190476/ss;
798 lpmGs = 1.0-0.0230655/ss;
G4TemplateAutoLock< G4Mutex > G4AutoLock
G4double epsilon(G4double density, G4double temperature)
std::vector< const G4Element * > G4ElementVector
G4double condition(const G4ErrorSymMatrix &m)
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
G4double G4Log(G4double x)
#define G4MUTEX_INITIALIZER
CLHEP::Hep3Vector G4ThreeVector
virtual void flatArray(const int size, double *vect)=0
const G4ThreeVector & GetMomentumDirection() const
G4double GetLogKineticEnergy() const
G4double GetKineticEnergy() const
static G4Electron * Electron()
static const G4ElementTable * GetElementTable()
static G4EmParameters * Instance()
const G4Material * GetMaterial() const
const G4ElementVector * GetElementVector() const
const G4double * GetAtomicNumDensityVector() const
G4double GetElectronDensity() const
G4double GetRadlen() const
G4double GetPDGMass() const
static G4Pow * GetInstance()
G4double Z13(G4int Z) const
virtual G4ThreeVector & SampleDirection(const G4DynamicParticle *dp, G4double finalTotalEnergy, G4int Z, const G4Material *)=0
void SetElementSelectors(std::vector< G4EmElementSelector * > *)
G4VEmAngularDistribution * GetAngularDistribution()
G4double LowEnergyLimit() const
std::vector< G4EmElementSelector * > * GetElementSelectors()
G4VEmModel * GetTripletModel()
void SetCurrentElement(const G4Element *)
void SetLowEnergyLimit(G4double)
G4VEmModel(const G4String &nam)
void SetAngularDistribution(G4VEmAngularDistribution *)
virtual void SampleSecondaries(std::vector< G4DynamicParticle * > *, const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double tmin=0.0, G4double tmax=DBL_MAX)=0
const G4Element * SelectTargetAtom(const G4MaterialCutsCouple *, const G4ParticleDefinition *, G4double kineticEnergy, G4double logKineticEnergy, G4double cutEnergy=0.0, G4double maxEnergy=DBL_MAX)
void InitialiseElementSelectors(const G4ParticleDefinition *, const G4DataVector &)
virtual void Initialise(const G4ParticleDefinition *, const G4DataVector &)=0
G4double SecondaryThreshold() const
G4ParticleChangeForLoss * GetParticleChangeForLoss()
G4double fPrimaryParticleMass
void SetParticle(const G4ParticleDefinition *p)
G4double fPrimaryKinEnergy
G4double ComputeCrossSectionPerAtom(const G4ParticleDefinition *, G4double ekin, G4double zet, G4double, G4double cutEnergy, G4double maxEnergy=DBL_MAX) override
virtual G4double ComputeDXSectionPerAtom(G4double gammaEnergy)
const G4ParticleDefinition * fPrimaryParticle
static const G4double gBremFactor
void InitialiseLocal(const G4ParticleDefinition *, G4VEmModel *masterModel) override
G4bool fIsScatOffElectron
void SampleSecondaries(std::vector< G4DynamicParticle * > *, const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double cutEnergy, G4double maxEnergy) override
G4double fPrimaryTotalEnergy
G4double ComputeDEDXPerVolume(const G4Material *, const G4ParticleDefinition *, G4double ekin, G4double cutEnergy) override
G4eBremsstrahlungRelModel(const G4ParticleDefinition *p=nullptr, const G4String &nam="eBremLPM")
~G4eBremsstrahlungRelModel() override
G4double fLowestKinEnergy
G4ParticleDefinition * fGammaParticle
void SetupForMaterial(const G4ParticleDefinition *, const G4Material *, G4double) override
G4ParticleChangeForLoss * fParticleChange
G4double MinPrimaryEnergy(const G4Material *, const G4ParticleDefinition *, G4double cutEnergy) override
static const G4double gMigdalConstant
void Initialise(const G4ParticleDefinition *, const G4DataVector &) override