Import Geant4 11.4.0.beta source tree
This commit is contained in:
@@ -60,7 +60,6 @@
|
||||
namespace
|
||||
{
|
||||
constexpr G4int maxN = 1000;
|
||||
constexpr G4double emin = 2*136.9*CLHEP::MeV;
|
||||
}
|
||||
|
||||
G4ChargeExchange::G4ChargeExchange(G4ChargeExchangeXS* ptr)
|
||||
@@ -102,21 +101,25 @@ G4HadFinalState* G4ChargeExchange::ApplyYourself(
|
||||
// is not possible on proton, only on deuteron
|
||||
if (1 == Z && (211 == projPDG || 321 == projPDG)) { A = 2; }
|
||||
|
||||
if (verboseLevel > 1)
|
||||
if (verboseLevel > 1) {
|
||||
G4cout << "G4ChargeExchange for " << part->GetParticleName()
|
||||
<< " PDGcode= " << projPDG << " on nucleus Z= " << Z
|
||||
<< " A= " << A << " N= " << A - Z
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
G4double mass1 = G4NucleiProperties::GetNuclearMass(A, Z);
|
||||
G4LorentzVector lv0 = aTrack.Get4Momentum();
|
||||
G4double etot = mass1 + lv0.e();
|
||||
|
||||
// select final state
|
||||
const G4ParticleDefinition* theSecondary =
|
||||
fXSection->SampleSecondaryType(part, Z, A);
|
||||
fXSection->SampleSecondaryType(part, aTrack.GetMaterial(),
|
||||
Z, A, aTrack.GetTotalEnergy());
|
||||
G4int pdg = theSecondary->GetPDGEncoding();
|
||||
|
||||
if (verboseLevel > 1)
|
||||
G4cout << " Secondary " << theSecondary->GetParticleName() << " pdg=" << pdg << G4endl;
|
||||
|
||||
// omega(782) and f2(1270)
|
||||
G4bool isShortLived = (pdg == 223 || pdg == 225);
|
||||
|
||||
@@ -141,62 +144,86 @@ G4HadFinalState* G4ChargeExchange::ApplyYourself(
|
||||
else if (Z == 1 && A == 3) { theRecoil = G4Triton::Triton(); }
|
||||
else if (Z == 2 && A == 3) { theRecoil = G4He3::He3(); }
|
||||
else if (Z == 2 && A == 4) { theRecoil = G4Alpha::Alpha(); }
|
||||
else if (nist->GetIsotopeAbundance(Z, A) > 0.0) {
|
||||
theRecoil = G4ParticleTable::GetParticleTable()
|
||||
->GetIonTable()->GetIon(Z, A, 0.0);
|
||||
}
|
||||
|
||||
// check if there is enough energy for the final state
|
||||
// and sample mass of produced state
|
||||
const G4double mass0 = theSecondary->GetPDGMass();
|
||||
G4double mass3 = (nullptr == theRecoil) ?
|
||||
G4NucleiProperties::GetNuclearMass(A, Z) : theRecoil->GetPDGMass();
|
||||
G4double mass2 = mass0;
|
||||
if (isShortLived &&
|
||||
!SampleMass(mass2, theSecondary->GetPDGWidth(), etot - mass3)) {
|
||||
return &theParticleChange;
|
||||
}
|
||||
|
||||
// not possible kinematically
|
||||
if (etot <= mass2 + mass3) {
|
||||
return &theParticleChange;
|
||||
}
|
||||
|
||||
// sample kinematics
|
||||
G4LorentzVector lv1(0.0, 0.0, 0.0, mass1);
|
||||
G4LorentzVector lv = lv0 + lv1;
|
||||
G4ThreeVector bst = lv.boostVector();
|
||||
G4double ss = lv.mag2();
|
||||
G4double m0 = lv.mag();
|
||||
const G4double mass0 = theSecondary->GetPDGMass();
|
||||
G4double mass2 = mass0;
|
||||
G4double mass3;
|
||||
G4bool ok = false;
|
||||
|
||||
if (verboseLevel > 1) {
|
||||
G4cout << " Secondary meson " << theSecondary->GetParticleName()
|
||||
<< " mass(MeV)=" << mass2 << " pdg=" << pdg
|
||||
<< " Final Z=" << Z << " isShortLived=" << isShortLived
|
||||
<< " " << lv
|
||||
<< G4endl;
|
||||
}
|
||||
// fixed recoil mass
|
||||
if (nullptr != theRecoil) {
|
||||
mass3 = theRecoil->GetPDGMass();
|
||||
ok = (m0 > mass2 + mass3);
|
||||
|
||||
// excited nuclear state
|
||||
} else {
|
||||
G4double mass30 = G4NucleiProperties::GetNuclearMass(A, Z);
|
||||
const G4double eFermi = 10*CLHEP::MeV;
|
||||
for (G4int i=0; i<10; ++i) {
|
||||
mass3 = mass30 + eFermi*G4UniformRand();
|
||||
if (m0 > mass2 + mass3) {
|
||||
ok = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isShortLived) {
|
||||
const G4double elim = 300*CLHEP::MeV;
|
||||
ok = false;
|
||||
for (G4int i=0; i<10; ++i) {
|
||||
if (SampleMass(mass2, theSecondary->GetPDGWidth(), elim)) {
|
||||
if (m0 > mass2 + mass3) {
|
||||
ok = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// not possible kinematically
|
||||
if (!ok) { return &theParticleChange; }
|
||||
|
||||
// tmax = 4*momCMS^2
|
||||
G4double e2 = ss + mass2*mass2 - mass3*mass3;
|
||||
G4double tmax = e2*e2/ss - 4*mass2*mass2;
|
||||
|
||||
G4double e2 = (m0*m0 + mass2*mass2 - mass3*mass3)/(2*m0);
|
||||
G4double momentumCMS = std::sqrt(e2*e2 - mass2*mass2);
|
||||
|
||||
G4double tmax = 4*(momentumCMS*momentumCMS);
|
||||
G4double t = SampleT(theSecondary, A, tmax);
|
||||
|
||||
G4double phi = G4UniformRand()*CLHEP::twopi;
|
||||
G4double cost = 1. - 2.0*t/tmax;
|
||||
|
||||
if (cost > 1.0) { cost = 1.0; }
|
||||
else if(cost < -1.0) { cost = -1.0; }
|
||||
// if cos(theta) negative, there is a numerical problem
|
||||
// instead of making scattering backward, make in this case
|
||||
// no scattering
|
||||
if (std::abs(cost) > 1.0) { cost = 1.0; }
|
||||
|
||||
G4double sint = std::sqrt((1.0-cost)*(1.0+cost));
|
||||
|
||||
if (verboseLevel>1) {
|
||||
if (verboseLevel > 1) {
|
||||
G4cout << " t= " << t << " tmax(GeV^2)= " << tmax/(GeV*GeV)
|
||||
<< " cos(t)=" << cost << " sin(t)=" << sint << G4endl;
|
||||
}
|
||||
G4double momentumCMS = 0.5*std::sqrt(tmax);
|
||||
G4LorentzVector lv2(momentumCMS*sint*std::cos(phi),
|
||||
momentumCMS*sint*std::sin(phi),
|
||||
momentumCMS*cost,
|
||||
std::sqrt(momentumCMS*momentumCMS + mass2*mass2));
|
||||
momentumCMS*cost, e2);
|
||||
|
||||
// kinematics in the final state, may be a warning should be added if
|
||||
G4ThreeVector bst = lv.boostVector();
|
||||
lv2.boost(bst);
|
||||
if (lv2.e() < mass2) {
|
||||
lv2.setE(mass2);
|
||||
}
|
||||
lv -= lv2;
|
||||
if (lv.e() < mass3) {
|
||||
lv.setE(mass3);
|
||||
@@ -205,6 +232,7 @@ G4HadFinalState* G4ChargeExchange::ApplyYourself(
|
||||
// prepare secondary particles
|
||||
theParticleChange.SetStatusChange(stopAndKill);
|
||||
theParticleChange.SetEnergyChange(0.0);
|
||||
theParticleChange.SetWeightChange(fXSWeightFactor);
|
||||
|
||||
if (!isShortLived) {
|
||||
auto aSec = new G4DynamicParticle(theSecondary, lv2);
|
||||
@@ -218,8 +246,9 @@ G4HadFinalState* G4ChargeExchange::ApplyYourself(
|
||||
auto p = (*products)[i];
|
||||
auto lvp = p->Get4Momentum();
|
||||
lvp.boost(bst1);
|
||||
p->Set4Momentum(lvp);
|
||||
theParticleChange.AddSecondary(p, secID);
|
||||
auto pnew = new G4DynamicParticle(*p);
|
||||
pnew->Set4Momentum(lvp);
|
||||
theParticleChange.AddSecondary(pnew, secID);
|
||||
}
|
||||
delete products;
|
||||
}
|
||||
@@ -229,7 +258,7 @@ G4HadFinalState* G4ChargeExchange::ApplyYourself(
|
||||
auto aRec = new G4DynamicParticle(theRecoil, lv);
|
||||
theParticleChange.AddSecondary(aRec, secID);
|
||||
} else {
|
||||
// recoil is an unstable fragment
|
||||
// recoil is a fragment, which may be unstable
|
||||
G4Fragment frag(A, Z, lv);
|
||||
auto products = fHandler->BreakItUp(frag);
|
||||
for (auto & prod : *products) {
|
||||
@@ -243,43 +272,50 @@ G4HadFinalState* G4ChargeExchange::ApplyYourself(
|
||||
}
|
||||
|
||||
G4double G4ChargeExchange::SampleT(const G4ParticleDefinition*,
|
||||
const G4int A, const G4double tmax) const
|
||||
const G4int A, const G4double ltmax) const
|
||||
{
|
||||
const G4double GeV2 = CLHEP::GeV*CLHEP::GeV;
|
||||
const G4double numLimit = 18.;
|
||||
|
||||
G4double tmax = ltmax/GeV2;
|
||||
if (verboseLevel > 1) {
|
||||
G4cout << "G4ChargeExchange::SampleT tmax(GeV^2)=" << tmax << G4endl;
|
||||
}
|
||||
|
||||
G4double aa, bb, cc, dd;
|
||||
G4Pow* g4pow = G4Pow::GetInstance();
|
||||
if (A <= 62.) {
|
||||
aa = g4pow->powZ(A, 1.63);
|
||||
bb = 14.5*g4pow->powZ(A, 0.66);
|
||||
cc = 1.4*g4pow->powZ(A, 0.33);
|
||||
G4double a13 = g4pow->Z13(A);
|
||||
if (A <= 62) {
|
||||
aa = (A*A);
|
||||
bb = 14.5*a13*a13;
|
||||
cc = 1.4*a13;
|
||||
dd = 10.;
|
||||
} else {
|
||||
aa = g4pow->powZ(A, 1.33);
|
||||
bb = 60.*g4pow->powZ(A, 0.33);
|
||||
bb = 60.*a13;
|
||||
cc = 0.4*g4pow->powZ(A, 0.40);
|
||||
dd = 10.;
|
||||
}
|
||||
G4double x1 = (1.0 - G4Exp(-tmax*bb))*aa/bb;
|
||||
G4double x2 = (1.0 - G4Exp(-tmax*dd))*cc/dd;
|
||||
|
||||
G4double t;
|
||||
G4double y = bb;
|
||||
if(G4UniformRand()*(x1 + x2) < x2) y = dd;
|
||||
|
||||
for (G4int i=0; i<maxN; ++i) {
|
||||
t = -G4Log(G4UniformRand())/y;
|
||||
if (t <= tmax) { return t; }
|
||||
G4double q1 = 1.0 - G4Exp(-std::min(bb*tmax, numLimit));
|
||||
G4double q2 = 1.0 - G4Exp(-std::min(dd*tmax, numLimit));
|
||||
G4double s1 = q1*aa;
|
||||
G4double s2 = q2*cc;
|
||||
if ((s1 + s2)*G4UniformRand() < s2) {
|
||||
q1 = q2;
|
||||
bb = dd;
|
||||
}
|
||||
return 0.0;
|
||||
return -GeV2*G4Log(1.0 - G4UniformRand()*q1)/bb;
|
||||
}
|
||||
|
||||
G4bool G4ChargeExchange::SampleMass(G4double& M, const G4double G, const G4double elim)
|
||||
G4bool G4ChargeExchange::SampleMass(G4double& M, const G4double G,
|
||||
const G4double elim)
|
||||
{
|
||||
// +- 4 width but above 2 pion mass
|
||||
const G4double e1 = std::max(M - 4*G, emin);
|
||||
const G4double e2 = std::min(M + 4*G, elim) - e1;
|
||||
G4double e1 = std::max(M - 4*G, elim);
|
||||
G4double e2 = M + 4*G - e1;
|
||||
if (e2 <= 0.0) { return false; }
|
||||
const G4double M2 = M*M;
|
||||
const G4double MG2 = M2*G*G;
|
||||
G4double M2 = M*M;
|
||||
G4double MG2 = M2*G*G;
|
||||
|
||||
// sampling Breit-Wigner function
|
||||
for (G4int i=0; i<maxN; ++i) {
|
||||
|
||||
@@ -143,8 +143,10 @@ G4HadFinalState* G4HadronElastic::ApplyYourself(
|
||||
G4double phi = G4UniformRand()*CLHEP::twopi;
|
||||
G4double cost = 1. - 2.0*t/pLocalTmax;
|
||||
|
||||
if (cost > 1.0) { cost = 1.0; }
|
||||
else if(cost < -1.0) { cost = -1.0; }
|
||||
// if cos(theta) negative, there is a numerical problem
|
||||
// instead of making scattering backward, make in this case
|
||||
// no scattering
|
||||
if (std::abs(cost) > 1.0) { cost = 1.0; }
|
||||
|
||||
G4double sint = std::sqrt((1.0-cost)*(1.0+cost));
|
||||
|
||||
@@ -209,7 +211,7 @@ G4HadronElastic::SampleInvariantT(const G4ParticleDefinition* part,
|
||||
G4double mom, G4int, G4int A)
|
||||
{
|
||||
const G4double plabLowLimit = 400.0*CLHEP::MeV;
|
||||
const G4double GeV2 = GeV*GeV;
|
||||
const G4double GeV2 = CLHEP::GeV*CLHEP::GeV;
|
||||
const G4double z07in13 = std::pow(0.7, 0.3333333333);
|
||||
const G4double numLimit = 18.;
|
||||
|
||||
@@ -263,7 +265,7 @@ G4HadronElastic::SampleInvariantT(const G4ParticleDefinition* part,
|
||||
G4double q2 = 1.0 - G4Exp(-std::min(dd*tmax, numLimit));
|
||||
G4double s1 = q1*aa;
|
||||
G4double s2 = q2*cc;
|
||||
if((s1 + s2)*G4UniformRand() < s2) {
|
||||
if ((s1 + s2)*G4UniformRand() < s2) {
|
||||
q1 = q2;
|
||||
bb = dd;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user