Import Geant4 11.3.0 source tree

This commit is contained in:
Gabriele Cosmo
2024-12-06 11:11:40 +01:00
parent e58e650b32
commit 32390e802b
1984 changed files with 98713 additions and 83996 deletions
@@ -36,7 +36,7 @@
#include "G4ElementTable.hh"
#include "G4Material.hh"
#include "G4Element.hh"
#include "G4Isotope.hh"
#include "G4IsotopeList.hh"
#include "G4HadronicParameters.hh"
#include "Randomize.hh"
#include "G4SystemOfUnits.hh"
@@ -60,13 +60,9 @@ namespace {
const G4double pG0[5] = {2.55, 4.6, 3.7, 5.5, 4.6}; // g0
const G4double pG1[5] = {-0.23, -0.5, 0., 0., -2.}; // g1
// beta_prime value for calculation of cross section of pi0 and eta
// absorption inside different nuclei
const G4double beta_prime_pi = 0.0410;
const G4double beta_prime_eta = 0.0402;
}
G4ChargeExchangeXS::G4ChargeExchangeXS()
{
if (verboseLevel > 1) {
@@ -93,106 +89,119 @@ void G4ChargeExchangeXS::CrossSectionDescription(std::ostream& outFile) const
<< "pi+, pi-, K+, K-, KL\n";
}
G4bool G4ChargeExchangeXS::IsIsoApplicable(const G4DynamicParticle*,
G4int, G4int,
const G4Element*, const G4Material*)
G4bool G4ChargeExchangeXS::IsElementApplicable(const G4DynamicParticle*,
G4int, const G4Material*)
{
return true;
}
G4double
G4ChargeExchangeXS::GetIsoCrossSection(const G4DynamicParticle* aParticle,
G4int Z, G4int A,
const G4Isotope*, const G4Element*,
const G4Material*)
G4ChargeExchangeXS::GetElementCrossSection(const G4DynamicParticle* aParticle,
G4int ZZ, const G4Material* mat)
{
G4double result = 0.0;
const G4double pE = aParticle->GetTotalEnergy();
if (pE <= fEnergyLimit) { return result; }
if (pE <= fEnergyLimit) { return result; }
auto part = aParticle->GetDefinition();
G4int pdg = part->GetPDGEncoding();
// Get or calculate the nucleus mass, particle mass,particle kinetic energy
// and particle total energy
G4double tM = G4NucleiProperties::GetNuclearMass(A, Z);
G4double pM = part->GetPDGMass();
// Calculate s(lorentz invariant)
// Get or calculate the proton mass, particle mass, and s(Lorentz invariant)
G4double tM = CLHEP::proton_mass_c2;
G4double pM = part->GetPDGMass();
G4double lorentz_s = tM*tM + 2*tM*pE + pM*pM;
if (lorentz_s <= (tM + pM)*(tM + pM)) { return result; }
const G4int Z = std::min(ZZ, ZMAXNUCLEARDATA);
const G4int A = G4lrint(aeff[Z]);
if (verboseLevel > 1) {
G4cout << "### G4ChargeExchangeXS: " << part->GetParticleName()
<< " Z=" << Z << " A=" << A << " Etot(GeV)=" << pE/CLHEP::GeV
<< " s(GeV^2)=" << lorentz_s/(CLHEP::GeV*CLHEP::GeV) << G4endl;
}
// For unit conversion
const G4double inv1e7 = 1e-7;
const G4double inv1e7 = 0.1/(CLHEP::GeV*CLHEP::GeV);
const G4double fact = 1e-30*CLHEP::cm2;
const G4double pfact = 0.1/CLHEP::GeV;
const G4double kfact = 56.3*fact;
G4double logA = g4calc->logZ(A);
const G4double csmax = 1e-16;
// The approximation of Glauber-Gribov formula -> extend it from interaction with
// proton to nuclei Z^(2/3). The factor g4calc->powA(A,-beta_prime_pi*G4Log(A))
// proton to nuclei Z^(2/3). The factor g4calc->powA(A,-beta_prime_pi*G4Log(A))
// takes into account absorption of pi0 and eta
// pi- + p -> sum of (pi0 + eta) + n
// pi- + p -> n + meson (0- pi0, 1- eta, 2- eta', 3- omega, 4- f2(1270))
if (pdg == -211) {
const G4double z23 = g4calc->Z23(Z);
const G4int z = A/2;
const G4double a23 = g4calc->Z23(z);
const G4double x = lorentz_s*inv1e7;
G4double sum = 122.*z23*g4calc->powA(x, -1.23)*g4calc->powZ(A,-beta_prime_pi*logA);
fXSecPion[0] = sum;
sum += 31.*z23*g4calc->powA(x, -1.53)*g4calc->powZ(A,-beta_prime_eta*logA);
fXSecPion[1] = sum;
const G4double logX = G4Log(x);
for (G4int i=2; i<5; ++i) {
sum += piA[i]*z23*g4calc->powA(x, -pAP[i])*(1.0 + pG0[i] + pG1[i]*logX)
*g4calc->powA(z23, -0.15*a23)/(pC0[i] + pC1[i]*logX);
fXSecPion[i] = sum;
G4double z23 = g4calc->Z23(Z);
G4double x = lorentz_s*inv1e7;
G4double logX = G4Log(x);
G4double logA = g4calc->logZ(A);
G4double xf = g4calc->powZ(A, -beta_prime_pi*logA);
G4double sum = 0.0;
for (G4int i=0; i<5; ++i) {
G4double xg = std::max(1.0 + pG0[i] + pG1[i]*logX, 0.0);
G4double xc = std::max(pC0[i] + pC1[i]*logX, csmax);
G4double xs = z23*piA[i]*g4calc->powA(x, -pAP[i])*xf*xg/xc;
sum += xs;
fXSecPion[i] = sum;
}
result = sum*fact;
}
// pi+ + n -> sum of (pi0 + eta) + p
// pi+ + n -> p + meson (0- pi0, 1- eta, 2- eta', 3- omega, 4- f2(1270))
else if (pdg == 211) {
const G4double n23 = g4calc->Z23(A - Z);
const G4int z = A/2;
const G4double a23 = g4calc->Z23(z);
const G4double x = lorentz_s*inv1e7;
G4double sum = 122.*n23*g4calc->powA(x, -1.23)*g4calc->powZ(A,-beta_prime_pi*logA);
fXSecPion[0] = sum;
sum += 31.*n23*g4calc->powA(x, -1.53)*g4calc->powZ(A,-beta_prime_eta*logA);
fXSecPion[1] = sum;
const G4double logX = G4Log(x);
for (G4int i=2; i<5; ++i) {
sum += piA[i]*n23*g4calc->powA(x, -pAP[i])*(1.0 + pG0[i] + pG1[i]*logX)
*g4calc->powA(n23, -0.15*a23)/(pC0[i] + pC1[i]*logX);
fXSecPion[i] = sum;
G4double n23 = g4calc->Z23(A - Z);
G4double x = lorentz_s*inv1e7;
G4double logX = G4Log(x);
G4double logA = g4calc->logZ(A);
G4double xf = g4calc->powZ(A, -beta_prime_pi*logA);
// hydrogen target case Z = A = 1
// the cross section is defined by fraction of deuteron and tritium
if (1 == Z) { n23 = ComputeDeuteronFraction(mat); }
G4double sum = 0.0;
for (G4int i=0; i<5; ++i) {
G4double xg = std::max(1.0 + pG0[i] + pG1[i]*logX, 0.0);
G4double xc = std::max(pC0[i] + pC1[i]*logX, csmax);
G4double xs = n23*piA[i]*g4calc->powA(x, -pAP[i])*xf*xg/xc;
sum += xs;
fXSecPion[i] = sum;
}
result = sum*fact;
}
// Kaon x-sections depend on the primary particles momentum
// K- + p -> Kbar + n
else if (pdg == -321){
// Calculate the momentum of the bombarding particles and convert
// it to GeV/c^2 unit
const G4double p_momentum = std::sqrt(pE*pE - pM*pM)*pfact;
else if (pdg == -321) {
G4double p_momentum = std::sqrt(pE*pE - pM*pM)*pfact;
result = g4calc->Z23(Z)*g4calc->powA(p_momentum, -1.60)*kfact;
}
// K+ + n -> Kbar + p
else if (pdg == 321) {
const G4double p_momentum = std::sqrt(pE*pE - pM*pM)*pfact;
result = g4calc->Z23(A-Z)*g4calc->powA(p_momentum, -1.60)*kfact;
G4double p_momentum = std::sqrt(pE*pE - pM*pM)*pfact;
G4double n23 = g4calc->Z23(A-Z);
// hydrogen target case Z = A = 1
// the cross section is defined by fraction of deuteron and tritium
if (1 == Z) { n23 = ComputeDeuteronFraction(mat); }
result = n23*g4calc->powA(p_momentum, -1.60)*kfact;
}
// KL
else if (pdg == 130) {
// Cross section of K-long = 0.5*(Cross section of K+ + Cross section of K-)
// Cross section of KL = 0.5*(Cross section of K+ + Cross section of K-)
const G4double p_momentum = std::sqrt(pE*pE - pM*pM)*pfact;
result = 0.5*(g4calc->Z23(Z) + g4calc->Z23(A-Z))*
g4calc->powA(p_momentum, -1.60)*kfact;
}
return result*fFactor;
result *= fFactor;
if (verboseLevel > 1) {
G4cout << " Done for " << part->GetParticleName() << " Etot(GeV)=" << pE/CLHEP::GeV
<< " res(mb)=" << result/CLHEP::millibarn << G4endl;
}
return result;
}
const G4ParticleDefinition*
@@ -200,33 +209,35 @@ G4ChargeExchangeXS::SampleSecondaryType(const G4ParticleDefinition* part,
const G4int Z, const G4int A)
{
const G4ParticleDefinition* pd = nullptr;
G4int pdg = part->GetPDGEncoding();
G4int pdg = std::abs(part->GetPDGEncoding());
// pi- + p / pi+ + n
if (std::abs(pdg) == 211) {
const G4double x = fXSecPion[4]*G4UniformRand();
if (pdg == 211) {
pd = fPionSecPD[0];
G4double x = fXSecPion[4]*G4UniformRand();
for (G4int i=0; i<5; ++i) {
if (x <= fXSecPion[i]) {
return fPionSecPD[i];
pd = fPionSecPD[i];
break;
}
}
}
// K- + p / K+ + n
// Equal opportunity of producing k-short and k-long
else if (std::abs(pdg) == 321) {
if (G4UniformRand() > 0.5) {
pd = G4KaonZeroLong::KaonZeroLong();
else if (pdg == 321) {
if (G4UniformRand() >= 0.5) {
pd = G4KaonZeroLong::KaonZeroLong();
}
else {
pd = G4KaonZeroShort::KaonZeroShort();
}
}
// KL + atom
else if (std::abs(pdg) == 130) {
// KL + nucleus
else if (pdg == 130) {
G4double prob = (G4double)Z/(G4double)A;
if (G4UniformRand() > prob) {
if (G4UniformRand() >= prob) {
pd = G4KaonMinus::KaonMinus();
}
else {
@@ -236,3 +247,21 @@ G4ChargeExchangeXS::SampleSecondaryType(const G4ParticleDefinition* part,
return pd;
}
G4double
G4ChargeExchangeXS::ComputeDeuteronFraction(const G4Material* mat)
{
for (auto const & elm : *mat->GetElementVector()) {
if (1 == elm->GetZasInt()) {
G4double ab = 0.0;
const G4int nIso = (G4int)elm->GetNumberOfIsotopes();
const G4double* abu = elm->GetRelativeAbundanceVector();
for (G4int j = 0; j < nIso; ++j) {
auto const iso = elm->GetIsotope(j);
ab += (iso->GetN() - iso->GetZ())*abu[j];
}
return ab;
}
}
return 0.0;
}