Import Geant4 10.6.0 source tree
This commit is contained in:
@@ -39,6 +39,7 @@
|
||||
// (ANR-13-BS05-0002).
|
||||
//
|
||||
// Reference: Nucl. Instrum. Meth. A 899 (2018) 85 (arXiv:1802.08253 [hep-ph])
|
||||
// Nucl. Instrum. Meth., A 936 (2019) 290
|
||||
//
|
||||
// Class Description:
|
||||
//
|
||||
@@ -104,6 +105,8 @@
|
||||
#include "G4Electron.hh"
|
||||
#include "G4Positron.hh"
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4MuonPlus.hh"
|
||||
#include "G4MuonMinus.hh"
|
||||
#include "G4IonTable.hh"
|
||||
#include "G4NucleiProperties.hh"
|
||||
|
||||
@@ -117,15 +120,31 @@
|
||||
#include "G4ThreeVector.hh"
|
||||
#include "G4RotationMatrix.hh"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
// // Q : Use enum G4EmProcessSubType hire ?
|
||||
// enum G45DConversionMode
|
||||
// {
|
||||
// kEPair, kMuPair
|
||||
// };
|
||||
|
||||
const G4int kEPair = 0;
|
||||
const G4int kMuPair = 1;
|
||||
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4BetheHeitler5DModel::G4BetheHeitler5DModel(const G4ParticleDefinition* pd,
|
||||
const G4String& nam)
|
||||
: G4BetheHeitlerModel(pd, nam), fVerbose(1), fConversionType(0), iraw(false)
|
||||
: G4PairProductionRelModel(pd, nam),fVerbose(1),fConversionType(0),
|
||||
iraw(false),
|
||||
fLepton1(G4Electron::Definition()),fLepton2(G4Positron::Definition()),
|
||||
fConvMode(kEPair),
|
||||
fTheMuPlus(G4MuonPlus::Definition()),fTheMuMinus(G4MuonMinus::Definition())
|
||||
{
|
||||
SetLowEnergyLimit(2*CLHEP::electron_mass_c2);
|
||||
theIonTable = G4IonTable::GetIonTable();
|
||||
//Q: Do we need this on Model
|
||||
SetLowEnergyLimit(2*fTheElectron->GetPDGMass());
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -138,7 +157,7 @@ G4BetheHeitler5DModel::~G4BetheHeitler5DModel()
|
||||
void G4BetheHeitler5DModel::Initialise(const G4ParticleDefinition* part,
|
||||
const G4DataVector& vec)
|
||||
{
|
||||
G4BetheHeitlerModel::Initialise(part, vec);
|
||||
G4PairProductionRelModel::Initialise(part, vec);
|
||||
|
||||
G4EmParameters* theManager = G4EmParameters::Instance();
|
||||
// place to initialise model parameters
|
||||
@@ -156,6 +175,90 @@ void G4BetheHeitler5DModel::Initialise(const G4ParticleDefinition* part,
|
||||
iraw = theManager->OnIsolated();
|
||||
// G4cout << "BH5DModel::Initialise verbose " << fVerbose
|
||||
// << " isolated " << iraw << " ctype "<< fConversionType << G4endl;
|
||||
|
||||
//Q: Do we need this on Model
|
||||
// The Leptons defined via SetLeptonPair(..) method
|
||||
SetLowEnergyLimit(2*CLHEP::electron_mass_c2);
|
||||
|
||||
if (fConvMode == kEPair) {
|
||||
assert(fLepton1->GetPDGEncoding() == fTheElectron->GetPDGEncoding()) ;
|
||||
if (fVerbose > 3)
|
||||
G4cout << "BH5DModel::Initialise conversion to e+ e-" << G4endl;
|
||||
}
|
||||
|
||||
if (fConvMode == kMuPair) {
|
||||
assert(fLepton1->GetPDGEncoding() == fTheMuMinus->GetPDGEncoding()) ;
|
||||
if (fVerbose > 3)
|
||||
G4cout << "BH5DModel::Initialise conversion to mu+ mu-" << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4BetheHeitler5DModel::SetLeptonPair(const G4ParticleDefinition* p1,
|
||||
const G4ParticleDefinition* p2)
|
||||
{
|
||||
// Lepton1 - nagative charged particle
|
||||
if ( p1->GetPDGEncoding() < 0 ){
|
||||
if ( p1->GetPDGEncoding() ==
|
||||
G4Positron::Definition()->GetPDGEncoding() ) {
|
||||
SetConversionMode(kEPair);
|
||||
fLepton1 = p2;
|
||||
fLepton2 = p1;
|
||||
// if (fVerbose)
|
||||
G4cout << "G4BetheHeitler5DModel::SetLeptonPair conversion to e+ e-"
|
||||
<< G4endl;
|
||||
} else if ( p1->GetPDGEncoding() ==
|
||||
G4MuonPlus::Definition()->GetPDGEncoding() ) {
|
||||
SetConversionMode(kMuPair);
|
||||
fLepton1 = p2;
|
||||
fLepton2 = p1;
|
||||
// if (fVerbose)
|
||||
G4cout << "G4BetheHeitler5DModel::SetLeptonPair conversion to mu+ mu-"
|
||||
<< G4endl;
|
||||
} else {
|
||||
// Exception
|
||||
G4ExceptionDescription ed;
|
||||
ed << "Model not applicable to particle(s) "
|
||||
<< p1->GetParticleName() << ", "
|
||||
<< p2->GetParticleName();
|
||||
G4Exception("G4BetheHeitler5DModel::SetLeptonPair","em0002",
|
||||
FatalException, ed);
|
||||
}
|
||||
} else {
|
||||
if ( p1->GetPDGEncoding() ==
|
||||
G4Electron::Definition()->GetPDGEncoding() ) {
|
||||
SetConversionMode(kEPair);
|
||||
fLepton1 = p1;
|
||||
fLepton2 = p2;
|
||||
// if (fVerbose)
|
||||
G4cout << "G4BetheHeitler5DModel::SetLeptonPair conversion to e+ e-"
|
||||
<< G4endl;
|
||||
} else if ( p1->GetPDGEncoding() ==
|
||||
G4MuonMinus::Definition()->GetPDGEncoding() ) {
|
||||
SetConversionMode(kMuPair);
|
||||
fLepton1 = p1;
|
||||
fLepton2 = p2;
|
||||
// if (fVerbose)
|
||||
G4cout << "G4BetheHeitler5DModel::SetLeptonPair conversion to mu+ mu-"
|
||||
<< G4endl;
|
||||
} else {
|
||||
// Exception
|
||||
G4ExceptionDescription ed;
|
||||
ed << "Model not applicable to particle(s) "
|
||||
<< p1->GetParticleName() << ", "
|
||||
<< p2->GetParticleName();
|
||||
G4Exception("G4BetheHeitler5DModel::SetLeptonPair","em0002",
|
||||
FatalException, ed);
|
||||
}
|
||||
}
|
||||
if ( fLepton1->GetPDGEncoding() != fLepton2->GetAntiPDGEncoding() ) {
|
||||
G4Exception("G4BetheHeitler5DModel::SetLeptonPair","em0007",
|
||||
FatalErrorInArgument, "pair must be particle, antiparticle ");
|
||||
G4cerr << "BH5DModel::SetLeptonPair BAD paricle/anti particle pair"
|
||||
<< fLepton1->GetParticleName() << ", "
|
||||
<< fLepton2->GetParticleName() << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -181,9 +284,12 @@ G4BetheHeitler5DModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
|
||||
{
|
||||
// MeV
|
||||
static const G4double ElectronMass = CLHEP::electron_mass_c2;
|
||||
static const G4double ElectronMass2 = ElectronMass*ElectronMass;
|
||||
|
||||
const G4double LeptonMass = fLepton1->GetPDGMass();
|
||||
const G4double LeptonMass2 = LeptonMass*LeptonMass;
|
||||
|
||||
static const G4double alpha0 = CLHEP::fine_structure_const;
|
||||
// mm
|
||||
// mm
|
||||
static const G4double r0 = CLHEP::classic_electr_radius;
|
||||
// mbarn
|
||||
static const G4double r02 = r0*r0*1.e+25;
|
||||
@@ -192,25 +298,45 @@ G4BetheHeitler5DModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
|
||||
// static const G4double factor1 = pow((6.0 * pi),(1.0/3.0))/(8.*alpha0*ElectronMass);
|
||||
static const G4double factor1 = 2.66134007899/(8.*alpha0*ElectronMass);
|
||||
//
|
||||
static const G4double PairInvMassMin = 2.*ElectronMass;
|
||||
G4double PairInvMassMin = 2.*LeptonMass;
|
||||
G4double TrThreshold = 2.0 * ( (LeptonMass2)/ElectronMass + LeptonMass);
|
||||
|
||||
//
|
||||
static const G4double nu[10] = { 0.0227436, 0.0582046, 3.0322675, 2.8275065,
|
||||
-0.0034004, 1.1212766, 1.8989468, 68.3492750,
|
||||
0.0211186, 14.4 };
|
||||
static const G4double tr[10] = { 0.0332350, 4.3942537, 2.8515925, 2.6351695,
|
||||
-0.0031510, 1.5737305, 1.8104647, 20.6434021,
|
||||
-0.0272586, 28.9};
|
||||
static const G4double nu[2][10] = {
|
||||
//electron
|
||||
{ 0.0227436, 0.0582046, 3.0322675, 2.8275065, -0.0034004,
|
||||
1.1212766, 1.8989468, 68.3492750, 0.0211186, 14.4},
|
||||
//muon
|
||||
{0.67810E-06, 0.86037E+05, 2.0008395, 1.6739719, -0.0057279,
|
||||
1.4222, 0.0, 263230.0, 0.0521, 51.1338}
|
||||
};
|
||||
static const G4double tr[2][10] = {
|
||||
//electron
|
||||
{ 0.0332350, 4.3942537, 2.8515925, 2.6351695, -0.0031510,
|
||||
1.5737305, 1.8104647, 20.6434021, -0.0272586, 28.9},
|
||||
//muon
|
||||
{0.10382E-03, 0.14408E+17, 4.1368679, 3.2662121, -0.0163091,
|
||||
0.0000, 0.0, 0.0, 0.0000, 1.0000}
|
||||
};
|
||||
//
|
||||
static const G4double para[3][2] = { {11., -16.},{-1.17, -2.95},{-2., -0.5} };
|
||||
static const G4double para[2][3][2] = {
|
||||
//electron
|
||||
{ {11., -16.},{-1.17, -2.95},{-2., -0.5} },
|
||||
//muon
|
||||
{ {17.5, 1.},{-1.17, -2.95},{2., 6.} }
|
||||
};
|
||||
//
|
||||
static const G4double correctionIndex = 1.4;
|
||||
//
|
||||
const G4double GammaEnergy = aDynamicGamma->GetKineticEnergy();
|
||||
// Protection, Will not be true tot cross section = 0
|
||||
if ( GammaEnergy <= PairInvMassMin) { return; }
|
||||
|
||||
const G4double GammaEnergy2 = GammaEnergy*GammaEnergy;
|
||||
// Will not be true tot cross section = 0
|
||||
if ( GammaEnergy <= 2.0*ElectronMass) { return; }
|
||||
//
|
||||
const G4ParticleMomentum GammaDirection = aDynamicGamma->GetMomentumDirection();
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
const G4ParticleMomentum GammaDirection =
|
||||
aDynamicGamma->GetMomentumDirection();
|
||||
G4ThreeVector GammaPolarization = aDynamicGamma->GetPolarization();
|
||||
|
||||
// The protection polarization perpendicular to the direction vector,
|
||||
@@ -223,6 +349,7 @@ G4BetheHeitler5DModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
|
||||
// End of Protection
|
||||
//
|
||||
const G4double GammaPolarizationMag = GammaPolarization.mag();
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// target element
|
||||
// select randomly one element constituting the material
|
||||
@@ -234,6 +361,10 @@ G4BetheHeitler5DModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
|
||||
const G4double iZ13 = 1./anElement->GetIonisation()->GetZ3();
|
||||
const G4double targetMass = G4NucleiProperties::GetNuclearMass(A, Z);
|
||||
|
||||
const G4double NuThreshold = 2.0 * ( (LeptonMass2)/targetMass + LeptonMass);
|
||||
// No conversion possible below nuclear threshold
|
||||
if ( GammaEnergy <= NuThreshold) { return; }
|
||||
|
||||
CLHEP::HepRandomEngine* rndmEngine = G4Random::getTheEngine();
|
||||
|
||||
// itriplet : true -- triplet, false -- nuclear.
|
||||
@@ -242,8 +373,8 @@ G4BetheHeitler5DModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
|
||||
itriplet = false;
|
||||
} else if (fConversionType == 2) {
|
||||
itriplet = true;
|
||||
if ( GammaEnergy <= 4.0*ElectronMass ) return;
|
||||
} else if ( GammaEnergy > 4.0*ElectronMass ) {
|
||||
if ( GammaEnergy <= TrThreshold ) return;
|
||||
} else if ( GammaEnergy > TrThreshold ) {
|
||||
// choose triplet or nuclear from a triplet/nuclear=1/Z
|
||||
// total cross section ratio.
|
||||
// approximate at low energies !
|
||||
@@ -251,6 +382,7 @@ G4BetheHeitler5DModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
|
||||
itriplet = true;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
const G4double RecoilMass = itriplet ? ElectronMass : targetMass;
|
||||
const G4double RecoilMass2 = RecoilMass*RecoilMass;
|
||||
@@ -269,27 +401,33 @@ G4BetheHeitler5DModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
|
||||
|
||||
// maximum value of pdf
|
||||
const G4double EffectiveZ = iraw ? 0.5 : Z;
|
||||
const G4double Threshold = itriplet ? 4.*ElectronMass : 2.*ElectronMass;
|
||||
const G4double Threshold = itriplet ? TrThreshold : NuThreshold;
|
||||
const G4double AvailableEnergy = GammaEnergy - Threshold;
|
||||
const G4double LogAvailableEnergy = G4Log(AvailableEnergy);
|
||||
//
|
||||
const G4double MaxDiffCross = itriplet
|
||||
? MaxDiffCrossSection(tr, EffectiveZ, AvailableEnergy, LogAvailableEnergy)
|
||||
: MaxDiffCrossSection(nu, EffectiveZ, AvailableEnergy, LogAvailableEnergy);
|
||||
? MaxDiffCrossSection(tr[fConvMode],
|
||||
EffectiveZ, AvailableEnergy, LogAvailableEnergy)
|
||||
: MaxDiffCrossSection(nu[fConvMode],
|
||||
EffectiveZ, AvailableEnergy, LogAvailableEnergy);
|
||||
//
|
||||
// 50% safety marging factor
|
||||
const G4double ymax = 1.5 * MaxDiffCross;
|
||||
// x1 bounds
|
||||
const G4double xu1 = (LogAvailableEnergy > para[2][0])
|
||||
? para[0][0] + para[1][0]*LogAvailableEnergy
|
||||
: para[0][0] + para[2][0]*para[1][0];
|
||||
const G4double xl1 = (LogAvailableEnergy > para[2][1])
|
||||
? para[0][1] + para[1][1]*LogAvailableEnergy
|
||||
: para[0][1] + para[2][1]*para[1][1];
|
||||
const G4double xu1 = (LogAvailableEnergy > para[fConvMode][2][0])
|
||||
? para[fConvMode][0][0] +
|
||||
para[fConvMode][1][0]*LogAvailableEnergy
|
||||
: para[fConvMode][0][0] +
|
||||
para[fConvMode][2][0]*para[fConvMode][1][0];
|
||||
const G4double xl1 = (LogAvailableEnergy > para[fConvMode][2][1])
|
||||
? para[fConvMode][0][1] +
|
||||
para[fConvMode][1][1]*LogAvailableEnergy
|
||||
: para[fConvMode][0][1] +
|
||||
para[fConvMode][2][1]*para[fConvMode][1][1];
|
||||
//
|
||||
G4LorentzVector Recoil;
|
||||
G4LorentzVector Positron;
|
||||
G4LorentzVector Electron;
|
||||
G4LorentzVector LeptonPlus;
|
||||
G4LorentzVector LeptonMinus;
|
||||
G4double pdf = 0.;
|
||||
|
||||
G4double rndmv6[6];
|
||||
@@ -356,30 +494,25 @@ G4BetheHeitler5DModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
|
||||
thePRecoil*cosTheta,
|
||||
RecEnergyCMS);
|
||||
|
||||
// const G4LorentzVector Pair(-Recoil.x(),
|
||||
// -Recoil.y(),
|
||||
// -Recoil.z(),
|
||||
// sqrts-RecEnergyCMS);
|
||||
|
||||
// in the pair frame
|
||||
const G4double thePLepton = std::sqrt( (LeptonEnergy2-ElectronMass)
|
||||
*(LeptonEnergy2+ElectronMass));
|
||||
const G4double thePLepton = std::sqrt( (LeptonEnergy2-LeptonMass)
|
||||
*(LeptonEnergy2+LeptonMass));
|
||||
|
||||
Positron.set(thePLepton*sinThetaLept*cosPhiLept,
|
||||
LeptonPlus.set(thePLepton*sinThetaLept*cosPhiLept,
|
||||
thePLepton*sinThetaLept*sinPhiLept,
|
||||
thePLepton*cosThetaLept,
|
||||
LeptonEnergy2);
|
||||
|
||||
Electron.set(-Positron.x(),
|
||||
-Positron.y(),
|
||||
-Positron.z(),
|
||||
LeptonMinus.set(-LeptonPlus.x(),
|
||||
-LeptonPlus.y(),
|
||||
-LeptonPlus.z(),
|
||||
LeptonEnergy2);
|
||||
|
||||
|
||||
// Normalisation of final state phase space:
|
||||
// Section 47 of Particle Data Group, Chin. Phys. C, 40, 100001 (2016)
|
||||
// const G4double Norme = Recoil1.vect().mag() * Positron2.vect().mag();
|
||||
const G4double Norme = Recoil.vect().mag() * Positron.vect().mag();
|
||||
// const G4double Norme = Recoil1.vect().mag() * LeptonPlus2.vect().mag();
|
||||
const G4double Norme = Recoil.vect().mag() * LeptonPlus.vect().mag();
|
||||
|
||||
// e+, e- to CMS frame from pair frame
|
||||
|
||||
@@ -388,50 +521,50 @@ G4BetheHeitler5DModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
|
||||
G4LorentzVector( -Recoil.x(), -Recoil.y(), -Recoil.z(),
|
||||
sqrts-RecEnergyCMS).boostVector();
|
||||
|
||||
Positron.boost(pair2cms);
|
||||
Electron.boost(pair2cms);
|
||||
LeptonPlus.boost(pair2cms);
|
||||
LeptonMinus.boost(pair2cms);
|
||||
|
||||
// back to the laboratory frame (make use of the CMS(0,0,Eg,Eg+RM)) form
|
||||
|
||||
Recoil.boostZ(betaCMS);
|
||||
Positron.boostZ(betaCMS);
|
||||
Electron.boostZ(betaCMS);
|
||||
LeptonPlus.boostZ(betaCMS);
|
||||
LeptonMinus.boostZ(betaCMS);
|
||||
|
||||
// Jacobian factors
|
||||
const G4double Jacob0 = x0*dum0*dum0;
|
||||
const G4double Jacob1 = 2.*X1*lnPairInvMassRange*PairInvMass;
|
||||
const G4double Jacob2 = std::abs(sinThetaLept);
|
||||
|
||||
const G4double EPlus = Positron.t();
|
||||
const G4double PPlus = Positron.vect().mag();
|
||||
const G4double sinThetaPlus = Positron.vect().perp()/PPlus;
|
||||
const G4double cosThetaPlus = Positron.vect().cosTheta();
|
||||
const G4double EPlus = LeptonPlus.t();
|
||||
const G4double PPlus = LeptonPlus.vect().mag();
|
||||
const G4double sinThetaPlus = LeptonPlus.vect().perp()/PPlus;
|
||||
const G4double cosThetaPlus = LeptonPlus.vect().cosTheta();
|
||||
|
||||
const G4double pPX = Positron.x();
|
||||
const G4double pPY = Positron.y();
|
||||
const G4double pPX = LeptonPlus.x();
|
||||
const G4double pPY = LeptonPlus.y();
|
||||
const G4double dum1 = 1./std::sqrt( pPX*pPX + pPY*pPY );
|
||||
const G4double cosPhiPlus = pPX*dum1;
|
||||
const G4double sinPhiPlus = pPY*dum1;
|
||||
|
||||
// denominators:
|
||||
// the two cancelling leading terms for forward emission at high energy, removed
|
||||
const G4double elMassCTP = ElectronMass*cosThetaPlus;
|
||||
const G4double elMassCTP = LeptonMass*cosThetaPlus;
|
||||
const G4double ePlusSTP = EPlus*sinThetaPlus;
|
||||
const G4double DPlus = (elMassCTP*elMassCTP + ePlusSTP*ePlusSTP)
|
||||
/(EPlus + PPlus*cosThetaPlus);
|
||||
|
||||
const G4double EMinus = Electron.t();
|
||||
const G4double PMinus = Electron.vect().mag();
|
||||
const G4double sinThetaMinus = Electron.vect().perp()/PMinus;
|
||||
const G4double cosThetaMinus = Electron.vect().cosTheta();
|
||||
const G4double EMinus = LeptonMinus.t();
|
||||
const G4double PMinus = LeptonMinus.vect().mag();
|
||||
const G4double sinThetaMinus = LeptonMinus.vect().perp()/PMinus;
|
||||
const G4double cosThetaMinus = LeptonMinus.vect().cosTheta();
|
||||
|
||||
const G4double ePX = Electron.x();
|
||||
const G4double ePY = Electron.y();
|
||||
const G4double ePX = LeptonMinus.x();
|
||||
const G4double ePY = LeptonMinus.y();
|
||||
const G4double dum2 = 1./std::sqrt( ePX*ePX + ePY*ePY );
|
||||
const G4double cosPhiMinus = ePX*dum2;
|
||||
const G4double sinPhiMinus = ePY*dum2;
|
||||
|
||||
const G4double elMassCTM = ElectronMass*cosThetaMinus;
|
||||
const G4double elMassCTM = LeptonMass*cosThetaMinus;
|
||||
const G4double eMinSTM = EMinus*sinThetaMinus;
|
||||
const G4double DMinus = (elMassCTM*elMassCTM + eMinSTM*eMinSTM)
|
||||
/(EMinus + PMinus*cosThetaMinus);
|
||||
@@ -440,7 +573,8 @@ G4BetheHeitler5DModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
|
||||
const G4double cosdPhi = cosPhiPlus*cosPhiMinus + sinPhiPlus*sinPhiMinus;
|
||||
const G4double PRec = Recoil.vect().mag();
|
||||
const G4double q2 = PRec*PRec;
|
||||
const G4double BigPhi = -ElectronMass2 / (GammaEnergy*GammaEnergy2 * q2*q2);
|
||||
|
||||
const G4double BigPhi = -LeptonMass2 / (GammaEnergy*GammaEnergy2 * q2*q2);
|
||||
|
||||
G4double FormFactor = 1.;
|
||||
if (!iraw) {
|
||||
@@ -523,24 +657,22 @@ G4BetheHeitler5DModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
|
||||
G4RotationMatrix GtoW(GammaPolarization,yGrec,GammaDirection);
|
||||
|
||||
Recoil.transform(GtoW);
|
||||
Positron.transform(GtoW);
|
||||
Electron.transform(GtoW);
|
||||
LeptonPlus.transform(GtoW);
|
||||
LeptonMinus.transform(GtoW);
|
||||
|
||||
if ( fVerbose > 2 ) {
|
||||
G4cout << "BetheHeitler5DModel Recoil " << Recoil.x() << " " << Recoil.y() << " " << Recoil.z()
|
||||
<< " " << Recoil.t() << " " << G4endl;
|
||||
G4cout << "BetheHeitler5DModel Positron " << Positron.x() << " " << Positron.y() << " "
|
||||
<< Positron.z() << " " << Positron.t() << " " << G4endl;
|
||||
G4cout << "BetheHeitler5DModel Electron " << Electron.x() << " " << Electron.y() << " "
|
||||
<< Electron.z() << " " << Electron.t() << " " << G4endl;
|
||||
G4cout << "BetheHeitler5DModel LeptonPlus " << LeptonPlus.x() << " " << LeptonPlus.y() << " "
|
||||
<< LeptonPlus.z() << " " << LeptonPlus.t() << " " << G4endl;
|
||||
G4cout << "BetheHeitler5DModel LeptonMinus " << LeptonMinus.x() << " " << LeptonMinus.y() << " "
|
||||
<< LeptonMinus.z() << " " << LeptonMinus.t() << " " << G4endl;
|
||||
}
|
||||
|
||||
// Create secondaries
|
||||
G4DynamicParticle* aParticle1 = new G4DynamicParticle(fLepton1,LeptonMinus);
|
||||
G4DynamicParticle* aParticle2 = new G4DynamicParticle(fLepton2,LeptonPlus);
|
||||
|
||||
// electron
|
||||
G4DynamicParticle* aParticle1 = new G4DynamicParticle(fTheElectron,Electron);
|
||||
// positron
|
||||
G4DynamicParticle* aParticle2 = new G4DynamicParticle(fThePositron,Positron);
|
||||
// create G4DynamicParticle object for the particle3 ( recoil )
|
||||
G4ParticleDefinition* RecoilPart;
|
||||
if (itriplet) {
|
||||
|
||||
@@ -105,7 +105,7 @@ G4double G4ESTARStopping::GetElectronicDEDX(G4int i, G4double energy)
|
||||
|
||||
void G4ESTARStopping::Initialise()
|
||||
{
|
||||
dirPath = getenv("G4LEDATA");
|
||||
dirPath = std::getenv("G4LEDATA");
|
||||
if(!dirPath) {
|
||||
G4Exception("G4ESTARStopping()","em0006",FatalException,
|
||||
"Environment variable G4LEDATA not defined");
|
||||
|
||||
@@ -253,7 +253,7 @@ void G4GSMottCorrection::InitMCDataPerMaterials() {
|
||||
// it's called only if data has not been loaded for this element yet
|
||||
void G4GSMottCorrection::LoadMCDataElement(const G4Element *elem) {
|
||||
// allocate memory
|
||||
G4int izet = G4lrint(elem->GetZ());
|
||||
G4int izet = elem->GetZasInt();
|
||||
if (izet>gMaxZet) {
|
||||
izet = gMaxZet;
|
||||
}
|
||||
@@ -262,7 +262,7 @@ void G4GSMottCorrection::LoadMCDataElement(const G4Element *elem) {
|
||||
fMCDataPerElement[izet] = perElem;
|
||||
//
|
||||
// load data from file
|
||||
char* tmppath = getenv("G4LEDATA");
|
||||
char* tmppath = std::getenv("G4LEDATA");
|
||||
if (!tmppath) {
|
||||
G4Exception("G4GSMottCorrection::LoadMCDataElement()","em0006",
|
||||
FatalException,
|
||||
|
||||
@@ -175,12 +175,12 @@ void G4GSPWACorrections::InitDataPerMaterials() {
|
||||
// it's called only if data has not been loaded for this element yet
|
||||
void G4GSPWACorrections::LoadDataElement(const G4Element *elem) {
|
||||
// allocate memory
|
||||
G4int izet = G4lrint(elem->GetZ());
|
||||
G4int izet = elem->GetZasInt();
|
||||
if (izet>gMaxZet) {
|
||||
izet = gMaxZet;
|
||||
}
|
||||
// load data from file
|
||||
char* tmppath = getenv("G4LEDATA");
|
||||
char* tmppath = std::getenv("G4LEDATA");
|
||||
if (!tmppath) {
|
||||
G4Exception("G4GSPWACorrection::LoadDataElement()","em0006",
|
||||
FatalException,
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
#include "G4GammaConversion.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4BetheHeitlerModel.hh"
|
||||
#include "G4PairProductionRelModel.hh"
|
||||
#include "G4Electron.hh"
|
||||
#include "G4EmParameters.hh"
|
||||
@@ -80,18 +79,10 @@ void G4GammaConversion::InitialiseProcess(const G4ParticleDefinition*)
|
||||
|
||||
SetMinKinEnergy(emin);
|
||||
|
||||
if(!EmModel(0)) { SetEmModel(new G4BetheHeitlerModel()); }
|
||||
if(!EmModel(0)) { SetEmModel(new G4PairProductionRelModel()); }
|
||||
EmModel(0)->SetLowEnergyLimit(emin);
|
||||
G4double energyLimit = std::min(EmModel(0)->HighEnergyLimit(), 80*GeV);
|
||||
EmModel(0)->SetHighEnergyLimit(energyLimit);
|
||||
EmModel(0)->SetHighEnergyLimit(emax);
|
||||
AddEmModel(1, EmModel(0));
|
||||
|
||||
if(emax > energyLimit) {
|
||||
if(!EmModel(1)) { SetEmModel(new G4PairProductionRelModel()); }
|
||||
EmModel(1)->SetLowEnergyLimit(energyLimit);
|
||||
EmModel(1)->SetHighEnergyLimit(emax);
|
||||
AddEmModel(1, EmModel(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -165,7 +165,6 @@ G4GoudsmitSaundersonMscModel::G4GoudsmitSaundersonMscModel(const G4String& nam)
|
||||
charge = 0;
|
||||
currentMaterialIndex = -1;
|
||||
//
|
||||
lambdalimit = 1.*mm;
|
||||
fr = 0.1;
|
||||
rangeinit = 1.e+21;
|
||||
geombig = 1.e+50*mm;
|
||||
@@ -185,8 +184,6 @@ G4GoudsmitSaundersonMscModel::G4GoudsmitSaundersonMscModel(const G4String& nam)
|
||||
mass = electron_mass_c2;
|
||||
taulim = 1.e-6;
|
||||
//
|
||||
facsafety = 0.6;
|
||||
|
||||
currentCouple = nullptr;
|
||||
fParticleChange = nullptr;
|
||||
//
|
||||
@@ -253,6 +250,7 @@ G4GoudsmitSaundersonMscModel::~G4GoudsmitSaundersonMscModel() {
|
||||
|
||||
void G4GoudsmitSaundersonMscModel::Initialise(const G4ParticleDefinition* p, const G4DataVector&) {
|
||||
SetParticle(p);
|
||||
InitialiseParameters(p);
|
||||
// -create GoudsmitSaundersonTable and init its Mott-correction member if
|
||||
// Mott-correction was required
|
||||
if (IsMaster()) {
|
||||
@@ -314,14 +312,13 @@ G4double G4GoudsmitSaundersonMscModel::CrossSectionPerVolume(const G4Material* m
|
||||
G4double,
|
||||
G4double) {
|
||||
G4double xsecTr1 = 0.; // cross section per volume i.e. macroscopic 1st transport cross section
|
||||
G4double efEnergy = kineticEnergy;
|
||||
//
|
||||
fLambda0 = 0.0; // elastic mean free path
|
||||
fLambda1 = 0.0; // first transport mean free path
|
||||
fScrA = 0.0; // screening parameter
|
||||
fG1 = 0.0; // first transport coef.
|
||||
// use Moliere's screening (with Mott-corretion if it was requested)
|
||||
if (efEnergy<10.*CLHEP::eV) efEnergy = 10.*CLHEP::eV;
|
||||
G4double efEnergy = std::max(kineticEnergy, 10.*CLHEP::eV);
|
||||
// total mometum square
|
||||
G4double pt2 = efEnergy*(efEnergy+2.0*electron_mass_c2);
|
||||
// beta square
|
||||
|
||||
@@ -435,7 +435,7 @@ G4GoudsmitSaundersonTable::GSMSCAngularDtr* G4GoudsmitSaundersonTable::GetGSAngu
|
||||
|
||||
|
||||
void G4GoudsmitSaundersonTable::LoadMSCData() {
|
||||
char* path = getenv("G4LEDATA");
|
||||
char* path = std::getenv("G4LEDATA");
|
||||
if (!path) {
|
||||
G4Exception("G4GoudsmitSaundersonTable::LoadMSCData()","em0006",
|
||||
FatalException,
|
||||
|
||||
@@ -94,10 +94,11 @@ void G4ICRU49NuclearStoppingModel::InitialiseArray()
|
||||
#ifdef G4MULTITHREADED
|
||||
G4MUTEXLOCK(&G4ICRU49NuclearStoppingModel::ICRU49NuclearMutex);
|
||||
#endif
|
||||
if(0.0 == Z23[2]) {
|
||||
for(G4int i=1; i<100; ++i) {
|
||||
if(0.0 == Z23[1]) {
|
||||
for(G4int i=2; i<100; ++i) {
|
||||
Z23[i] = g4calc->powZ(i, 0.23);
|
||||
}
|
||||
Z23[1] = 1.0;
|
||||
}
|
||||
#ifdef G4MULTITHREADED
|
||||
G4MUTEXUNLOCK(&G4ICRU49NuclearStoppingModel::ICRU49NuclearMutex);
|
||||
|
||||
@@ -117,6 +117,11 @@ G4PairProductionRelModel::G4PairProductionRelModel(const G4ParticleDefinition*,
|
||||
fTheElectron(G4Electron::Electron()), fThePositron(G4Positron::Positron()),
|
||||
fParticleChange(nullptr)
|
||||
{
|
||||
// gamma energy below which the parametrized atomic x-section is used (80 GeV)
|
||||
fParametrizedXSectionThreshold = 80.0*CLHEP::GeV;
|
||||
// gamma energy below the Coulomb correction is turned off (50 MeV)
|
||||
fCoulombCorrectionThreshold = 50.0*CLHEP::MeV;
|
||||
// set angular generator used in the final state kinematics computation
|
||||
SetAngularDistribution(new G4ModifiedTsai());
|
||||
}
|
||||
|
||||
@@ -174,7 +179,9 @@ G4double G4PairProductionRelModel::ComputeXSectionPerAtom(G4double gammaEnergy,
|
||||
// the way in which the Coulomb correction is applied i.e. avoid negative DCS)
|
||||
const G4int iz = std::min(gMaxZet, G4lrint(Z));
|
||||
const G4double eps0 = CLHEP::electron_mass_c2/gammaEnergy;
|
||||
const G4double dmax = gElementData[iz]->fDeltaMax;
|
||||
// Coulomb correction is always included in the DCS even below 50 MeV (note:
|
||||
// that this DCS is only used to get the integrated x-section)
|
||||
const G4double dmax = gElementData[iz]->fDeltaMaxHigh;
|
||||
const G4double dmin = 4.*eps0*gElementData[iz]->fDeltaFactor;
|
||||
const G4double eps1 = 0.5 - 0.5*std::sqrt(1.-dmin/dmax);
|
||||
const G4double epsMin = std::max(eps0, eps1);
|
||||
@@ -306,18 +313,26 @@ G4PairProductionRelModel::ComputeCrossSectionPerAtom(const G4ParticleDefinition*
|
||||
G4double crossSection = 0.0 ;
|
||||
// check kinematical limit
|
||||
if ( gammaEnergy <= 2.0*electron_mass_c2 ) { return crossSection; }
|
||||
// Computes the cross section with or without LPM suppression depending on
|
||||
// settings (by default with if the gamma energy is above a given threshold)
|
||||
// and using or not using complete sreening approximation (by default not).
|
||||
// Only the dependent part is computed in the numerical integration of the DCS
|
||||
// i.e. the result must be multiplied here with 4 \alpha r_0^2 Z(Z+\eta(Z))
|
||||
crossSection = ComputeXSectionPerAtom(gammaEnergy, Z);
|
||||
// apply the constant factors:
|
||||
// - eta(Z) is a correction to account interaction in the field of e-
|
||||
// - gXSecFactor = 4 \alpha r_0^2
|
||||
const G4int iz = std::min(gMaxZet, G4lrint(Z));
|
||||
const G4double eta = gElementData[iz]->fEtaValue;
|
||||
crossSection *= gXSecFactor*Z*(Z+eta);
|
||||
// compute the atomic cross section either by using x-section parametrization
|
||||
// or by numerically integrationg the DCS (with or without LPM)
|
||||
if ( gammaEnergy < fParametrizedXSectionThreshold) {
|
||||
// using the parametrized cross sections (max up to 80 GeV)
|
||||
crossSection = ComputeParametrizedXSectionPerAtom(gammaEnergy, Z);
|
||||
} else {
|
||||
// by numerical integration of the DCS:
|
||||
// Computes the cross section with or without LPM suppression depending on
|
||||
// settings (by default with if the gamma energy is above a given threshold)
|
||||
// and using or not using complete sreening approximation (by default not).
|
||||
// Only the dependent part is computed in the numerical integration of the DCS
|
||||
// i.e. the result must be multiplied here with 4 \alpha r_0^2 Z(Z+\eta(Z))
|
||||
crossSection = ComputeXSectionPerAtom(gammaEnergy, Z);
|
||||
// apply the constant factors:
|
||||
// - eta(Z) is a correction to account interaction in the field of e-
|
||||
// - gXSecFactor = 4 \alpha r_0^2
|
||||
const G4int iz = std::min(gMaxZet, G4lrint(Z));
|
||||
const G4double eta = gElementData[iz]->fEtaValue;
|
||||
crossSection *= gXSecFactor*Z*(Z+eta);
|
||||
}
|
||||
// final protection
|
||||
return std::max(crossSection, 0.);
|
||||
}
|
||||
@@ -363,76 +378,88 @@ G4PairProductionRelModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fve
|
||||
// 'eps' is the total energy transferred to one of the e-/e+ pair in initial
|
||||
// gamma energy units Eg. Since the corresponding DCS is symmetric on eps=0.5,
|
||||
// the kinematical limits for eps0=mc^2/Eg <= eps <= 0.5
|
||||
//
|
||||
// The Coulomb factor for the target element (Z) (Eg>50 MeV is assumed)
|
||||
// F(Z) = 8*ln(Z)/3 + 8*fc(Z)
|
||||
//
|
||||
// The screening variable 'delta(eps)' = 136*Z^{-1/3}*eps0/[eps(1-eps)]
|
||||
// Due to the Coulomb correction, the DCS can go below zero even at
|
||||
// kinematicaly allowed eps > eps0 values. In order to exclude this eps
|
||||
// range with negative DCS, the minimum eps value will be set to eps_min =
|
||||
// max[eps0, epsp] with epsp is the solution of SF(delta(epsp)) - F(Z)/2 = 0
|
||||
// with SF being the screening function (SF1=SF2 at high value of delta).
|
||||
// The solution is epsp = 0.5 - 0.5*sqrt[ 1 - 4*136*Z^{-1/3}eps0/deltap]
|
||||
// with deltap = Exp[(42.038-F(Z))/8.29]-0.958. So the limits are:
|
||||
// - when eps=eps_max = 0.5 => delta_min = 136*Z^{-1/3}*eps0/4
|
||||
// - epsp = 0.5 - 0.5*sqrt[ 1 - delta_min/deltap]
|
||||
// - and eps_min = max[eps0, epsp]
|
||||
const G4int iZet = std::min(gMaxZet, anElement->GetZasInt());
|
||||
const G4double deltaFactor = gElementData[iZet]->fDeltaFactor*eps0;
|
||||
const G4double deltaMin = 4.*deltaFactor;
|
||||
const G4double deltaMax = gElementData[iZet]->fDeltaMax;
|
||||
// compute the limits of eps
|
||||
const G4double epsp = 0.5 - 0.5*std::sqrt(1. - deltaMin/deltaMax) ;
|
||||
const G4double epsMin = std::max(eps0,epsp);
|
||||
const G4double epsRange = 0.5 - epsMin;
|
||||
const G4double FZ = 8.*(gElementData[iZet]->fLogZ13 +
|
||||
gElementData[iZet]->fCoulomb);
|
||||
//
|
||||
// sample the energy rate (eps) of the created electron (or positron)
|
||||
G4double F10, F20;
|
||||
ScreenFunction12(deltaMin, F10, F20);
|
||||
F10 -= FZ;
|
||||
F20 -= FZ;
|
||||
const G4double NormF1 = std::max(F10 * epsRange * epsRange, 0.);
|
||||
const G4double NormF2 = std::max(1.5 * F20 , 0.);
|
||||
const G4double NormCond = NormF1/(NormF1 + NormF2);
|
||||
// check if LPM correction is active
|
||||
const G4bool isLPM = (fIsUseLPMCorrection && gammaEnergy>gEgLPMActivation);
|
||||
fLPMEnergy = mat->GetRadlen()*gLPMconstant;
|
||||
// we will need 3 uniform random number for each trial of sampling
|
||||
G4double rndmv[3];
|
||||
G4double greject = 0.;
|
||||
// 1. 'eps' is sampled uniformly on the [eps0, 0.5] inteval if Eg<Egsmall
|
||||
// 2. otherwise, on the [eps_min, 0.5] interval according to the DCS (case 2.)
|
||||
G4double eps;
|
||||
do {
|
||||
rndmEngine->flatArray(3, rndmv);
|
||||
if (NormCond > rndmv[0]) {
|
||||
eps = 0.5 - epsRange * fG4Calc->A13(rndmv[1]);
|
||||
const G4double delta = deltaFactor/(eps*(1.-eps));
|
||||
if (isLPM) {
|
||||
G4double lpmXiS, lpmGS, lpmPhiS, phi1, phi2;
|
||||
ComputePhi12(delta, phi1, phi2);
|
||||
ComputeLPMfunctions(lpmXiS, lpmGS, lpmPhiS, eps, gammaEnergy, iZet);
|
||||
greject = lpmXiS*((2.*lpmPhiS+lpmGS)*phi1-lpmGS*phi2-lpmPhiS*FZ)/F10;
|
||||
} else {
|
||||
greject = (ScreenFunction1(delta)-FZ)/F10;
|
||||
}
|
||||
} else {
|
||||
eps = epsMin + epsRange*rndmv[1];
|
||||
const G4double delta = deltaFactor/(eps*(1.-eps));
|
||||
if (isLPM) {
|
||||
G4double lpmXiS, lpmGS, lpmPhiS, phi1, phi2;
|
||||
ComputePhi12(delta, phi1, phi2);
|
||||
ComputeLPMfunctions(lpmXiS, lpmGS, lpmPhiS, eps, gammaEnergy, iZet);
|
||||
greject = lpmXiS*( (lpmPhiS+0.5*lpmGS)*phi1 + 0.5*lpmGS*phi2
|
||||
-0.5*(lpmGS+lpmPhiS)*FZ )/F20;
|
||||
} else {
|
||||
greject = (ScreenFunction2(delta)-FZ)/F20;
|
||||
}
|
||||
// case 1.
|
||||
static const G4double Egsmall = 2.*CLHEP::MeV;
|
||||
if (gammaEnergy < Egsmall) {
|
||||
eps = eps0 + (0.5-eps0)*rndmEngine->flat();
|
||||
} else {
|
||||
// case 2.
|
||||
// get the Coulomb factor for the target element (Z) and gamma energy (Eg)
|
||||
// F(Z) = 8*ln(Z)/3 if Eg <= 50 [MeV] => no Coulomb correction
|
||||
// F(Z) = 8*ln(Z)/3 + 8*fc(Z) if Eg > 50 [MeV] => fc(Z) is the Coulomb cor.
|
||||
//
|
||||
// The screening variable 'delta(eps)' = 136*Z^{-1/3}*eps0/[eps(1-eps)]
|
||||
// Due to the Coulomb correction, the DCS can go below zero even at
|
||||
// kinematicaly allowed eps > eps0 values. In order to exclude this eps
|
||||
// range with negative DCS, the minimum eps value will be set to eps_min =
|
||||
// max[eps0, epsp] with epsp is the solution of SF(delta(epsp)) - F(Z)/2 = 0
|
||||
// with SF being the screening function (SF1=SF2 at high value of delta).
|
||||
// The solution is epsp = 0.5 - 0.5*sqrt[ 1 - 4*136*Z^{-1/3}eps0/deltap]
|
||||
// with deltap = Exp[(42.038-F(Z))/8.29]-0.958. So the limits are:
|
||||
// - when eps=eps_max = 0.5 => delta_min = 136*Z^{-1/3}*eps0/4
|
||||
// - epsp = 0.5 - 0.5*sqrt[ 1 - delta_min/deltap]
|
||||
// - and eps_min = max[eps0, epsp]
|
||||
const G4int iZet = std::min(gMaxZet, anElement->GetZasInt());
|
||||
const G4double deltaFactor = gElementData[iZet]->fDeltaFactor*eps0;
|
||||
const G4double deltaMin = 4.*deltaFactor;
|
||||
G4double deltaMax = gElementData[iZet]->fDeltaMaxLow;
|
||||
G4double FZ = 8.*gElementData[iZet]->fLogZ13;
|
||||
if ( gammaEnergy > fCoulombCorrectionThreshold ) { // Eg > 50 MeV ?
|
||||
FZ += 8.*gElementData[iZet]->fCoulomb;
|
||||
deltaMax = gElementData[iZet]->fDeltaMaxHigh;
|
||||
}
|
||||
// Loop checking, 03-Aug-2015, Vladimir Ivanchenko
|
||||
} while (greject < rndmv[2]);
|
||||
// end of eps sampling
|
||||
// compute the limits of eps
|
||||
const G4double epsp = 0.5 - 0.5*std::sqrt(1. - deltaMin/deltaMax) ;
|
||||
const G4double epsMin = std::max(eps0,epsp);
|
||||
const G4double epsRange = 0.5 - epsMin;
|
||||
//
|
||||
// sample the energy rate (eps) of the created electron (or positron)
|
||||
G4double F10, F20;
|
||||
ScreenFunction12(deltaMin, F10, F20);
|
||||
F10 -= FZ;
|
||||
F20 -= FZ;
|
||||
const G4double NormF1 = std::max(F10 * epsRange * epsRange, 0.);
|
||||
const G4double NormF2 = std::max(1.5 * F20 , 0.);
|
||||
const G4double NormCond = NormF1/(NormF1 + NormF2);
|
||||
// check if LPM correction is active
|
||||
const G4bool isLPM = (fIsUseLPMCorrection && gammaEnergy>gEgLPMActivation);
|
||||
fLPMEnergy = mat->GetRadlen()*gLPMconstant;
|
||||
// we will need 3 uniform random number for each trial of sampling
|
||||
G4double rndmv[3];
|
||||
G4double greject = 0.;
|
||||
do {
|
||||
rndmEngine->flatArray(3, rndmv);
|
||||
if (NormCond > rndmv[0]) {
|
||||
eps = 0.5 - epsRange * fG4Calc->A13(rndmv[1]);
|
||||
const G4double delta = deltaFactor/(eps*(1.-eps));
|
||||
if (isLPM) {
|
||||
G4double lpmXiS, lpmGS, lpmPhiS, phi1, phi2;
|
||||
ComputePhi12(delta, phi1, phi2);
|
||||
ComputeLPMfunctions(lpmXiS, lpmGS, lpmPhiS, eps, gammaEnergy, iZet);
|
||||
greject = lpmXiS*((2.*lpmPhiS+lpmGS)*phi1-lpmGS*phi2-lpmPhiS*FZ)/F10;
|
||||
} else {
|
||||
greject = (ScreenFunction1(delta)-FZ)/F10;
|
||||
}
|
||||
} else {
|
||||
eps = epsMin + epsRange*rndmv[1];
|
||||
const G4double delta = deltaFactor/(eps*(1.-eps));
|
||||
if (isLPM) {
|
||||
G4double lpmXiS, lpmGS, lpmPhiS, phi1, phi2;
|
||||
ComputePhi12(delta, phi1, phi2);
|
||||
ComputeLPMfunctions(lpmXiS, lpmGS, lpmPhiS, eps, gammaEnergy, iZet);
|
||||
greject = lpmXiS*( (lpmPhiS+0.5*lpmGS)*phi1 + 0.5*lpmGS*phi2
|
||||
-0.5*(lpmGS+lpmPhiS)*FZ )/F20;
|
||||
} else {
|
||||
greject = (ScreenFunction2(delta)-FZ)/F20;
|
||||
}
|
||||
}
|
||||
// Loop checking, 03-Aug-2015, Vladimir Ivanchenko
|
||||
} while (greject < rndmv[2]);
|
||||
// end of eps sampling
|
||||
}
|
||||
//
|
||||
// select charges randomly
|
||||
G4double eTotEnergy, pTotEnergy;
|
||||
@@ -452,8 +479,7 @@ G4PairProductionRelModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fve
|
||||
G4ThreeVector eDirection, pDirection;
|
||||
//
|
||||
GetAngularDistribution()->SamplePairDirections(aDynamicGamma,
|
||||
eKinEnergy, pKinEnergy,
|
||||
eDirection, pDirection);
|
||||
eKinEnergy, pKinEnergy, eDirection, pDirection);
|
||||
// create G4DynamicParticle object for the particle1
|
||||
G4DynamicParticle* aParticle1= new G4DynamicParticle(
|
||||
fTheElectron,eDirection,eKinEnergy);
|
||||
@@ -486,7 +512,8 @@ void G4PairProductionRelModel::InitialiseElementData()
|
||||
const G4double logZ13 = elem->GetIonisation()->GetlogZ3();
|
||||
const G4double Z13 = elem->GetIonisation()->GetZ3();
|
||||
const G4double fc = elem->GetfCoulomb();
|
||||
const G4double FZ = 8.*(logZ13 + fc);
|
||||
const G4double FZLow = 8.*logZ13;
|
||||
const G4double FZHigh = 8.*(logZ13 + fc);
|
||||
G4double Fel;
|
||||
G4double Finel;
|
||||
if (iz<5) { // use data from Dirac-Fock atomic model
|
||||
@@ -501,7 +528,8 @@ void G4PairProductionRelModel::InitialiseElementData()
|
||||
elD->fCoulomb = fc;
|
||||
elD->fLradEl = Fel;
|
||||
elD->fDeltaFactor = 136./Z13;
|
||||
elD->fDeltaMax = G4Exp((42.038 - FZ)/8.29) - 0.958;
|
||||
elD->fDeltaMaxLow = G4Exp((42.038 - FZLow)/8.29) - 0.958;
|
||||
elD->fDeltaMaxHigh = G4Exp((42.038 - FZHigh)/8.29) - 0.958;
|
||||
elD->fEtaValue = Finel/(Fel-fc);
|
||||
elD->fLPMVarS1Cond = std::sqrt(2.)*Z13*Z13/(184.*184.);
|
||||
elD->fLPMILVarS1Cond = 1./G4Log(elD->fLPMVarS1Cond);
|
||||
@@ -611,3 +639,71 @@ void G4PairProductionRelModel::ComputeLPMfunctions(G4double &funcXiS,
|
||||
}
|
||||
}
|
||||
|
||||
// Calculates the microscopic cross section in GEANT4 internal units. Same as in
|
||||
// G4BetheHeitlerModel and should be used below 80 GeV since it start to deverge
|
||||
// from the cross section data above 80-90 GeV:
|
||||
// Parametrized formula (L. Urban) is used to estimate the atomic cross sections
|
||||
// given numerically in the table of [Hubbell, J. H., Heinz Albert Gimm, and I.
|
||||
// Overbo: "Pair, Triplet, and Total Atomic Cross Sections (and Mass Attenuation
|
||||
// Coefficients) for 1 MeV‐100 GeV Photons in Elements Z= 1 to 100." Journal of
|
||||
// physical and chemical reference data 9.4 (1980): 1023-1148.]
|
||||
//
|
||||
// The formula gives a good approximation of the data from 1.5 MeV to 100 GeV.
|
||||
// below 1.5 MeV: sigma=sigma(1.5MeV)*(GammaEnergy-2electronmass)
|
||||
// *(GammaEnergy-2electronmass)
|
||||
G4double
|
||||
G4PairProductionRelModel::ComputeParametrizedXSectionPerAtom(G4double gammaE,
|
||||
G4double Z)
|
||||
{
|
||||
G4double xSection = 0.0 ;
|
||||
// short versions
|
||||
static const G4double kMC2 = CLHEP::electron_mass_c2;
|
||||
// zero cross section below the kinematical limit: Eg<2mc^2
|
||||
if (Z < 0.9 || gammaE <= 2.0*kMC2) { return xSection; }
|
||||
//
|
||||
static const G4double gammaEnergyLimit = 1.5*CLHEP::MeV;
|
||||
// set coefficients a, b c
|
||||
static const G4double a0 = 8.7842e+2*CLHEP::microbarn;
|
||||
static const G4double a1 = -1.9625e+3*CLHEP::microbarn;
|
||||
static const G4double a2 = 1.2949e+3*CLHEP::microbarn;
|
||||
static const G4double a3 = -2.0028e+2*CLHEP::microbarn;
|
||||
static const G4double a4 = 1.2575e+1*CLHEP::microbarn;
|
||||
static const G4double a5 = -2.8333e-1*CLHEP::microbarn;
|
||||
|
||||
static const G4double b0 = -1.0342e+1*CLHEP::microbarn;
|
||||
static const G4double b1 = 1.7692e+1*CLHEP::microbarn;
|
||||
static const G4double b2 = -8.2381 *CLHEP::microbarn;
|
||||
static const G4double b3 = 1.3063 *CLHEP::microbarn;
|
||||
static const G4double b4 = -9.0815e-2*CLHEP::microbarn;
|
||||
static const G4double b5 = 2.3586e-3*CLHEP::microbarn;
|
||||
|
||||
static const G4double c0 = -4.5263e+2*CLHEP::microbarn;
|
||||
static const G4double c1 = 1.1161e+3*CLHEP::microbarn;
|
||||
static const G4double c2 = -8.6749e+2*CLHEP::microbarn;
|
||||
static const G4double c3 = 2.1773e+2*CLHEP::microbarn;
|
||||
static const G4double c4 = -2.0467e+1*CLHEP::microbarn;
|
||||
static const G4double c5 = 6.5372e-1*CLHEP::microbarn;
|
||||
// check low energy limit of the approximation (1.5 MeV)
|
||||
G4double gammaEnergyOrg = gammaE;
|
||||
if (gammaE < gammaEnergyLimit) { gammaE = gammaEnergyLimit; }
|
||||
// compute gamma energy variables
|
||||
const G4double x = G4Log(gammaE/kMC2);
|
||||
const G4double x2 = x *x;
|
||||
const G4double x3 = x2*x;
|
||||
const G4double x4 = x3*x;
|
||||
const G4double x5 = x4*x;
|
||||
//
|
||||
const G4double F1 = a0 + a1*x + a2*x2 + a3*x3 + a4*x4 + a5*x5;
|
||||
const G4double F2 = b0 + b1*x + b2*x2 + b3*x3 + b4*x4 + b5*x5;
|
||||
const G4double F3 = c0 + c1*x + c2*x2 + c3*x3 + c4*x4 + c5*x5;
|
||||
// compute the approximated cross section
|
||||
xSection = (Z + 1.)*(F1*Z + F2*Z*Z + F3);
|
||||
// check if we are below the limit of the approximation and apply correction
|
||||
if (gammaEnergyOrg < gammaEnergyLimit) {
|
||||
const G4double dum = (gammaEnergyOrg-2.*kMC2)/(gammaEnergyLimit-2.*kMC2);
|
||||
xSection *= dum*dum;
|
||||
}
|
||||
return xSection;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -333,7 +333,7 @@ void G4SBBremTable::InitSamplingTables() {
|
||||
|
||||
// should be called only from LoadSamplingTables(G4int) and once
|
||||
void G4SBBremTable::LoadSTGrid() {
|
||||
char* path = getenv("G4LEDATA");
|
||||
char* path = std::getenv("G4LEDATA");
|
||||
if (!path) {
|
||||
G4Exception("G4SBBremTable::LoadSTGrid()","em0006",
|
||||
FatalException, "Environment variable G4LEDATA not defined");
|
||||
@@ -391,7 +391,7 @@ void G4SBBremTable::LoadSamplingTables(G4int iz) {
|
||||
}
|
||||
// load data for a given Z only once
|
||||
iz = std::max(std::min(fMaxZet, iz),1);
|
||||
char* path = getenv("G4LEDATA");
|
||||
char* path = std::getenv("G4LEDATA");
|
||||
if (!path) {
|
||||
G4Exception("G4SBBremTable::LoadSamplingTables()","em0006",
|
||||
FatalException, "Environment variable G4LEDATA not defined");
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -23,7 +23,6 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class file
|
||||
@@ -40,11 +39,12 @@
|
||||
// Modifications:
|
||||
//
|
||||
// 24.07.2018 Introduced possibility to use sampling tables to sample the
|
||||
// emitted photon energy (instead of using rejectio) from the Seltzer-
|
||||
// Berger scalled DCS for bremsstrahlung photon emission. Using these
|
||||
// sampling tables option gives faster(30-70%) final state generation
|
||||
// than the original rejection but takes some extra memory (+ ~6MB in
|
||||
// the case of the full CMS detector). (M Novak)
|
||||
// emitted photon energy (instead of using rejectio) from the
|
||||
// Seltzer-Berger scalled DCS for bremsstrahlung photon emission.
|
||||
// Using these sampling tables option gives faster(30-70%) final
|
||||
// state generation than the original rejection but takes some
|
||||
// extra memory (+ ~6MB in the case of the full CMS detector).
|
||||
// (M Novak)
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
@@ -61,21 +61,32 @@
|
||||
#include "G4ModifiedTsai.hh"
|
||||
//#include "G4DipBustGenerator.hh"
|
||||
#include "G4EmParameters.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
|
||||
#include "G4Physics2DVector.hh"
|
||||
#include "G4Exp.hh"
|
||||
#include "G4Log.hh"
|
||||
|
||||
#include "G4ios.hh"
|
||||
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
G4Physics2DVector* G4SeltzerBergerModel::gSBDCSData[] = { nullptr };
|
||||
G4SBBremTable* G4SeltzerBergerModel::gSBSamplingTable = nullptr;
|
||||
G4double G4SeltzerBergerModel::gYLimitData[] = { 0.0 };
|
||||
G4String G4SeltzerBergerModel::gDataDirectory = "";
|
||||
|
||||
#ifdef G4MULTITHREADED
|
||||
G4Mutex G4SeltzerBergerModel::theSBMutex = G4MUTEX_INITIALIZER;
|
||||
#endif
|
||||
|
||||
static const G4double kMC2 = CLHEP::electron_mass_c2;
|
||||
static const G4double kAlpha = CLHEP::twopi*CLHEP::fine_structure_const;
|
||||
|
||||
G4SeltzerBergerModel::G4SeltzerBergerModel(const G4ParticleDefinition* p,
|
||||
const G4String& nam)
|
||||
const G4String& nam)
|
||||
: G4eBremsstrahlungRelModel(p,nam), fIsUseBicubicInterpolation(false),
|
||||
fIsUseSamplingTables(true), fNumWarnings(0), fIndx(0), fIndy(0)
|
||||
{
|
||||
@@ -83,7 +94,6 @@ G4SeltzerBergerModel::G4SeltzerBergerModel(const G4ParticleDefinition* p,
|
||||
SetLowEnergyLimit(fLowestKinEnergy);
|
||||
SetLPMFlag(false);
|
||||
SetAngularDistribution(new G4ModifiedTsai());
|
||||
//SetAngularDistribution(new G4DipBustGenerator());
|
||||
}
|
||||
|
||||
G4SeltzerBergerModel::~G4SeltzerBergerModel()
|
||||
@@ -104,7 +114,7 @@ G4SeltzerBergerModel::~G4SeltzerBergerModel()
|
||||
}
|
||||
|
||||
void G4SeltzerBergerModel::Initialise(const G4ParticleDefinition* p,
|
||||
const G4DataVector& cuts)
|
||||
const G4DataVector& cuts)
|
||||
{
|
||||
if (p) {
|
||||
SetParticle(p);
|
||||
@@ -112,17 +122,17 @@ void G4SeltzerBergerModel::Initialise(const G4ParticleDefinition* p,
|
||||
fIsUseSamplingTables = G4EmParameters::Instance()->EnableSamplingTable();
|
||||
// Access to elements
|
||||
if (IsMaster()) {
|
||||
// check environment variable
|
||||
// build the complete string identifying the file with the data set
|
||||
char* path = getenv("G4LEDATA");
|
||||
const G4ElementTable* theElemTable = G4Element::GetElementTable();
|
||||
size_t numOfElem = G4Element::GetNumberOfElements();
|
||||
for (size_t ie = 0; ie < numOfElem; ++ie) {
|
||||
G4int izet =
|
||||
std::max(1,std::min(((*theElemTable)[ie])->GetZasInt(), gMaxZet-1));
|
||||
// load SB-DCS data for this atomic number if it has not been loaded yet
|
||||
if (!gSBDCSData[izet]) {
|
||||
ReadData(izet, path);
|
||||
|
||||
auto theCoupleTable = G4ProductionCutsTable::GetProductionCutsTable();
|
||||
size_t numOfCouples = theCoupleTable->GetTableSize();
|
||||
for(size_t j=0; j<numOfCouples; ++j) {
|
||||
auto mat = theCoupleTable->GetMaterialCutsCouple(j)->GetMaterial();
|
||||
auto elmVec = mat->GetElementVector();
|
||||
size_t numOfElem = mat->GetNumberOfElements();
|
||||
for (size_t ie = 0; ie < numOfElem; ++ie) {
|
||||
G4int Z = std::max(1,std::min(((*elmVec)[ie])->GetZasInt(), gMaxZet-1));
|
||||
// load SB-DCS data for this atomic number if it has not been loaded yet
|
||||
InitialiseForElement(nullptr, Z);
|
||||
}
|
||||
}
|
||||
// elem.selectr. only for master: base class init-local will set for workers
|
||||
@@ -146,26 +156,32 @@ void G4SeltzerBergerModel::Initialise(const G4ParticleDefinition* p,
|
||||
}
|
||||
}
|
||||
|
||||
G4String G4SeltzerBergerModel::DirectoryPath() const {
|
||||
return "/brem_SB/br";
|
||||
}
|
||||
|
||||
void G4SeltzerBergerModel::ReadData(G4int izet, const char* path) {
|
||||
// return if it has been already loaded
|
||||
if (gSBDCSData[izet]) {
|
||||
return;
|
||||
}
|
||||
const char* datadir = path;
|
||||
if (!datadir) {
|
||||
datadir = getenv("G4LEDATA");
|
||||
if (!datadir) {
|
||||
G4Exception("G4SeltzerBergerModel::ReadData()","em0006",FatalException,
|
||||
const G4String& G4SeltzerBergerModel::FindDirectoryPath()
|
||||
{
|
||||
// check environment variable
|
||||
// build the complete string identifying the file with the data set
|
||||
if(gDataDirectory.empty()) {
|
||||
const char* path = std::getenv("G4LEDATA");
|
||||
if (path) {
|
||||
std::ostringstream ost;
|
||||
ost << path << "/brem_SB/br";
|
||||
gDataDirectory = ost.str();
|
||||
} else {
|
||||
G4Exception("G4SeltzerBergerModel::FindDirectoryPath()","em0006",
|
||||
FatalException,
|
||||
"Environment variable G4LEDATA not defined");
|
||||
return;
|
||||
}
|
||||
}
|
||||
return gDataDirectory;
|
||||
}
|
||||
|
||||
void G4SeltzerBergerModel::ReadData(G4int Z) {
|
||||
// return if it has been already loaded
|
||||
if (gSBDCSData[Z]) {
|
||||
return;
|
||||
}
|
||||
std::ostringstream ost;
|
||||
ost << datadir << DirectoryPath() << izet;
|
||||
ost << FindDirectoryPath() << Z;
|
||||
std::ifstream fin(ost.str().c_str());
|
||||
if (!fin.is_open()) {
|
||||
G4ExceptionDescription ed;
|
||||
@@ -180,9 +196,9 @@ void G4SeltzerBergerModel::ReadData(G4int izet, const char* path) {
|
||||
G4Physics2DVector* v = new G4Physics2DVector();
|
||||
if (v->Retrieve(fin)) {
|
||||
v->SetBicubicInterpolation(fIsUseBicubicInterpolation);
|
||||
gSBDCSData[izet] = v;
|
||||
static const G4double emaxlog = 4*G4Log(10.);
|
||||
gYLimitData[izet] = v->Value(0.97, emaxlog, fIndx, fIndy);
|
||||
gYLimitData[Z] = v->Value(0.97, emaxlog, fIndx, fIndy);
|
||||
gSBDCSData[Z] = v;
|
||||
} else {
|
||||
G4ExceptionDescription ed;
|
||||
ed << "Bremsstrahlung data file <" << ost.str().c_str()
|
||||
@@ -191,13 +207,10 @@ void G4SeltzerBergerModel::ReadData(G4int izet, const char* path) {
|
||||
ed,"G4LEDATA version should be G4EMLOW6.23 or later.");
|
||||
delete v;
|
||||
}
|
||||
// G4cout << dataSB[Z] << G4endl;
|
||||
}
|
||||
|
||||
G4double G4SeltzerBergerModel::ComputeDXSectionPerAtom(G4double gammaEnergy)
|
||||
{
|
||||
static const G4double kMC2 = CLHEP::electron_mass_c2;
|
||||
static const G4double kAlpha = CLHEP::twopi*CLHEP::fine_structure_const;
|
||||
G4double dxsec = 0.0;
|
||||
if (gammaEnergy < 0.0 || fPrimaryKinEnergy <= 0.0) {
|
||||
return dxsec;
|
||||
@@ -212,14 +225,6 @@ G4double G4SeltzerBergerModel::ComputeDXSectionPerAtom(G4double gammaEnergy)
|
||||
if (!gSBDCSData[fCurrentIZ]) {
|
||||
InitialiseForElement(nullptr, fCurrentIZ);
|
||||
}
|
||||
/*
|
||||
G4ExceptionDescription ed;
|
||||
ed << "Bremsstrahlung data for Z= " << Z
|
||||
<< " are not initialized!";
|
||||
G4Exception("G4SeltzerBergerModel::ComputeDXSectionPerAtom()","em0005",
|
||||
FatalException, ed,
|
||||
"G4LEDATA version should be G4EMLOW6.23 or later.");
|
||||
*/
|
||||
// NOTE: SetupForMaterial should have been called before!
|
||||
const G4double pt2 = fPrimaryKinEnergy*(fPrimaryKinEnergy+2.*kMC2);
|
||||
const G4double invb2 = fPrimaryTotalEnergy*fPrimaryTotalEnergy/pt2;
|
||||
@@ -251,7 +256,6 @@ G4SeltzerBergerModel::SampleSecondaries(std::vector<G4DynamicParticle*>* vdp,
|
||||
G4double cutEnergy,
|
||||
G4double maxEnergy)
|
||||
{
|
||||
static const G4double kMC2 = CLHEP::electron_mass_c2;
|
||||
const G4double kinEnergy = dp->GetKineticEnergy();
|
||||
const G4double logKinEnergy = dp->GetLogKineticEnergy();
|
||||
const G4double tmin = std::min(cutEnergy, kinEnergy);
|
||||
@@ -292,7 +296,8 @@ G4SeltzerBergerModel::SampleSecondaries(std::vector<G4DynamicParticle*>* vdp,
|
||||
vdp->push_back(gamma);
|
||||
//
|
||||
// compute post-interaction kinematics of the primary e-/e+
|
||||
G4ThreeVector dir = (totMomentum*dp->GetMomentumDirection()-gammaEnergy*gamDir).unit();
|
||||
G4ThreeVector dir =
|
||||
(totMomentum*dp->GetMomentumDirection()-gammaEnergy*gamDir).unit();
|
||||
const G4double finalE = kinEnergy - gammaEnergy;
|
||||
/*
|
||||
G4cout << "### G4SBModel: v= "
|
||||
@@ -323,8 +328,6 @@ G4SeltzerBergerModel::SampleEnergyTransfer(const G4double kinEnergy,
|
||||
const G4double tmin,
|
||||
const G4double tmax)
|
||||
{
|
||||
static const G4double kMC2 = CLHEP::electron_mass_c2;
|
||||
static const G4double kAlpha = CLHEP::twopi*CLHEP::fine_structure_const;
|
||||
// min max of the transformed variable: x(k) = ln(k^2+k_p^2) that is in
|
||||
// [ln(k_c^2+k_p^2), ln(E_k^2+k_p^2)]
|
||||
const G4double xmin = G4Log(tmin*tmin+fDensityCorr);
|
||||
@@ -333,24 +336,19 @@ G4SeltzerBergerModel::SampleEnergyTransfer(const G4double kinEnergy,
|
||||
// majoranta
|
||||
const G4double x0 = tmin/kinEnergy;
|
||||
G4double vmax;
|
||||
if (fCurrentIZ < 93) {
|
||||
vmax = gSBDCSData[fCurrentIZ]->Value(x0, y, fIndx, fIndy)*1.02;
|
||||
} else {
|
||||
// reset cashed x and y indices
|
||||
fIndx = 0;
|
||||
fIndy = 0;
|
||||
vmax = gSBDCSData[fCurrentIZ]->Value(x0, y, fIndx, fIndy)*1.2;
|
||||
if (!gSBDCSData[fCurrentIZ]) {
|
||||
InitialiseForElement(nullptr, fCurrentIZ);
|
||||
}
|
||||
vmax = gSBDCSData[fCurrentIZ]->Value(x0, y, fIndx, fIndy)*1.02;
|
||||
//
|
||||
static const G4double kEPeakLim = 300.*CLHEP::MeV;
|
||||
static const G4double kELowLim = 20.*CLHEP::keV;
|
||||
// majoranta corrected for e-
|
||||
if (fIsElectron && x0 < 0.97 && ((kinEnergy>kEPeakLim) || (kinEnergy<kELowLim))) {
|
||||
const G4double ylim = std::min(gYLimitData[fCurrentIZ],
|
||||
if (fIsElectron && x0 < 0.97 &&
|
||||
((kinEnergy>kEPeakLim) || (kinEnergy<kELowLim))) {
|
||||
G4double ylim = std::min(gYLimitData[fCurrentIZ],
|
||||
1.1*gSBDCSData[fCurrentIZ]->Value(0.97,y,fIndx,fIndy));
|
||||
if (ylim > vmax) {
|
||||
vmax = ylim;
|
||||
}
|
||||
vmax = std::max(vmax, ylim);
|
||||
}
|
||||
if (x0 < 0.05) {
|
||||
vmax *= 1.2;
|
||||
@@ -363,7 +361,8 @@ G4SeltzerBergerModel::SampleEnergyTransfer(const G4double kinEnergy,
|
||||
G4double gammaEnergy, v;
|
||||
for (G4int nn = 0; nn < kNCountMax; ++nn) {
|
||||
rndmEngine->flatArray(2, rndm);
|
||||
gammaEnergy = std::sqrt(std::max(G4Exp(xmin + rndm[0]*xrange)-fDensityCorr,0.));
|
||||
gammaEnergy =
|
||||
std::sqrt(std::max(G4Exp(xmin + rndm[0]*xrange)-fDensityCorr,0.));
|
||||
v = gSBDCSData[fCurrentIZ]->Value(gammaEnergy/kinEnergy, y, fIndx, fIndy);
|
||||
// e+ correction
|
||||
if (!fIsElectron) {
|
||||
@@ -401,21 +400,25 @@ G4SeltzerBergerModel::SampleEnergyTransfer(const G4double kinEnergy,
|
||||
return gammaEnergy;
|
||||
}
|
||||
|
||||
#include "G4AutoLock.hh"
|
||||
namespace { G4Mutex SeltzerBergerModel1Mutex = G4MUTEX_INITIALIZER; }
|
||||
void G4SeltzerBergerModel::InitialiseForElement(const G4ParticleDefinition*,
|
||||
G4int izet)
|
||||
G4int Z)
|
||||
{
|
||||
G4AutoLock l(&SeltzerBergerModel1Mutex);
|
||||
// G4cout << "G4SeltzerBergerModel::InitialiseForElement Z= " << Z << G4endl;
|
||||
if (!gSBDCSData[izet]) {
|
||||
ReadData(izet);
|
||||
}
|
||||
if (!gSBDCSData[Z]) {
|
||||
#ifdef G4MULTITHREADED
|
||||
G4MUTEXLOCK(&theSBMutex);
|
||||
if (!gSBDCSData[Z]) {
|
||||
#endif
|
||||
ReadData(Z);
|
||||
#ifdef G4MULTITHREADED
|
||||
}
|
||||
G4MUTEXUNLOCK(&theSBMutex);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void G4SeltzerBergerModel::SetupForMaterial(const G4ParticleDefinition*,
|
||||
const G4Material* mat,
|
||||
G4double kineticEnergy)
|
||||
const G4Material* mat,
|
||||
G4double kineticEnergy)
|
||||
{
|
||||
fDensityFactor = gMigdalConstant*mat->GetElectronDensity();
|
||||
// calculate threshold for density effect: gamma*k_p = sqrt(fDensityCorr)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -123,16 +123,15 @@ void G4WentzelOKandVIxSection::Initialise(const G4ParticleDefinition* p,
|
||||
|
||||
// cosThetaMax is below 1.0 only when MSC is combined with SS
|
||||
if(isCombined) { cosThetaMax = cosThetaLim; }
|
||||
|
||||
G4double a = G4EmParameters::Instance()->FactorForAngleLimit()
|
||||
*CLHEP::hbarc/CLHEP::fermi;
|
||||
G4EmParameters* param = G4EmParameters::Instance();
|
||||
G4double a = param->FactorForAngleLimit()*CLHEP::hbarc/CLHEP::fermi;
|
||||
factorA2 = 0.5*a*a;
|
||||
currentMaterial = nullptr;
|
||||
|
||||
fNucFormfactor = G4EmParameters::Instance()->NuclearFormfactorType();
|
||||
fNucFormfactor = param->NuclearFormfactorType();
|
||||
if(0.0 == ScreenRSquare[0]) { InitialiseA(); }
|
||||
|
||||
// Mott corrections
|
||||
// Mott corrections always added
|
||||
if((p == theElectron || p == thePositron) && !fMottXSection) {
|
||||
fMottXSection = new G4ScreeningMottCrossSection();
|
||||
fMottXSection->Initialise(p, 1.0);
|
||||
@@ -158,7 +157,7 @@ void G4WentzelOKandVIxSection::InitialiseA()
|
||||
G4double constn = 6.937e-6/(MeV*MeV);
|
||||
G4double fct = G4EmParameters::Instance()->ScreeningFactor();
|
||||
|
||||
G4double afact = fct*0.5*alpha2*a0*a0;
|
||||
G4double afact = 0.5*fct*alpha2*a0*a0;
|
||||
ScreenRSquare[0] = afact;
|
||||
ScreenRSquare[1] = afact;
|
||||
ScreenRSquareElec[1] = afact;
|
||||
@@ -388,14 +387,14 @@ G4WentzelOKandVIxSection::SampleSingleScattering(G4double cosTMin,
|
||||
}
|
||||
G4double grej;
|
||||
if(fMottXSection) {
|
||||
fMottXSection->SetupKinematic(tkin, (G4double)targetZ);
|
||||
fMottXSection->SetupKinematic(tkin, targetZ);
|
||||
grej = fMottXSection->RatioMottRutherfordCosT(std::sqrt(z1))*fm*fm;
|
||||
} else {
|
||||
grej = (1. - z1*factB + factB1*targetZ*sqrt(z1*factB)*(2. - z1))
|
||||
*fm*fm/(1.0 + z1*factD);
|
||||
}
|
||||
//G4cout << "SampleSingleScattering: E= " << tkin << " z1= "
|
||||
// << z1 << " grej= " << grej << G4endl;
|
||||
// G4cout << "SampleSingleScattering: E= " << tkin << " z1= "
|
||||
// << z1 << " grej= "<< grej << " mottFact= "<< fMottFactor<< G4endl;
|
||||
if(fMottFactor*rndmEngineMod->flat() <= grej ) {
|
||||
// exclude "false" scattering due to formfactor and spin effect
|
||||
G4double cost = 1.0 - z1;
|
||||
|
||||
@@ -124,6 +124,7 @@ void G4WentzelVIModel::Initialise(const G4ParticleDefinition* p,
|
||||
{
|
||||
// reset parameters
|
||||
SetupParticle(p);
|
||||
InitialiseParameters(p);
|
||||
currentRange = 0.0;
|
||||
|
||||
if(isCombined) {
|
||||
|
||||
@@ -59,8 +59,6 @@
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
#include "G4NucleiProperties.hh"
|
||||
#include "G4Pow.hh"
|
||||
#include "G4LossTableManager.hh"
|
||||
#include "G4LossTableBuilder.hh"
|
||||
#include "G4NistManager.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -94,13 +94,15 @@ G4eSingleCoulombScatteringModel::G4eSingleCoulombScatteringModel(const G4String&
|
||||
currentMaterialIndex = -1;
|
||||
|
||||
Mottcross = new G4ScreeningMottCrossSection();
|
||||
//G4cout <<"## G4eSingleCoulombScatteringModel: " << this << " " << Mottcross << G4endl;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4eSingleCoulombScatteringModel::~G4eSingleCoulombScatteringModel()
|
||||
{
|
||||
delete Mottcross;
|
||||
//G4cout <<"## G4eSingleCoulombScatteringModel: delete " << this << " " << Mottcross << G4endl;
|
||||
delete Mottcross;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -168,7 +168,7 @@ G4VParticleChange* G4eplusAnnihilation::AtRestDoIt(const G4Track& track,
|
||||
G4Track* t = new G4Track(dp, time, track.GetPosition());
|
||||
t->SetTouchableHandle(track.GetTouchableHandle());
|
||||
if (biasManager) {
|
||||
t->SetWeight(biasManager->GetWeight(i));
|
||||
t->SetWeight(weight * biasManager->GetWeight(i));
|
||||
} else {
|
||||
t->SetWeight(weight);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class file
|
||||
@@ -58,8 +57,6 @@
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
#include "G4NucleiProperties.hh"
|
||||
#include "G4Pow.hh"
|
||||
#include "G4LossTableManager.hh"
|
||||
#include "G4LossTableBuilder.hh"
|
||||
#include "G4NistManager.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
Reference in New Issue
Block a user