Import Geant4 10.7.0.beta source tree

This commit is contained in:
Gabriele Cosmo
2020-06-26 10:23:25 +02:00
parent c02c370437
commit 67ba86d073
1871 changed files with 174422 additions and 131884 deletions
@@ -115,94 +115,95 @@ G4double G4LindhardSorensenData::ComputeDeltaL(G4int idx, G4double x) const
void G4LindhardSorensenData::InitialiseData()
{
xmin = G4Log(0.02);
xmax = 2.5*g4calc->logZ(10);
xmax = G4Log(316.22777);
const G4double lsdata[9][NPOINT] = {
{0.0036181621,
0.0042618872, 0.0040786701, 0.0039097273, 0.0041240731, 0.0044311195, // 1-5
0.0059858073, 0.0079655897, 0.0089669217, 0.010091248, 0.0096319233, // 6-10
0.0085344428, 0.0087326058, 0.009780094, 0.010617094, 0.011277997, // 11-15
0.01185287, 0.012242278, 0.012507042, 0.012369698, 0.012202436, // 16-20
0.012016446, 0.011793182, 0.011612196, 0.011375017, 0.010624408, // 21-25
0.0096685612, 0.0093765113, 0.0091152632, 0.0087458522, 0.0082645153, // 26-30
0.0068625676, 0.0046558921, 0.0021660968, -0.00072760644, -0.0062653709,// 31-35
-0.015834368, -0.03224412, -0.062296044, -0.10327705, -0.16545368},
{-0.024837796,
-0.018943357, -0.013251703, -0.007646936, -0.003751624, 7.4932758e-05, // 1-5
0.0027996278, 0.0057534909, 0.0078441157, 0.010341958, 0.012419648, // 5-10
0.01491866, 0.016403769, 0.018106955, 0.019249728, 0.020704966, // 11-15
0.021636244, 0.022526456, 0.023429501, 0.024251631, 0.024727856, // 15-20
0.024997337, 0.025225657, 0.025335138, 0.025474553, 0.025306356, // 21-25
0.025048151, 0.02467553, 0.02416496, 0.023519917, 0.022699646, // 25-30
0.020902526, 0.017645158, 0.013219058, 0.0059989118, -0.0042559395, // 31-35
-0.020223315, -0.044480728, -0.074942757, -0.11185084, -0.15264337},
{-0.04948514,
-0.039259418, -0.029641846, -0.022112859, -0.0152972, -0.0077213168, // 1-5
-0.0031032447, 0.0023506153, 0.0058573025, 0.0097554723, 0.012692892, // 5-10
0.016404575, 0.018642388, 0.021492082, 0.023328047, 0.025358859, // 11-15
0.026839018, 0.028169751, 0.029240668, 0.030035325, 0.030689491, // 15-20
0.031113343, 0.031518392, 0.031657748, 0.031794607, 0.031672646, // 21-25
0.031507453, 0.031024952, 0.030410522, 0.029266343, 0.027729316, // 25-30
0.025132583, 0.02141173, 0.016127626, 0.008039769, -0.0046793613, // 31-35
-0.02196456, -0.043877567, -0.070852217, -0.09979099, -0.13187648},
{-0.07502957,
-0.063927817, -0.053895181, -0.043621797, -0.033329203, -0.024765223, // 1-5
-0.015996122, -0.0084995741, -0.00017499271, 0.0064195209, 0.01117532,// 5-10
0.016956954, 0.02155737, 0.025213602, 0.029869549, 0.031980316, // 11-15
0.034664781, 0.036995048, 0.038244843, 0.039836367, 0.040930356, // 15-20
0.041677336, 0.042211864, 0.042472572, 0.042617755, 0.042393662, // 21-25
0.042049893, 0.041341375, 0.040408112, 0.03867031, 0.036457345, // 25-30
0.032742289, 0.027897265, 0.020305954, 0.0099602019, -0.0036658833, // 31-35
-0.020344557, -0.039700638, -0.059781744, -0.080649004, -0.10263347},
{-0.081885964,
-0.072049323, -0.06299877, -0.053400445, -0.043830227, -0.03415406, // 1-5
-0.024723298, -0.015706543, -0.0070305988, 0.0016621818, 0.0093560784, // 5-10
0.017338568, 0.023286722, 0.028930541, 0.034048359, 0.037750635, // 11-15
0.041512165, 0.04362858, 0.046323682, 0.048044285, 0.049379817, // 15-20
0.050501289, 0.050963981, 0.051463496, 0.051292532, 0.051074821, // 21-25
0.050350498, 0.049370817, 0.047660517, 0.045247985, 0.04188952, // 25-30
0.037009647, 0.030171627, 0.021186013, 0.0092064517, -0.0051358689, // 31-35
-0.01977885, -0.036354277, -0.053187271, -0.069851489, -0.087776477},
{-0.083068958,
-0.074302116, -0.065040071, -0.056500699, -0.047189921, -0.03781489, // 1-5
-0.028666422, -0.0192974, -0.0097949279, -0.0011649946, 0.0071301285, // 5-10
0.01548354, 0.023483416, 0.030515545, 0.036162102, 0.040602642, // 11-15
0.045011738, 0.048259036, 0.051136495, 0.053524791, 0.054971064, // 15-20
0.056247898, 0.056729496, 0.057135059, 0.056923775, 0.05657171, // 21-25
0.055504504, 0.054134086, 0.051812977, 0.048857213, 0.044525663, // 25-30
0.038593442, 0.03027527, 0.020452704, 0.0082978722, -0.0045556908, // 31-35
-0.018750622, -0.033642805, -0.048788529, -0.064509221, -0.080215679},
{-0.083061344,
-0.075180377, -0.066735793, -0.059067728, -0.049303999, -0.040618218, // 1-5
-0.031608369, -0.022553882, -0.012699373, -0.0033434259, 0.0051129584, // 5-10
0.013817276, 0.023132109, 0.030886148, 0.037688311, 0.043478106, // 11-15
0.048602814, 0.052502168, 0.055969817, 0.058142903, 0.060860174, // 15-20
0.061732795, 0.062844014, 0.062911637, 0.06278651, 0.061898673, // 21-25
0.060500452, 0.058323088, 0.055297604, 0.051242701, 0.04596475, // 25-30
0.038863441, 0.030302781, 0.019055839, 0.0072837125, -0.0047516889, // 31-35
-0.017733076, -0.031547911, -0.04523347, -0.059727542, -0.074202114},
{-0.082449782,
-0.07492693, -0.067041495, -0.059614338, -0.051061455, -0.042587329, // 1-5
-0.034242658, -0.025296495, -0.016157818, -0.0064198954, 0.0033148315, // 5-10
0.012927383, 0.021914897, 0.03053429, 0.03854699, 0.045293871, // 11-15
0.05141546, 0.056473799, 0.060050334, 0.063292547, 0.065215264, // 15-20
0.066961692, 0.067369593, 0.067623539, 0.066825274, 0.065740573, // 21-25
0.063673411, 0.061033708, 0.057399807, 0.052544441, 0.04583072, // 25-30
0.037931379, 0.028569029, 0.017544895, 0.0068751554, -0.0038105519, // 31-35
-0.015233268, -0.026956839, -0.038981068, -0.05091927, -0.064344384},
{-0.081232852,
-0.074976912, -0.068421001, -0.060951614, -0.053624488, -0.045755024, // 1-5
-0.037708151, -0.029246587, -0.02018635, -0.01073862, -0.00085387172, // 5-10
0.0090831897, 0.018970381, 0.02761289, 0.036215831, 0.044355404, // 11-15
0.051067631, 0.057143777, 0.061348214, 0.065462308, 0.06715594, // 15-20
0.069155687, 0.069845259, 0.069828188, 0.069170195, 0.067585183, // 21-25
0.065486015, 0.062437523, 0.058111347, 0.052410482, 0.045597673, // 25-30
0.037571853, 0.028019555, 0.016564385, 0.0060254421, -0.0043254115, // 31-35
-0.015675051, -0.027353574, -0.03931666, -0.050325729, -0.06174447}};
{0.0036181621,
0.0042618872, 0.0040786701, 0.0039097273, 0.0041240731, 0.0044311195, // 0-5
0.0059858073, 0.0079655897, 0.0089669217, 0.010091248, 0.0096319233, // 5-10
0.0085344428, 0.0087326058, 0.009780094, 0.010617094, 0.011277997, // 10-15
0.01185287, 0.012242278, 0.012507042, 0.012369698, 0.012202436, // 15-20
0.012016446, 0.011793182, 0.011612196, 0.011375017, 0.010624408, // 20-25
0.0096685612, 0.0093765113, 0.0091152632, 0.0087458522, 0.0082645153, // 25-30
0.0068625676, 0.0046558921, 0.0021660968, -0.00072760644, -0.0062653709,// 30-35
-0.015834368, -0.03224412, -0.062296044, -0.10327705, -0.16545368},
{-0.024837796,
-0.018943357, -0.013251703, -0.007646936, -0.003751624, 7.4932758e-05, // 0-5
0.0027996278, 0.0057534909, 0.0078441157, 0.010341958, 0.012419648, // 5-10
0.01491866, 0.016403769, 0.018106955, 0.019249728, 0.020704966, // 10-15
0.021636244, 0.022526456, 0.023429501, 0.024251631, 0.024727856, // 15-20
0.024997337, 0.025225657, 0.025335138, 0.025474553, 0.025306356, // 20-25
0.025048151, 0.02467553, 0.02416496, 0.023519917, 0.022699646, // 25-30
0.020902526, 0.017645158, 0.013219058, 0.0059989118, -0.0042559395, // 30-35
-0.020223315, -0.044480728, -0.074942757, -0.1108863, -0.15439805},
{-0.04948514,
-0.039259418, -0.029641846, -0.022112859, -0.0152972, -0.0077213168, // 0-5
-0.0031032447, 0.0023506153, 0.0058573025, 0.0097554723, 0.012692892, // 5-10
0.016404575, 0.018642388, 0.021492082, 0.023328047, 0.025358859, // 10-15
0.026839018, 0.028169751, 0.029240668, 0.030035325, 0.030689491, // 15-20
0.031113343, 0.031518392, 0.031657748, 0.031794607, 0.031672646, // 20-25
0.031507453, 0.031024952, 0.030410522, 0.029266343, 0.027729316, // 25-30
0.025132583, 0.02141173, 0.016127626, 0.008039769, -0.0046793613, // 30-35
-0.02196456, -0.043877567, -0.070852217, -0.09979099, -0.13187648},
{-0.07502957,
-0.063927817, -0.053895181, -0.043621797, -0.033329203, -0.024765223, // 0-5
-0.015996122, -0.0084995741, -0.00017499271, 0.0064195209, 0.01117532,// 5-10
0.016956954, 0.02155737, 0.025213602, 0.029869549, 0.031980316, // 10-15
0.034664781, 0.036995048, 0.038244843, 0.039836367, 0.040930356, // 15-20
0.041677336, 0.042211864, 0.042472572, 0.042617755, 0.042393662, // 20-25
0.042049893, 0.041341375, 0.040408112, 0.03867031, 0.036457345, // 25-30
0.032742289, 0.027897265, 0.020305954, 0.0099602019, -0.0036658833, // 30-35
-0.020344557, -0.039700638, -0.059781744, -0.080649004, -0.10263347},
{-0.081885964,
-0.072049323, -0.06299877, -0.053400445, -0.043830227, -0.03415406, // 0-5
-0.024723298, -0.015706543, -0.0070305988, 0.0016621818, 0.0093560784, // 5-10
0.017338568, 0.023286722, 0.028930541, 0.034048359, 0.037750635, // 10-15
0.041512165, 0.04362858, 0.046323682, 0.048044285, 0.049379817, // 15-20
0.050501289, 0.050963981, 0.051463496, 0.051292532, 0.051074821, // 20-25
0.050350498, 0.049370817, 0.047660517, 0.045247985, 0.04188952, // 25-30
0.037009647, 0.030171627, 0.021186013, 0.0092064517, -0.0051358689, // 30-35
-0.01977885, -0.036354277, -0.053187271, -0.069851489, -0.087776477},
{-0.083068958,
-0.074302116, -0.065040071, -0.056500699, -0.047189921, -0.03781489, // 0-5
-0.028666422, -0.0192974, -0.0097949279, -0.0011649946, 0.0071301285, // 5-10
0.01548354, 0.023483416, 0.030515545, 0.036162102, 0.040602642, // 10-15
0.045011738, 0.048259036, 0.051136495, 0.053524791, 0.054971064, // 15-20
0.056247898, 0.056729496, 0.057135059, 0.056923775, 0.05657171, // 20-25
0.055504504, 0.054134086, 0.051812977, 0.048857213, 0.044525663, // 25-30
0.038593442, 0.03027527, 0.020452704, 0.0082978722, -0.0045556908, // 30-35
-0.018750622, -0.033642805, -0.048788529, -0.064509221, -0.080215679},
{-0.083061344,
-0.075180377, -0.066630961, -0.058114277, -0.049303999, -0.040618218, // 0-5
-0.031608369, -0.022553882, -0.012699373, -0.0033434259, 0.0051129584, // 5-10
0.013817276, 0.023132109, 0.030886148, 0.037688311, 0.043478106, // 10-15
0.048602814, 0.052502168, 0.055969817, 0.058142903, 0.060860174, // 15-20
0.061732795, 0.062844014, 0.062911637, 0.06278651, 0.061898673, // 20-25
0.060500452, 0.058323088, 0.055297604, 0.051242701, 0.04596475, // 25-30
0.038863441, 0.030302781, 0.019055839, 0.0072837125, -0.0047516889, // 30-35
-0.017733076, -0.031547911, -0.04523347, -0.059727542, -0.074202114},
{-0.082449782,
-0.07492693, -0.067041495, -0.059614338, -0.051061455, -0.042587329, // 0-5
-0.034242658, -0.025296495, -0.016157818, -0.0064198954, 0.0033148315, // 5-10
0.012927383, 0.021914897, 0.03053429, 0.03854699, 0.045293871, // 10-15
0.05141546, 0.056473799, 0.060050334, 0.063292547, 0.065215264, // 15-20
0.066961692, 0.067369593, 0.067623539, 0.066825274, 0.065740573, // 20-25
0.063673411, 0.061033708, 0.057399807, 0.052544441, 0.04583072, // 25-30
0.037931379, 0.028569029, 0.017544895, 0.0068751554, -0.0038105519, // 30-35
-0.015233268, -0.026956839, -0.038975048, -0.051387898, -0.064344384},
{-0.081232852,
-0.074976912, -0.068421001, -0.060951614, -0.053624488, -0.045755024, // 0-5
-0.037708151, -0.029246587, -0.02018635, -0.01073862, -0.00085387172, // 5-10
0.0090831897, 0.018970381, 0.02761289, 0.036215831, 0.044355404, // 10-15
0.051067631, 0.057143777, 0.061348214, 0.065462308, 0.06715594, // 15-20
0.069155687, 0.069845259, 0.069828188, 0.069170195, 0.067585183, // 20-25
0.065486015, 0.062437523, 0.058111347, 0.052410482, 0.045597673, // 25-30
0.037571853, 0.028019555, 0.016564385, 0.0060254421, -0.0043254115, // 30-35
-0.015675051, -0.027353574, -0.03931666, -0.050325729, -0.06174447}};
for(G4int i=0; i<=LVECT; ++i) {
data[i] = new G4PhysicsLinearVector(xmin, xmax, NPOINT-1);
for(size_t j=0; j<NPOINT; ++j) {
data[i]->SetSpline(true);
for(std::size_t j=0; j<NPOINT; ++j) {
data[i]->PutValue(j, lsdata[i][j]);
}
}
@@ -64,9 +64,9 @@ G4UniversalFluctuation::G4UniversalFluctuation(const G4String& nam)
particle(nullptr),
minNumberInteractionsBohr(10.0),
minLoss(10.*eV),
nmaxCont(16.),
nmaxCont(8.),
rate(0.56),
a0(50.),
a0(42),
fw(4.00)
{
lastMaterial = nullptr;
@@ -116,19 +116,19 @@ G4UniversalFluctuation::SampleFluctuations(const G4MaterialCutsCouple* couple,
// shortcut for very small loss or from a step nearly equal to the range
// (out of validity of the model)
//
if (averageLoss < minLoss) { return averageLoss; }
G4double meanLoss = averageLoss;
G4double tkin = dp->GetKineticEnergy();
const G4double tkin = dp->GetKineticEnergy();
//G4cout<< "Emean= "<< meanLoss<< " tmax= "<< tmax<< " L= "<<length<<G4endl;
if (meanLoss < minLoss) { return meanLoss; }
if(dp->GetDefinition() != particle) { InitialiseMe(dp->GetDefinition()); }
CLHEP::HepRandomEngine* rndmEngineF = G4Random::getTheEngine();
G4double tau = tkin * m_Inv_particleMass;
G4double gam = tau + 1.0;
G4double gam2 = gam*gam;
G4double beta2 = tau*(tau + 2.0)/gam2;
const G4double gam = tkin * m_Inv_particleMass + 1.0;
const G4double gam2 = gam*gam;
const G4double beta = dp->GetBeta();
const G4double beta2 = beta*beta;
G4double loss(0.), siga(0.);
@@ -149,12 +149,12 @@ G4UniversalFluctuation::SampleFluctuations(const G4MaterialCutsCouple* couple,
siga = sqrt((1.0/beta2 - 0.5) * twopi_mc2_rcl2 * tmax * length
* electronDensity * chargeSquare);
G4double sn = meanLoss/siga;
const G4double sn = meanLoss/siga;
// thick target case
if (sn >= 2.0) {
G4double twomeanLoss = meanLoss + meanLoss;
const G4double twomeanLoss = meanLoss + meanLoss;
do {
loss = G4RandGauss::shoot(rndmEngineF,meanLoss,siga);
// Loop checking, 03-Aug-2015, Vladimir Ivanchenko
@@ -191,7 +191,7 @@ G4UniversalFluctuation::SampleFluctuations(const G4MaterialCutsCouple* couple,
if(tmax <= e0) { return meanLoss; }
// width correction for small cuts
G4double scaling = std::min(1.+0.5*CLHEP::keV/tmax,1.50);
const G4double scaling = std::min(1.+0.5*CLHEP::keV/tmax,1.50);
meanLoss /= scaling;
G4double a1(0.0), a2(0.0), a3(0.0);
@@ -206,14 +206,14 @@ G4UniversalFluctuation::SampleFluctuations(const G4MaterialCutsCouple* couple,
if(w2 > ipotLogFluct) {
if(w2 > e2LogFluct) {
G4double C = meanLoss*(1.-rate)/(w2-ipotLogFluct);
const G4double C = meanLoss*(1.-rate)/(w2-ipotLogFluct);
a1 = C*f1Fluct*(w2-e1LogFluct)/e1Fluct;
a2 = C*f2Fluct*(w2-e2LogFluct)/e2Fluct;
} else {
a1 = meanLoss*(1.-rate)/e1;
}
if(a1 < a0) {
G4double fwnow = 0.5+(fw-0.5)*sqrt(a1/a0);
const G4double fwnow = 0.5+(fw-0.5)*sqrt(a1/a0);
a1 /= fwnow;
e1 *= fwnow;
} else {
@@ -251,8 +251,8 @@ G4UniversalFluctuation::SampleFluctuations(const G4MaterialCutsCouple* couple,
if(a3 > nmaxCont)
{
alfa = w1*(nmaxCont+a3)/(w1*nmaxCont+a3);
G4double alfa1 = alfa*G4Log(alfa)/(alfa-1.);
G4double namean = a3*w1*(alfa-1.)/((w1-1.)*alfa);
const G4double alfa1 = alfa*G4Log(alfa)/(alfa-1.);
const G4double namean = a3*w1*(alfa-1.)/((w1-1.)*alfa);
emean += namean*e0*alfa1;
sig2e += e0*e0*namean*(alfa-alfa1*alfa1);
p3 = a3-namean;
@@ -294,8 +294,8 @@ G4double G4UniversalFluctuation::Dispersion(
electronDensity = material->GetElectronDensity();
G4double gam = (dp->GetKineticEnergy())*m_Inv_particleMass + 1.0;
G4double beta2 = 1.0 - 1.0/(gam*gam);
const G4double beta = dp->GetBeta();
const G4double beta2 = beta*beta;
G4double siga = (1.0/beta2 - 0.5) * twopi_mc2_rcl2 * tmax * length
* electronDensity * chargeSquare;
@@ -314,13 +314,8 @@ G4UniversalFluctuation::SetParticleAndCharge(const G4ParticleDefinition* part,
particleMass = part->GetPDGMass();
// Derived quantities
if( particleMass != 0.0 ){
m_Inv_particleMass = 1.0 / particleMass;
m_massrate = electron_mass_c2 * m_Inv_particleMass ;
}else{
m_Inv_particleMass = DBL_MAX;
m_massrate = DBL_MAX;
}
m_Inv_particleMass = 1.0 / particleMass;
m_massrate = electron_mass_c2 * m_Inv_particleMass;
}
chargeSquare = q2;
}
@@ -63,6 +63,7 @@
#include "G4LossTableManager.hh"
#include "G4EmParameters.hh"
#include "G4ParticleChangeForMSC.hh"
#include "G4ProductionCutsTable.hh"
#include "G4Poisson.hh"
#include "G4Pow.hh"
@@ -74,6 +75,8 @@
using namespace std;
std::vector<G4UrbanMscModel::mscData*> G4UrbanMscModel::msc;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4UrbanMscModel::G4UrbanMscModel(const G4String& nam)
@@ -88,8 +91,6 @@ G4UrbanMscModel::G4UrbanMscModel(const G4String& nam)
tlimitminfix = 0.01*nm;
tlimitminfix2 = 1.*nm;
stepmin = tlimitminfix;
stepmina = 1.;
stepminb = 1.;
smallstep = 1.e10;
currentRange = 0. ;
rangeinit = 0.;
@@ -101,18 +102,7 @@ G4UrbanMscModel::G4UrbanMscModel(const G4String& nam)
geomlimit = geombig;
presafety = 0.*mm;
Zold = 0.;
Zeff = 1.;
Z2 = 1.;
Z23 = 1.;
lnZ = 0.;
coeffth1 = 0.;
coeffth2 = 0.;
coeffc1 = 0.;
coeffc2 = 0.;
coeffc3 = 0.;
coeffc4 = 0.;
particle = 0;
particle = nullptr;
positron = G4Positron::Positron();
theManager = G4LossTableManager::Instance();
@@ -127,6 +117,9 @@ G4UrbanMscModel::G4UrbanMscModel(const G4String& nam)
drr = 0.35;
finalr = 10.*um;
tlow = 5.*CLHEP::keV;
invmev = 1.0/CLHEP::MeV;
skindepth = skin*stepmin;
mass = proton_mass_c2;
@@ -135,7 +128,7 @@ G4UrbanMscModel::G4UrbanMscModel(const G4String& nam)
= zPathLength = par1 = par2 = par3 = 0;
currentLogKinEnergy = LOG_EKIN_MIN;
currentMaterialIndex = -1;
idx = 0;
fParticleChange = nullptr;
couple = nullptr;
}
@@ -143,7 +136,12 @@ G4UrbanMscModel::G4UrbanMscModel(const G4String& nam)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4UrbanMscModel::~G4UrbanMscModel()
{}
{
if(IsMaster()) {
for(auto & ptr : msc) { delete ptr; }
msc.clear();
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -157,6 +155,7 @@ void G4UrbanMscModel::Initialise(const G4ParticleDefinition* p,
latDisplasmentbackup = latDisplasment;
dispAlg96 = (G4EmParameters::Instance()->LateralDisplacementAlg96());
if(IsMaster() || msc.size() == 0) { InitialiseModelCache(); }
/*
G4cout << "### G4UrbanMscModel::Initialise done for "
<< p->GetParticleName() << " type= " << steppingAlgorithm << G4endl;
@@ -284,7 +283,7 @@ G4double G4UrbanMscModel::ComputeCrossSectionPerAtom(
G4double sigma;
SetParticle(part);
Z23 = G4Pow::GetInstance()->Z23(G4lrint(AtomicNumber));
G4double Z23 = G4Pow::GetInstance()->Z23(G4lrint(AtomicNumber));
// correction if particle .ne. e-/e+
// compute equivalent kinetic energy
@@ -325,8 +324,8 @@ G4double G4UrbanMscModel::ComputeCrossSectionPerAtom(
G4int iZ = 14;
// Loop checking, 03-Aug-2015, Vladimir Ivanchenko
while ((iZ>=0)&&(Zdat[iZ]>=AtomicNumber)) iZ -= 1;
if (iZ==14) iZ = 13;
if (iZ==-1) iZ = 0 ;
iZ = std::min(std::max(iZ, 0), 13);
G4double ZZ1 = Zdat[iZ];
G4double ZZ2 = Zdat[iZ+1];
@@ -361,8 +360,8 @@ G4double G4UrbanMscModel::ComputeCrossSectionPerAtom(
G4int iT = 21;
// Loop checking, 03-Aug-2015, Vladimir Ivanchenko
while ((iT>=0)&&(Tdat[iT]>=eKineticEnergy)) iT -= 1;
if(iT==21) iT = 20;
if(iT==-1) iT = 0 ;
iT = std::min(std::max(iT, 0), 20);
// calculate betasquare values
G4double T = Tdat[iT], E = T + electron_mass_c2;
@@ -447,23 +446,18 @@ G4double G4UrbanMscModel::ComputeTruePathLengthLimit(
G4StepStatus stepStatus = sp->GetStepStatus();
couple = track.GetMaterialCutsCouple();
SetCurrentCouple(couple);
currentMaterialIndex = couple->GetIndex();
idx = couple->GetIndex();
currentKinEnergy = dp->GetKineticEnergy();
currentLogKinEnergy = dp->GetLogKineticEnergy();
currentRange = GetRange(particle,currentKinEnergy,couple,currentLogKinEnergy);
lambda0 = GetTransportMeanFreePath(particle,currentKinEnergy,
currentLogKinEnergy);
tPathLength = min(tPathLength,currentRange);
tPathLength = std::min(tPathLength,currentRange);
/*
G4cout << "G4Urban::StepLimit tPathLength= " << tPathLength
<< " range= " <<currentRange<< " lambda= "<<lambda0
<<G4endl;
*/
// set flag to default values
Zeff = couple->GetMaterial()->GetIonisation()->GetZeffective();
if(Zold != Zeff)
UpdateCache();
// stop here if small step
if(tPathLength < tlimitminfix) {
@@ -474,9 +468,9 @@ G4double G4UrbanMscModel::ComputeTruePathLengthLimit(
// upper limit for the straight line distance the particle can travel
// for electrons and positrons
G4double distance = (mass < masslimite)
? currentRange*(1.20-Zeff*(1.62e-2-9.22e-5*Zeff))
? currentRange*msc[idx]->doverra
// for muons, hadrons
: currentRange*(1.15-9.76e-4*Zeff);
: currentRange*msc[idx]->doverrb;
presafety = sp->GetSafety();
/*
@@ -493,7 +487,6 @@ G4double G4UrbanMscModel::ComputeTruePathLengthLimit(
}
latDisplasment = latDisplasmentbackup;
static const G4double invmev = 1.0/CLHEP::MeV;
// standard version
//
if (steppingAlgorithm == fUseDistanceToBoundary)
@@ -521,14 +514,10 @@ G4double G4UrbanMscModel::ComputeTruePathLengthLimit(
rangeinit = currentRange;
if(!firstStep) { smallstep = 1.; }
//define stepmin here (it depends on lambda!)
//rough estimation of lambda_elastic/lambda_transport
G4double rat = currentKinEnergy*invmev;
rat = 1.e-3/(2.e-3+rat*(stepmina+stepminb*rat));
//stepmin ~ lambda_elastic
stepmin = rat*lambda0;
stepmin = ComputeStepmin();
skindepth = skin*stepmin;
tlimitmin = max(0.7*sqrt(Zeff)*stepmin,tlimitminfix);
tlimitmin = ComputeTlimitmin();
/*
G4cout << "rangeinit= " << rangeinit << " stepmin= " << stepmin
<< " tlimitmin= " << tlimitmin << " geomlimit= "
@@ -556,7 +545,7 @@ G4double G4UrbanMscModel::ComputeTruePathLengthLimit(
tlimit = facrange*rangeinit;
//lower limit for tlimit
tlimit = min(max(tlimit,tlimitmin), tgeom);
tlimit = std::min(std::max(tlimit,tlimitmin), tgeom);
/*
G4cout << "tgeom= " << tgeom << " geomlimit= " << geomlimit
<< " tlimit= " << tlimit << " presafety= " << presafety << G4endl;
@@ -578,16 +567,16 @@ G4double G4UrbanMscModel::ComputeTruePathLengthLimit(
{
if(geomlimit > skindepth)
{
tlimit = min(tlimit, geomlimit-0.999*skindepth);
tlimit = std::min(tlimit, geomlimit-0.999*skindepth);
}
else
{
insideskin = true;
tlimit = min(tlimit, stepmin);
tlimit = std::min(tlimit, stepmin);
}
}
tlimit = max(tlimit, stepmin);
tlimit = std::max(tlimit, stepmin);
// randomise if not 'small' step and step determined by msc
tPathLength = ((tlimit < tPathLength)&&(smallstep > skin)&& !insideskin)
@@ -620,23 +609,22 @@ G4double G4UrbanMscModel::ComputeTruePathLengthLimit(
// 9.1 like stepping for e+/e- only (not for muons,hadrons)
if(mass < masslimite)
{
rangeinit = max(rangeinit, lambda0);
rangeinit = std::max(rangeinit, lambda0);
if(lambda0 > lambdalimit) {
fr *= (0.75+0.25*lambda0/lambdalimit);
}
}
//lower limit for tlimit
G4double rat = currentKinEnergy*invmev;
stepmin = lambda0*1.e-3/(2.e-3+rat*(stepmina+stepminb*rat));
tlimitmin = max(0.7*sqrt(Zeff)*stepmin,tlimitminfix);
stepmin = ComputeStepmin();
tlimitmin = ComputeTlimitmin();
}
//step limit
tlimit = (currentRange > presafety) ?
max(fr*rangeinit, facsafety*presafety) : currentRange;
std::max(fr*rangeinit, facsafety*presafety) : currentRange;
//lower limit for tlimit
tlimit = max(tlimit, tlimitmin);
tlimit = std::max(tlimit, tlimitmin);
// randomise if step determined by msc
tPathLength = (tlimit < tPathLength) ?
@@ -667,38 +655,35 @@ G4double G4UrbanMscModel::ComputeTruePathLengthLimit(
rangecut = geombig;
if(mass < masslimite)
{
G4int index = 1;
if(charge > 0.) index = 2;
rangecut = couple->GetProductionCuts()->GetProductionCut(index);
rangecut = msc[idx]->ecut;
if(lambda0 > lambdalimit) {
fr *= (0.84+0.16*lambda0/lambdalimit);
}
}
//lower limit for tlimit
G4double rat = currentKinEnergy*invmev;
stepmin = lambda0*1.e-3/(2.e-3+rat*(stepmina+stepminb*rat));
tlimitmin = max(0.7*sqrt(Zeff)*stepmin,tlimitminfix);
stepmin = ComputeStepmin();
tlimitmin = ComputeTlimitmin();
}
//step limit
tlimit = (currentRange > presafety) ?
max(fr*rangeinit, facsafety*presafety) : currentRange;
std::max(fr*rangeinit, facsafety*presafety) : currentRange;
//lower limit for tlimit
tlimit = max(tlimit, tlimitmin);
tlimit = std::max(tlimit, tlimitmin);
// condition for tPathLength from drr and finalr
if(currentRange > finalr) {
G4double tmax = drr*currentRange+
finalr*(1.-drr)*(2.-finalr/currentRange);
tPathLength = min(tPathLength,tmax);
tPathLength = std::min(tPathLength,tmax);
}
// condition safety
if(currentRange > rangecut) {
if(firstStep) {
tPathLength = min(tPathLength,facsafety*presafety);
tPathLength = std::min(tPathLength,facsafety*presafety);
} else if(stepStatus != fGeomBoundary && presafety > stepmin) {
tPathLength = min(tPathLength,presafety);
tPathLength = std::min(tPathLength,presafety);
}
}
@@ -707,14 +692,14 @@ G4double G4UrbanMscModel::ComputeTruePathLengthLimit(
std::min(tPathLength, Randomizetlimit()) : tPathLength;
}
// version similar to 7.1 (needed for some experiments)
// simple step limitation
else
{
if (stepStatus == fGeomBoundary)
{
tlimit = (currentRange > lambda0)
? facrange*currentRange : facrange*lambda0;
tlimit = max(tlimit, tlimitmin);
tlimit = std::max(tlimit, tlimitmin);
}
// randomise if step determined by msc
tPathLength = (tlimit < tPathLength) ?
@@ -754,7 +739,7 @@ G4double G4UrbanMscModel::ComputeGeomPathLength(G4double)
G4double tau = tPathLength/lambda0 ;
if ((tau <= tausmall) || insideskin) {
zPathLength = min(tPathLength, lambda0);
zPathLength = std::min(tPathLength, lambda0);
} else if (tPathLength < currentRange*dtrl) {
if(tau < taulim) zPathLength = tPathLength*(1.-0.5*tau) ;
@@ -772,7 +757,7 @@ G4double G4UrbanMscModel::ComputeGeomPathLength(G4double)
}
} else {
G4double rfin = max(currentRange-tPathLength, 0.01*currentRange);
G4double rfin = std::max(currentRange-tPathLength, 0.01*currentRange);
G4double T1 = GetEnergy(particle,rfin,couple);
G4double lambda1 = GetTransportMeanFreePath(particle,T1);
@@ -783,7 +768,7 @@ G4double G4UrbanMscModel::ComputeGeomPathLength(G4double)
zPathLength = (1.-G4Exp(par3*G4Log(lambda1/lambda0)))/(par1*par3);
}
zPathLength = min(zPathLength, lambda0);
zPathLength = std::min(zPathLength, lambda0);
//G4cout<< "zPathLength= "<< zPathLength<< " L0= " << lambda0 << G4endl;
return zPathLength;
}
@@ -968,7 +953,8 @@ G4double G4UrbanMscModel::SampleCosineTheta(G4double trueStepLength,
? G4Exp(G4Log(tsmall/lambda0)*onesixth)
: G4Exp(ltau*onesixth);
G4double xx = G4Log(lambdaeff/currentRadLength);
G4double xsi = coeffc1+u*(coeffc2+coeffc3*u)+coeffc4*xx;
G4double xsi = msc[idx]->coeffc1 +
u*(msc[idx]->coeffc2+msc[idx]->coeffc3*u)+msc[idx]->coeffc4*xx;
// tail should not be too big
xsi = std::max(xsi, 1.9);
@@ -1082,6 +1068,7 @@ G4double G4UrbanMscModel::ComputeTheta0(G4double trueStepLength,
if(particle == positron)
{
G4double Zeff = msc[idx]->Zeff;
static const G4double xl= 0.6;
static const G4double xh= 0.9;
static const G4double e = 113.0;
@@ -1112,7 +1099,7 @@ G4double G4UrbanMscModel::ComputeTheta0(G4double trueStepLength,
G4double theta0 = c_highland*std::abs(charge)*std::sqrt(y)*invbetacp;
// correction factor from e- scattering data
theta0 *= (coeffth1+coeffth2*G4Log(y));
theta0 *= (msc[idx]->coeffth1+msc[idx]->coeffth2*G4Log(y));
return theta0;
}
@@ -1264,3 +1251,52 @@ void G4UrbanMscModel::SampleDisplacementNew(G4double, G4double phi)
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4UrbanMscModel::InitialiseModelCache()
{
// it is assumed, that for the second run only addition
// of a new G4MaterialCutsCouple is possible
auto theCoupleTable = G4ProductionCutsTable::GetProductionCutsTable();
size_t numOfCouples = theCoupleTable->GetTableSize();
if(numOfCouples != msc.size()) { msc.resize(numOfCouples); }
for(size_t j=0; j<numOfCouples; ++j) {
auto aCouple = theCoupleTable->GetMaterialCutsCouple(j);
// cut may be changed before runs
G4double cut = aCouple->GetProductionCuts()->GetProductionCut(1);
if(msc[j]) {
msc[j]->ecut = cut;
continue;
}
// new couple
msc[j] = new mscData();
msc[j]->ecut = cut;
G4double Zeff = aCouple->GetMaterial()->GetIonisation()->GetZeffective();
msc[j]->Zeff = Zeff;
msc[j]->sqrtZ = std::sqrt(Zeff);
G4double lnZ = G4Log(Zeff);
// correction in theta0 formula
G4double w = G4Exp(lnZ/6.);
G4double facz = 0.990395+w*(-0.168386+w*0.093286) ;
msc[j]->coeffth1 = facz*(1. - 8.7780e-2/Zeff);
msc[j]->coeffth2 = facz*(4.0780e-2 + 1.7315e-4*Zeff);
// tail parameters
G4double Z13 = w*w;
msc[j]->coeffc1 = 2.3785 - Z13*(4.1981e-1 - Z13*6.3100e-2);
msc[j]->coeffc2 = 4.7526e-1 + Z13*(1.7694 - Z13*3.3885e-1);
msc[j]->coeffc3 = 2.3683e-1 - Z13*(1.8111 - Z13*3.2774e-1);
msc[j]->coeffc4 = 1.7888e-2 + Z13*(1.9659e-2 - Z13*2.6664e-3);
msc[j]->Z23 = Z13*Z13;
msc[j]->stepmina = 27.725/(1.+0.203*Zeff);
msc[j]->stepminb = 6.152/(1.+0.111*Zeff);
msc[j]->doverra = 1.20 - Zeff*(0.0162 - 9.22e-5*Zeff);
msc[j]->doverrb = 1.15 - 9.76e-4*Zeff;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -41,6 +41,7 @@
// 06-02-06 ComputeCrossSectionPerElectron, ComputeCrossSectionPerAtom (mma)
// 29-06-06 Fix problem for zero energy incident positron (V.Ivanchenko)
// 20-10-06 Add theGamma as a member (V.Ivanchenko)
// 18-01-20 Introduce thermal model of annihilation at rest (J.Allison)
//
//
// Class Description:
@@ -54,13 +55,12 @@
//
// GEANT4 internal units.
//
// Note 1: The initial electron is assumed free and at rest.
// Note 1: The initial electron is assumed free and at rest if atomic PDF
// is not defined
//
// Note 2: The annihilation processes producing one or more than two photons are
// ignored, as negligible compared to the two photons process.
//
// -------------------------------------------------------------------
//
@@ -75,7 +75,9 @@
#include "G4Positron.hh"
#include "G4Gamma.hh"
#include "Randomize.hh"
#include "G4RandomDirection.hh"
#include "G4ParticleChangeForGamma.hh"
#include "G4EmParameters.hh"
#include "G4Log.hh"
#include "G4Exp.hh"
@@ -83,6 +85,8 @@
using namespace std;
G4bool G4eeToTwoGammaModel::fSampleAtomicPDF = false;
G4eeToTwoGammaModel::G4eeToTwoGammaModel(const G4ParticleDefinition*,
const G4String& nam)
: G4VEmModel(nam),
@@ -102,6 +106,26 @@ G4eeToTwoGammaModel::~G4eeToTwoGammaModel()
void G4eeToTwoGammaModel::Initialise(const G4ParticleDefinition*,
const G4DataVector&)
{
if(IsMaster()) {
G4int verbose = G4EmParameters::Instance()->Verbose();
// redo initialisation for each new run
fSampleAtomicPDF = false;
const auto& materialTable = G4Material::GetMaterialTable();
for (const auto& material: *materialTable) {
const G4double meanEnergyPerIonPair = material->GetIonisation()->GetMeanEnergyPerIonPair();
if (meanEnergyPerIonPair > 0.) {
fSampleAtomicPDF = true;
if(verbose > 0) {
G4cout << "### G4eeToTwoGammaModel: for " << material->GetName() << " mean energy per ion pair is "
<< meanEnergyPerIonPair/CLHEP::eV << " eV" << G4endl;
}
}
}
}
// If no materials have meanEnergyPerIonPair set. This is probably the usual
// case, since most applications are not senstive to the slight
// non-collinearity of gammas in eeToTwoGamma. Do not issue any warning.
if(fParticleChange) { return; }
fParticleChange = GetParticleChangeForGamma();
}
@@ -135,9 +159,7 @@ G4double G4eeToTwoGammaModel::ComputeCrossSectionPerAtom(
G4double, G4double, G4double)
{
// Calculates the cross section per atom of annihilation into two photons
G4double cross = Z*ComputeCrossSectionPerElectron(kineticEnergy);
return cross;
return Z*ComputeCrossSectionPerElectron(kineticEnergy);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -149,19 +171,16 @@ G4double G4eeToTwoGammaModel::CrossSectionPerVolume(
G4double, G4double)
{
// Calculates the cross section per volume of annihilation into two photons
G4double eDensity = material->GetElectronDensity();
G4double cross = eDensity*ComputeCrossSectionPerElectron(kineticEnergy);
return cross;
return material->GetElectronDensity()*ComputeCrossSectionPerElectron(kineticEnergy);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
// Polarisation of gamma according to M.H.L.Pryce and J.C.Ward,
// Polarisation of gamma according to M.H.L.Pryce and J.C.Ward,
// Nature 4065 (1947) 435.
void G4eeToTwoGammaModel::SampleSecondaries(vector<G4DynamicParticle*>* vdp,
const G4MaterialCutsCouple*,
const G4MaterialCutsCouple* pCutsCouple,
const G4DynamicParticle* dp,
G4double,
G4double)
@@ -173,26 +192,81 @@ void G4eeToTwoGammaModel::SampleSecondaries(vector<G4DynamicParticle*>* vdp,
// Case at rest
if(posiKinEnergy == 0.0) {
G4double cost = 2.*rndmEngine->flat()-1.;
G4double sint = sqrt((1. - cost)*(1. + cost));
G4double phi = twopi * rndmEngine->flat();
G4ThreeVector dir(sint*cos(phi), sint*sin(phi), cost);
phi = twopi * rndmEngine->flat();
G4double cosphi = cos(phi);
G4double sinphi = sin(phi);
G4ThreeVector pol(cosphi, sinphi, 0.0);
pol.rotateUz(dir);
aGamma1 = new G4DynamicParticle(theGamma, dir, electron_mass_c2);
aGamma1->SetPolarization(pol.x(),pol.y(),pol.z());
aGamma2 = new G4DynamicParticle(theGamma,-dir, electron_mass_c2);
pol.set(-sinphi, cosphi, 0.0);
pol.rotateUz(dir);
aGamma2->SetPolarization(pol.x(),pol.y(),pol.z());
/*
G4cout << "Annihilation at rest fly: e0= " << " dir= " << dir
<< G4endl;
*/
} else {
const G4double eGamma = electron_mass_c2;
// In rest frame of positronium gammas are back to back
const G4ThreeVector& dir1 = G4RandomDirection();
const G4ThreeVector& dir2 = -dir1;
aGamma1 = new G4DynamicParticle(G4Gamma::Gamma(),dir1,eGamma);
aGamma2 = new G4DynamicParticle(G4Gamma::Gamma(),dir2,eGamma);
// In rest frame the gammas are polarised perpendicular to each other - see
// Pryce and Ward, Nature No 4065 (1947) p.435.
// Snyder et al, Physical Review 73 (1948) p.440.
G4ThreeVector pol1 = (G4RandomDirection().cross(dir1)).unit();
G4ThreeVector pol2 = (pol1.cross(dir2)).unit();
// But the positronium is moving...
// A positron in matter slows down and combines with an atomic electron to
// make a neutral “atom” called positronium, about half the size of a normal
// atom. I expect that when the energy of the positron is small enough,
// less than the binding energy of positronium (6.8 eV), it is
// energetically favourable for an electron from the outer orbitals of a
// nearby atom or molecule to transfer and bind to the positron, as in an
// ionic bond, leaving behind a mildly ionised nearby atom/molecule. I
// would expect the positronium to come away with a kinetic energy of a
// few eV on average. In its para (spin 0) state it annihilates into two
// photons, which in the rest frame of the positronium are collinear
// (back-to-back) due to momentum conservation. Because of the motion of the
// positronium, photons will be not quite back-to-back in the laboratory.
// The positroniuim acquires an energy of order its binding energy and
// doesn't have time to thermalise. Nevertheless, here we approximate its
// energy distribution by a Maxwell-Boltzman with mean energy <KE>. In terms
// of a more familiar concept of temperature, and the law of equipartition
// of energy of translational motion, <KE>=3kT/2. Each component of velocity
// has a distribution exp(-mv^2/2kT), which is a Gaussian of mean zero
// and variance kT/m=2<KE>/3m, where m is the positronium mass.
// We take <KE> = material->GetIonisation()->GetMeanEnergyPerIonPair().
if(fSampleAtomicPDF) {
const G4Material* material = pCutsCouple->GetMaterial();
const G4double meanEnergyPerIonPair = material->GetIonisation()->GetMeanEnergyPerIonPair();
const G4double& meanKE = meanEnergyPerIonPair; // Just an alias
if (meanKE > 0.) { // Positronium haas motion
// Mass of positronium
const G4double mass = 2.*electron_mass_c2;
// Mean <KE>=3kT/2, as described above
// const G4double T = 2.*meanKE/(3.*k_Boltzmann);
// Component velocities: Gaussian, variance kT/m=2<KE>/3m.
const G4double sigmav = std::sqrt(2.*meanKE/(3.*mass));
// This is in units where c=1
const G4double vx = G4RandGauss::shoot(0.,sigmav);
const G4double vy = G4RandGauss::shoot(0.,sigmav);
const G4double vz = G4RandGauss::shoot(0.,sigmav);
const G4ThreeVector v(vx,vy,vz); // In unit where c=1
const G4ThreeVector& beta = v; // so beta=v/c=v
aGamma1->Set4Momentum(aGamma1->Get4Momentum().boost(beta));
aGamma2->Set4Momentum(aGamma2->Get4Momentum().boost(beta));
// Rotate polarisation vectors
const G4ThreeVector& newDir1 = aGamma1->GetMomentumDirection();
const G4ThreeVector& newDir2 = aGamma2->GetMomentumDirection();
const G4ThreeVector& axis1 = dir1.cross(newDir1); // No need to be unit
const G4ThreeVector& axis2 = dir2.cross(newDir2); // No need to be unit
const G4double& angle1 = std::acos(dir1*newDir1);
const G4double& angle2 = std::acos(dir2*newDir2);
if (axis1 != G4ThreeVector()) pol1.rotate(axis1,angle1);
if (axis2 != G4ThreeVector()) pol2.rotate(axis2,angle2);
}
}
aGamma1->SetPolarization(pol1.x(),pol1.y(),pol1.z());
aGamma2->SetPolarization(pol2.x(),pol2.y(),pol2.z());
} else { // Positron interacts in flight
G4ThreeVector posiDirection = dp->GetMomentumDirection();
@@ -114,6 +114,8 @@ G4VParticleChange* G4eplusAnnihilation::AtRestDoIt(const G4Track& track,
// Performs the e+ e- annihilation when both particles are assumed at rest.
{
fParticleChange.InitializeForPostStep(track);
DefineMaterial(track.GetMaterialCutsCouple());
size_t idx = CurrentMaterialCutsCoupleIndex();
G4double ene(0.0);
G4VEmModel* model = SelectModel(ene, idx);