Import Geant4 11.3.0 source tree
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user