Import Geant4 11.4.0.beta source tree

This commit is contained in:
Gabriele Cosmo
2025-06-26 09:17:29 +02:00
parent 20a218bbe1
commit a499fb82e9
1941 changed files with 203285 additions and 95593 deletions
@@ -6,7 +6,7 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2025-04-22 Alberto Ribon (hadr-casc-V11-02-05)
## 2025-04-22 Alberto Ribon (hadr-casc-V11-03-00)
- G4CascadeFinalStateAlgorithm, G4NucleiModel : introduced the possibility to
retrieve either the behavior of these classes as in Geant4 version 11.3
(default) or as in 11.2 according to the value of boolean flags in
@@ -6,6 +6,24 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2025-05-15 Vladimir Ivanchenko (hadr-cohe-V11-03-03)
- G4ChargeExchange, G4HadronElastic - cleanup final state generation: use
the numerical limit for argument of the exponent to avoid precision loss;
in case of numerical problems force scattering angle to zero (do not
consider scattering backward); use similar parameterisation and code for
both models.
## 2025-05-01 Vladimir Ivanchenko (hadr-cohe-V11-03-02)
- G4ChargeExchange - fixed Coverity warning
## 2025-04-27 Vladimir Ivanchenko (hadr-cohe-V11-03-01)
- G4ChargeExchange - fixed problem in final state generation for the case of
unstable meson production omega(782) and f2(1270).
## 2025-04-15 Vladimir Ivanchenko (hadr-cohe-V11-03-00)
- G4ChargeExchange - fixed problem in kinematic computations, allowed recoil
nucleus to be in an excited state.
## 2024-11-15 Vladimir Ivanchenko (hadr-cohe-V11-02-03)
- G4ChargeExchange - fixed problem of the Hydrogen target; change event weight
if cross section biasing factor is applied
@@ -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;
}
@@ -6,7 +6,78 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2024-12-22 Vladimir Ivanchenko (hadr-deex-V11-02-19)
## 2025-06-18 Vladimir Ivanchenko (hadr-deex-V11-03-14)
- G4ExcitationHandler - fix initialisation of the new Fermi-BreakUp model
- G4FermiBreakUpAN - delete primary fragment, if decay is sucsessful - fixed
infinite loop in the new Fermi-BreakUp model
## 2025-06-04 Vladimir Ivanchenko (hadr-deex-V11-03-13)
- G4PhotonEvaporation, G4VEmissionProbability - check life time of final excitation
level, special treatment ground and the next level, attempt to fix #2660
## 2025-06-04 Vladimir Ivanchenko (hadr-deex-V11-03-12)
- G4FermiBreakUpAN - A.Novikov propose minor fix for final state generation
- G4DeexPrecoParameters - use the same set of parameters as in 11.3.2
- G4EvaporationProbability - fixed computation of inverse x-section
## 2025-05-22 Vladimir Ivanchenko (hadr-deex-V11-03-11)
- G4DeexPrecoUtility - a new class, which provide the same computation to avoid
code duplication
- G4DeexPrecoParameters - use conservative set of parameters
- G4VEmissionProbability - update parameters of integration of the probability
density function
- G4CoulombBarrier - code clean-up
- G4EvaporationProbability, G4ProtonEvaporationProbability,
G4DeuteronEvaporationProbability, G4TritonEvaporationProbability,
G4He3EvaporationProbability, G4AlphaEvaporationProbability
used G4DeexPrecoUtility
## 2025-05-01 Vladimir Ivanchenko (hadr-deex-V11-03-10)
- G4DeexPrecoParameters - added forgotten method
- G4VFermiFragmentAN, G4FermiBreakUpAN - fix Coverity warnings
## 2025-04-25 Vladimir Ivanchenko (hadr-deex-V11-03-09)
- G4FermiDataTypes - A. Novikov fixed compilation warnings at MAC
## 2025-04-04 Vladimir Ivanchenko (hadr-deex-V11-03-08)
- G4FermiBreakUpAN - new alternative FermiBreakUp model and supported classes
provided in github PR #84 by A. Novikov, Yandex and MIPT (January 2025) under
supervision of A. Svetlichnyi, INR RAS and MIPT. The model is based on
J.P. Bondorf et al., Physics Reports, 257(3):133221.
- G4ExcitationHandler, G4DeexPrecoParameters - updated initialisation
to switch between different FermiBreakUp models
## 2025-03-31 Vladimir Ivanchenko (hadr-deex-V11-03-07)
- G4LevelReader - attempt to fix Coverity warning.
## 2025-03-18 Vladimir Ivanchenko (hadr-deex-V11-03-06)
- G4GEMChannelVI, G4EvaporationGEMFactoryVI, G4DeexPrecoParameters - new GEM
de-excitation model with 83 decay channels (in the default 68 channels).
- G4Evaporation - improved debug printout.
## 2025-03-17 Vladimir Ivanchenko (hadr-deex-V11-03-05)
- G4StatMFMicroPartition - code cleanup, removed non-informative printout,
which may be repeated many times, instead stop MF model and return to
de-excitation handler.
## 2025-03-05 Vladimir Ivanchenko (hadr-deex-V11-03-04)
- G4VEmissionProbability - use the new utility class G4VSIntegration, which
allows to simplify code, results are practically not affected.
## 2025-02-15 Vladimir Ivanchenko (hadr-deex-V11-03-03)
- G4VEmissionProbability, G4EvaporationProbability, G4GEMProbabilityVI - updated
algorithms of integration of probabilities and sampling of kinetic energy of
emitted fragment (expected more accurate spectra).
## 2025-01-26 Vladimir Ivanchenko (hadr-deex-V11-03-02)
- G4DeexPrecoParameters - added extra enumerator to choose variant of the
pre-compound model.
## 2025-01-14 Vladimir Ivanchenko (hadr-deex-V11-03-01)
- G4NucLevel, G4PhotonEvaporation - use explicit type conversion from double
to float; use const arguments where possible.
## 2024-12-22 Vladimir Ivanchenko (hadr-deex-V11-03-00)
- G4ExcitationHandler, G4GammaTransition, G4PhotonEvaporation fixed problem
#2584 - removed production of unphysical states
@@ -34,6 +34,7 @@
// 17-11-2010 V.Ivanchenko integer Z and A
#include "G4AlphaEvaporationProbability.hh"
#include "G4DeexPrecoUtility.hh"
G4AlphaEvaporationProbability::G4AlphaEvaporationProbability() :
G4EvaporationProbability(4,2,1.0)
@@ -41,34 +42,7 @@ G4AlphaEvaporationProbability::G4AlphaEvaporationProbability() :
G4double G4AlphaEvaporationProbability::CalcAlphaParam(const G4Fragment& fr)
{
// Data comes from
// Dostrovsky, Fraenkel and Friedlander
// Physical Review, vol 116, num. 3 1959
//
// const G4int size = 5;
// G4double Zlist[5] = { 10.0, 20.0, 30.0, 50.0, 70.0};
// G4double Calpha[5] = { 0.10, 0.10, 0.10, 0.08, 0.06};
G4int aZ = fr.GetZ_asInt() - GetZ();
G4double C;
if (aZ <= 30)
{
C = 0.10;
}
else if (aZ <= 50)
{
C = 0.1 - (aZ-30)*0.001;
}
else if (aZ < 70)
{
C = 0.08 - (aZ-50)*0.001;
}
else
{
C = 0.06;
}
return 1.0 + C;
return 1.0 + G4DeexPrecoUtility::AlphaCValue(fr.GetZ_asInt() - 2);
}
G4double G4AlphaEvaporationProbability::CalcBetaParam(const G4Fragment &)
@@ -33,6 +33,7 @@
// 17-11-2010 V.Ivanchenko integer Z and A
#include "G4DeuteronEvaporationProbability.hh"
#include "G4DeexPrecoUtility.hh"
G4DeuteronEvaporationProbability::G4DeuteronEvaporationProbability() :
G4EvaporationProbability(2,1,3.0)
@@ -40,25 +41,7 @@ G4DeuteronEvaporationProbability::G4DeuteronEvaporationProbability() :
G4double G4DeuteronEvaporationProbability::CalcAlphaParam(const G4Fragment& fr)
{
// Data comes from
// Dostrovsky, Fraenkel and Friedlander
// Physical Review, vol 116, num. 3 1959
//
// const G4int size = 5;
// G4double Zlist[5] = { 10.0, 20.0, 30.0, 50.0, 70.0};
// G4double Cp[5] = { 0.50, 0.28, 0.20, 0.15, 0.10};
// C for deuteron is equal to C for protons divided by 2
G4int aZ = fr.GetZ_asInt()-GetZ();
G4double C;
if (aZ <= 70) {
C = 0.10;
} else {
C = ((((0.15417e-06*aZ) - 0.29875e-04)*aZ + 0.21071e-02)*aZ
- 0.66612e-01)*aZ + 0.98375;
}
return 1.0 + C*0.5;
return 1.0 + G4DeexPrecoUtility::ProtonCValue(fr.GetZ_asInt() - 1)*0.5;
}
G4double G4DeuteronEvaporationProbability::CalcBetaParam(const G4Fragment&)
@@ -214,7 +214,7 @@ void G4Evaporation::BreakFragment(G4FragmentVector* theResult,
// loop over evaporation channels
for(i=0; i<nChannels; ++i) {
prob = (*theChannels)[i]->GetEmissionProbability(theResidualNucleus);
if(fVerbose > 1 && prob > 0.0) {
if (fVerbose > 1 && prob > 0.0) {
G4cout << " Channel# " << i << " prob= " << prob << G4endl;
}
totprob += prob;
@@ -273,7 +273,10 @@ void G4Evaporation::BreakFragment(G4FragmentVector* theResult,
if (probabilities[i] >= totprob) { break; }
}
if(fVerbose > 1) { G4cout << "$$$ Channel # " << i << G4endl; }
if (fVerbose > 1) {
G4cout << "$$$ Selected Channel# " << i << " MaxChannel="
<< maxchannel << G4endl;
}
G4Fragment* frag = (*theChannels)[i]->EmittedFragment(theResidualNucleus);
if(fVerbose > 2 && frag) { G4cout << " " << *frag << G4endl; }
@@ -91,9 +91,9 @@ G4EvaporationProbability::G4EvaporationProbability(G4int anA, G4int aZ,
}
if (0 == aZ) {
ResetIntegrator(30, 0.15*CLHEP::MeV, 0.02);
ResetIntegrator(0.15*CLHEP::MeV, 0.01);
} else {
ResetIntegrator(30, 0.25*CLHEP::MeV, 0.03);
ResetIntegrator(0.20*CLHEP::MeV, 0.01);
}
}
@@ -169,37 +169,44 @@ G4double G4EvaporationProbability::TotalProbability(
return pProbability;
}
G4double G4EvaporationProbability::ComputeProbability(G4double K, G4double CB)
G4double G4EvaporationProbability::ComputeProbability(G4double kinE, G4double CB)
{
const G4double Kmin = 20*CLHEP::keV;
G4double K = std::max(kinE, Kmin);
// abnormal case - should never happens
if(pMass < pEvapMass + pResMass + K) { return 0.0; }
G4double pEvapM2 = pEvapMass*pEvapMass;
G4double mres = std::sqrt(pMass*pMass + pEvapM2 - 2.*pMass*(pEvapMass + K));
G4double K1 = pMass - pEvapMass - K;
G4double mres = std::sqrt(K1*K1 - K*(2*pEvapMass + K));
G4double excRes = mres - pResMass;
if (excRes < 0.0) { return 0.0; }
G4double K1 = (pMass*(K + pEvapMass) - pEvapM2)/mres - pEvapMass;
K1 = std::max(K1, 0.0);
G4double xs = CrossSection(K1, CB);
G4double K2 = 0.5*(pMass + pEvapMass + mres)*(pMass - pEvapMass - mres)/mres;
G4double xs = CrossSection(K2, CB);
if (xs <= 0.0) { return 0.0; }
a1 = pNuclearLevelData->GetLevelDensity(resZ, resA, excRes);
G4double E0 = std::max(freeU - delta0, 0.0);
G4double E1 = std::max(excRes - delta1, 0.0);
G4double prob = pcoeff*G4Exp(2.0*(std::sqrt(a1*E1) - std::sqrt(a0*E0)))*K1*xs;
G4double prob = pcoeff*G4Exp(2.0*(std::sqrt(a1*E1) - std::sqrt(a0*E0)))*K*xs;
return prob;
}
G4double
G4EvaporationProbability::CrossSection(G4double K, G4double CB)
G4EvaporationProbability::CrossSection(G4double kine, G4double CB)
{
const G4double Kmin = 20*CLHEP::keV;
G4double K = std::max(kine, Kmin);
// compute power once
if (OPTxs > 1 && 0 < index && resA != lastA) {
lastA = resA;
muu = G4KalbachCrossSection::ComputePowerParameter(resA, index);
}
if (OPTxs == 1) {
const G4double lim = 2*CLHEP::MeV;
G4double e1 = lowEnergyLimitMeV[theZ];
if (e1 == 0.0) { e1 = lim; }
K = std::max(K, e1);
recentXS = fXSection->GetElementCrossSection(K, resZ)/CLHEP::millibarn;
} else if (OPTxs == 2) {
@@ -34,6 +34,7 @@
// 17-11-2010 V.Ivanchenko integer Z and A
#include "G4He3EvaporationProbability.hh"
#include "G4DeexPrecoUtility.hh"
G4He3EvaporationProbability::G4He3EvaporationProbability() :
G4EvaporationProbability(3,2,2.0)
@@ -41,35 +42,7 @@ G4He3EvaporationProbability::G4He3EvaporationProbability() :
G4double G4He3EvaporationProbability::CalcAlphaParam(const G4Fragment& fr)
{
// Data comes from
// Dostrovsky, Fraenkel and Friedlander
// Physical Review, vol 116, num. 3 1959
//
// const G4int size = 5;
// G4double Zlist[5] = { 10.0, 20.0, 30.0, 50.0, 70.0};
// G4double Calpha[5] = { 0.10, 0.10, 0.10, 0.08, 0.06};
// C for He3 is equal to C for alpha times 4/3
G4int aZ = fr.GetZ_asInt() - GetZ();
G4double C;
if (aZ <= 30)
{
C = 0.10;
}
else if (aZ <= 50)
{
C = 0.1 - (aZ - 30)*0.001;
}
else if (aZ < 70)
{
C = 0.08 - (aZ - 50)*0.001;
}
else
{
C = 0.06;
}
return 1.0 + C*4/3.0;
return 1.0 + G4DeexPrecoUtility::AlphaCValue(fr.GetZ_asInt() - 2)*4.0/3.0;
}
G4double G4He3EvaporationProbability::CalcBetaParam(const G4Fragment & )
@@ -34,31 +34,19 @@
// 17-11-2010 V.Ivanchenko integer Z and A
#include "G4ProtonEvaporationProbability.hh"
#include "G4DeexPrecoUtility.hh"
G4ProtonEvaporationProbability::G4ProtonEvaporationProbability() :
G4EvaporationProbability(1,1,2.0)
{}
G4double
G4ProtonEvaporationProbability::CalcAlphaParam(const G4Fragment& fragment)
G4ProtonEvaporationProbability::CalcAlphaParam(const G4Fragment& fr)
{
// Data comes from
// Dostrovsky, Fraenkel and Friedlander
// Physical Review, vol 116, num. 3 1959
//
// const G4int size = 5;
// G4double Zlist[5] = { 10.0, 20.0, 30.0, 50.0, 70.0};
// G4double Cp[5] = { 0.50, 0.28, 0.20, 0.15, 0.10};
G4int aZ = fragment.GetZ_asInt()-GetZ();
G4double C = (aZ <= 70) ? 0.10 :
((((0.15417e-06*aZ) - 0.29875e-04)*aZ + 0.21071e-02)*aZ - 0.66612e-01)*aZ
+ 0.98375;
return 1.0 + C;
return 1.0 + G4DeexPrecoUtility::ProtonCValue(fr.GetZ_asInt() - 1);
}
G4double G4ProtonEvaporationProbability::CalcBetaParam(const G4Fragment & )
G4double G4ProtonEvaporationProbability::CalcBetaParam(const G4Fragment& )
{
return 0.0;
}
@@ -34,6 +34,7 @@
// 17-11-2010 V.Ivanchenko integer Z and A
#include "G4TritonEvaporationProbability.hh"
#include "G4DeexPrecoUtility.hh"
G4TritonEvaporationProbability::G4TritonEvaporationProbability() :
G4EvaporationProbability(3,1,2.0)
@@ -41,21 +42,7 @@ G4TritonEvaporationProbability::G4TritonEvaporationProbability() :
G4double G4TritonEvaporationProbability::CalcAlphaParam(const G4Fragment& fr)
{
// Data comes from
// Dostrovsky, Fraenkel and Friedlander
// Physical Review, vol 116, num. 3 1959
//
// const G4int size = 5;
// G4double Zlist[5] = { 10.0, 20.0, 30.0, 50.0, 70.0};
// G4double Cp[5] = { 0.50, 0.28, 0.20, 0.15, 0.10};
// C for triton is equal to C for protons divided by 3
G4int aZ = fr.GetZ_asInt()-GetZ();
G4double C = (aZ <= 70) ? 0.10 :
((((0.15417e-06*aZ) - 0.29875e-04)*aZ + 0.21071e-02)*aZ
- 0.66612e-01)*aZ + 0.98375;
return 1.0 + C/3.0;
return 1.0 + G4DeexPrecoUtility::ProtonCValue(fr.GetZ_asInt() - 1)/3.0;
}
G4double G4TritonEvaporationProbability::CalcBetaParam(const G4Fragment& )
@@ -0,0 +1,102 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// G4FermiBreakUpAN is an alternative realisation of Fermi Break Up
// de-excitation by A. Novikov, Yandex and MIPT (January 2025)
// under supervision of Aleksandr Svetlichnyi, INR RAS and MIPT
//
// The model originally developed in J.P. Bondorf, A.S. Botvina, A.S. Iljinov,
// I.N. Mishustin, and K. Sneppen, "Statistical multifragmentation of nuclei."
// Physics Reports, 257(3):133221, Jun 1995.
// https://doi.org/10.1016/0370-1573(94)00097-M, doi:10.1016/0370-1573(94)00097-m.
//
#ifndef G4FERMIBREAKUPAN_HH
#define G4FERMIBREAKUPAN_HH
#include "G4FermiDataTypes.hh"
#include "G4FermiParticle.hh"
#include "G4FermiSplitter.hh"
#include "G4VFermiBreakUp.hh"
#include "globals.hh"
#include <memory>
class G4FermiBreakUpAN : public G4VFermiBreakUp
{
private:
class PossibleSplits
{
private:
using NucleiSplits = std::vector<G4FermiFragmentVector>;
public:
PossibleSplits() = default;
PossibleSplits& operator=(PossibleSplits&&) noexcept = default;
PossibleSplits(const G4FermiAtomicMass maxAtomicMass);
const NucleiSplits& GetSplits(const G4FermiAtomicMass atomicMass,
const G4FermiChargeNumber chargeNumber) const;
void InsertSplits(const G4FermiAtomicMass atomicMass,
const G4FermiChargeNumber chargeNumber,
NucleiSplits&& splits);
private:
std::vector<NucleiSplits> splits_;
};
public:
explicit G4FermiBreakUpAN(G4int verbosity = 0);
~G4FermiBreakUpAN() override = default;
void Initialise() override;
// check if the Fermi Break Up model can be used
G4bool IsApplicable(G4int Z, G4int A, G4double eexc) const override;
// vector of products is added to the provided vector
// if no decay channel is found out for the primary fragment
// then it is added to the results vector
// if primary decays then it is deleted
void BreakFragment(G4FragmentVector* results, G4Fragment* theNucleus) override;
std::vector<G4FermiParticle> BreakItUp(const G4FermiParticle& nucleus) const;
private:
std::vector<G4FermiParticle> SplitToParticles(const G4FermiParticle& sourceParticle,
const G4FermiFragmentVector& split) const;
// improve performance, reusing allocated memory
mutable std::vector<G4double> weights_;
PossibleSplits splits_;
G4int secID_;
G4int verbosity_ = 0;
};
#endif // G4FERMIBREAKUP_HH
@@ -0,0 +1,186 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// G4FermiBreakUpAN alternative FermiBreakUp model
// by A. Novikov (January 2025)
//
#ifndef G4FERMIDATATYPES_HH
#define G4FERMIDATATYPES_HH
#include "G4LorentzVector.hh"
#include "G4ThreeVector.hh"
#include "globals.hh"
namespace
{
static constexpr G4int MAX_Z = 9;
static constexpr G4int MAX_A = 17;
}
class G4FermiAtomicMass
{
public:
using ValueType = std::uint32_t;
G4FermiAtomicMass() = default;
explicit constexpr G4FermiAtomicMass(ValueType mass) : mass_(mass) {}
G4FermiAtomicMass(const G4FermiAtomicMass& other) = default;
G4FermiAtomicMass(G4FermiAtomicMass&& other) = default;
G4FermiAtomicMass& operator=(const G4FermiAtomicMass& other) = default;
G4FermiAtomicMass& operator=(G4FermiAtomicMass&& other) = default;
constexpr operator std::uint32_t() const { return mass_; }
constexpr operator G4int() const { return mass_; }
constexpr operator G4double() const { return mass_; }
G4bool operator<(const G4FermiAtomicMass& other) const { return mass_ < other.mass_; }
G4bool operator>(const G4FermiAtomicMass& other) const { return mass_ > other.mass_; }
G4bool operator<=(const G4FermiAtomicMass& other) const { return mass_ <= other.mass_; }
G4bool operator>=(const G4FermiAtomicMass& other) const { return mass_ >= other.mass_; }
G4bool operator==(const G4FermiAtomicMass& other) const { return mass_ == other.mass_; }
G4bool operator!=(const G4FermiAtomicMass& other) const { return mass_ != other.mass_; }
private:
ValueType mass_;
};
class G4FermiChargeNumber
{
public:
using ValueType = std::uint32_t;
G4FermiChargeNumber() = default;
explicit constexpr G4FermiChargeNumber(ValueType charge) : charge_(charge) {}
G4FermiChargeNumber(const G4FermiChargeNumber& other) = default;
G4FermiChargeNumber(G4FermiChargeNumber&& other) = default;
G4FermiChargeNumber& operator=(const G4FermiChargeNumber& other) = default;
G4FermiChargeNumber& operator=(G4FermiChargeNumber&& other) = default;
constexpr operator std::uint32_t() const { return charge_; }
constexpr operator G4int() const { return charge_; }
constexpr operator G4double() const { return charge_; }
G4bool operator<(const G4FermiChargeNumber& other) const { return charge_ < other.charge_; }
G4bool operator>(const G4FermiChargeNumber& other) const { return charge_ > other.charge_; }
G4bool operator<=(const G4FermiChargeNumber& other) const { return charge_ <= other.charge_; }
G4bool operator>=(const G4FermiChargeNumber& other) const { return charge_ >= other.charge_; }
G4bool operator==(const G4FermiChargeNumber& other) const { return charge_ == other.charge_; }
G4bool operator!=(const G4FermiChargeNumber& other) const { return charge_ != other.charge_; }
private:
ValueType charge_;
};
struct G4FermiNucleiData
{
G4FermiAtomicMass atomicMass;
G4FermiChargeNumber chargeNumber;
G4bool operator<(const G4FermiNucleiData& other) const
{
return atomicMass < other.atomicMass
|| (atomicMass == other.atomicMass && chargeNumber < other.chargeNumber);
}
G4bool operator==(const G4FermiNucleiData& other) const
{
return atomicMass == other.atomicMass && chargeNumber == other.chargeNumber;
}
G4bool operator!=(const G4FermiNucleiData& other) const
{
return atomicMass != other.atomicMass || chargeNumber != other.chargeNumber;
}
};
namespace std
{
template<>
struct hash<G4FermiNucleiData>
{
std::size_t operator()(const G4FermiNucleiData& key) const
{
auto mass = G4int(key.atomicMass);
auto charge = G4int(key.chargeNumber);
return (mass * (mass + 1)) / 2 + charge;
}
};
std::string to_string(G4FermiAtomicMass mass);
std::string to_string(G4FermiChargeNumber charge);
std::ostream& operator<<(std::ostream& out, const G4FermiAtomicMass& mass);
std::istream& operator>>(std::istream& in, G4FermiAtomicMass& mass);
std::ostream& operator<<(std::ostream& out, const G4FermiChargeNumber& charge);
std::istream& operator>>(std::istream& in, G4FermiChargeNumber& charge);
} // namespace std
constexpr G4FermiAtomicMass operator""_m(unsigned long long mass)
{
return G4FermiAtomicMass(static_cast<std::uint32_t>(mass));
}
constexpr G4FermiChargeNumber operator""_c(unsigned long long charge)
{
return G4FermiChargeNumber(static_cast<std::uint32_t>(charge));
}
#define FERMI_ASSERT_MSG(COND, MSG) \
if (!(COND)) { \
G4ExceptionDescription ed; \
ed << "assertion failed: \"" << #COND << '\"' << " at " << __FILE__ << ':' << __LINE__ \
<< '\n' \
<< MSG; \
G4Exception("G4FermiBreakUpAN: ", "fermi03", FatalException, ed, ""); \
}
#endif // G4FERMIDATATYPES_HH
@@ -0,0 +1,124 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// G4FermiBreakUpAN alternative de-excitation model
// by A. Novikov (January 2025)
//
#ifndef G4FERMIFRAGMENTPOOLAN_HH
#define G4FERMIFRAGMENTPOOLAN_HH
#include "G4FermiDataTypes.hh"
#include "G4VFermiFragmentAN.hh"
#include "globals.hh"
class G4FermiFragmentPoolAN
{
private:
using Container = std::vector<const G4VFermiFragmentAN*>;
public:
class DefaultPoolANSource : private std::vector<G4VFermiFragmentAN*>
{
private:
using PoolANContainer = std::vector<G4VFermiFragmentAN*>;
public:
DefaultPoolANSource();
void Initialize();
using PoolANContainer::begin;
using PoolANContainer::cbegin;
using PoolANContainer::cend;
using PoolANContainer::end;
};
class IteratorRange
{
public:
using const_iterator = Container::const_iterator;
IteratorRange(const_iterator begin, const_iterator end) : begin_(begin), end_(end) {}
const_iterator begin() const { return begin_; }
const_iterator end() const { return end_; }
private:
const_iterator begin_;
const_iterator end_;
};
std::size_t Count(G4FermiAtomicMass atomicMass, G4FermiChargeNumber chargeNumber) const;
std::size_t Count(G4FermiNucleiData nuclei) const
{
return Count(nuclei.atomicMass, nuclei.chargeNumber);
}
IteratorRange GetFragments(G4FermiAtomicMass atomicMass,
G4FermiChargeNumber chargeNumber) const;
IteratorRange GetFragments(G4FermiNucleiData nuclei) const
{
return GetFragments(nuclei.atomicMass, nuclei.chargeNumber);
}
template<typename DataSource>
void Initialize(const DataSource& dataSource)
{
Initialize(dataSource.begin(), dataSource.end());
}
template<typename Iter>
void Initialize(Iter begin, Iter end)
{
fragments_.clear();
static_assert(
std::is_same_v<std::remove_const_t<typename Iter::value_type>, G4VFermiFragmentAN*>,
"invalid iterator");
for (auto it = begin; it != end; ++it) {
AddFragment(**it);
}
}
void AddFragment(const G4VFermiFragmentAN& fragment);
static G4FermiFragmentPoolAN& Instance()
{
static G4FermiFragmentPoolAN pool;
return pool;
}
private:
G4FermiFragmentPoolAN();
static inline const Container EmptyContainer_ = {};
std::vector<Container> fragments_;
};
#endif // G4FERMIFRAGMENTPOOL_HH
@@ -0,0 +1,94 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// G4FermiBreakUpAN alternative FermiBreakUp model
// by A. Novikov (January 2025)
//
#ifndef G4INTEGERPARTITION_HH
#define G4INTEGERPARTITION_HH
#include "globals.hh"
#include <vector>
using G4FermiPartition = std::vector<std::uint32_t>;
class G4integerPartition
{
public:
class Iterator;
Iterator begin() const;
Iterator end() const;
G4integerPartition(std::uint32_t number, std::uint32_t termsCount, std::uint32_t base = 1);
private:
std::uint32_t number_;
std::uint32_t termsCount_;
std::uint32_t base_;
};
class G4integerPartition::Iterator
{
public:
friend class G4integerPartition;
using difference_type = std::int64_t;
using value_type = G4FermiPartition;
using reference = const G4FermiPartition&;
using pointer = const G4FermiPartition*;
using iterator_category = std::forward_iterator_tag;
Iterator(const Iterator&) = default;
Iterator& operator=(const Iterator&) = default;
pointer operator->() const;
reference operator*() const;
Iterator& operator++();
Iterator operator++(int);
G4bool operator==(const Iterator& other) const;
G4bool operator!=(const Iterator& other) const;
private:
// represents end partition
Iterator() = default;
Iterator(std::uint32_t number, std::uint32_t termsCount, std::uint32_t base);
void NextPartition();
G4FermiPartition partition_;
};
#endif // G4intEGERPARTITION_HH
@@ -0,0 +1,101 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// G4FermiBreakUpAN alternative FermiBreakUp model
// by A. Novikov (January 2025)
//
#ifndef G4FERMINUCLEIPROPERTIES_HH
#define G4FERMINUCLEIPROPERTIES_HH
#include "G4FermiDataTypes.hh"
#include "globals.hh"
#include <vector>
// Caches values from larger G4NucleiProperties(x5-10 speed boost)
class G4FermiNucleiProperties
{
public:
void Initialize() { *this = G4FermiNucleiProperties(); }
template<typename DataSource>
void Initialize(const DataSource& dataSource)
{
Initialize(dataSource.begin(), dataSource.end());
}
template<typename Iter>
void Initialize(Iter begin, Iter end)
{
nucleiMasses_.clear();
static_assert(
std::is_same_v<typename Iter::value_type, std::pair<const G4FermiNucleiData, G4double>>,
"invalid iterator");
for (auto it = begin; it != end; ++it) {
InsertNuclei(it->first.atomicMass, it->first.chargeNumber, it->second);
}
}
static G4double GetNuclearMass(G4FermiAtomicMass atomicMass, G4FermiChargeNumber chargeNumber)
{
return Instance().GetNuclearMassImpl(atomicMass, chargeNumber);
}
static G4bool IsStable(G4FermiAtomicMass atomicMass, G4FermiChargeNumber chargeNumber)
{
return Instance().IsStableImpl(atomicMass, chargeNumber);
}
void InsertNuclei(G4FermiAtomicMass atomicMass, G4FermiChargeNumber chargeNumber, G4double mass,
G4bool isStable = true);
static G4FermiNucleiProperties& Instance()
{
static G4FermiNucleiProperties properties;
return properties;
}
private:
G4FermiNucleiProperties();
G4double GetNuclearMassImpl(G4FermiAtomicMass atomicMass,
G4FermiChargeNumber chargeNumber) const;
G4bool IsStableImpl(G4FermiAtomicMass atomicMass, G4FermiChargeNumber chargeNumber) const;
struct G4FermiMassData
{
G4double mass;
G4bool isStable = false; // is nuclei stable
G4bool isCached = false; // value has been inserted earlier
};
mutable std::vector<G4FermiMassData> nucleiMasses_;
};
#endif // G4FERMINUCLEIPROPERTIES_HH
@@ -0,0 +1,75 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// G4FermiBreakUpAN alternative de-excitation model
// by A. Novikov (January 2025)
//
#ifndef G4FERMIPARTICLE_HH
#define G4FERMIPARTICLE_HH
#include "G4FermiDataTypes.hh"
class G4FermiParticle
{
public:
G4FermiParticle() = delete;
G4FermiParticle(const G4FermiParticle&) = default;
G4FermiParticle(G4FermiParticle&&) = default;
G4FermiParticle& operator=(const G4FermiParticle&) = default;
G4FermiParticle& operator=(G4FermiParticle&&) = default;
G4FermiParticle(G4FermiAtomicMass atomicMass, G4FermiChargeNumber chargeNumber,
const G4LorentzVector& momentum);
G4FermiAtomicMass GetAtomicMass() const;
G4FermiChargeNumber GetChargeNumber() const;
const G4LorentzVector& GetMomentum() const;
G4double GetExcitationEnergy() const;
G4bool IsStable() const;
private:
void RecalculateExcitationEnergy();
G4FermiAtomicMass atomicMass_;
G4FermiChargeNumber chargeNumber_;
G4LorentzVector momentum_;
G4double excitationEnergy_ = 0;
};
namespace std
{
ostream& operator<<(ostream&, const G4FermiParticle&);
} // namespace std
#endif // G4FERMIPARTICLE_HH
@@ -23,14 +23,33 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
/*
# <<BEGIN-copyright>>
# <<END-copyright>>
*/
#ifndef G4GIDI_mass_h_included
#define G4GIDI_mass_h_included 1
//
// G4FermiBreakUpAN alternative FermiBreakUp model
// by A. Novikov (January 2025)
//
double G4GIDI_targetMass( const char *targetSymbol );
double G4GIDI_Z_AMass( int iZ, int iA );
#ifndef G4FERMIPHASEDECAY_HH
#define G4FERMIPHASEDECAY_HH
#endif // End of G4GIDI_mass_h_included
#include "G4HadPhaseSpaceKopylov.hh"
class G4FermiPhaseDecay
{
public:
std::vector<G4LorentzVector> CalculateDecay(const G4LorentzVector& totalMomentum,
const std::vector<G4double>& fragmentsMass) const
{
std::vector<G4LorentzVector> results;
KopylovDecay().Generate(totalMomentum.m(), fragmentsMass, results);
return results;
}
private:
static G4HadPhaseSpaceKopylov& KopylovDecay()
{
static G4HadPhaseSpaceKopylov phaseDecay;
return phaseDecay;
}
};
#endif // G4FERMIPHASEDECAY_HH
@@ -23,45 +23,32 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
/*
# <<BEGIN-copyright>>
# <<END-copyright>>
*/
#include "G4GIDI_map.hh"
//
// G4FermiBreakUpAN alternative de-excitation model
// by A. Novikov (January 2025)
//
using namespace GIDI;
#ifndef G4FERMISPLITTER_HH
#define G4FERMISPLITTER_HH
/*
***************************************************************
*/
G4GIDI_map::G4GIDI_map( const std::string &dataDirectory ) {
#include "G4FermiDataTypes.hh"
#include "G4VFermiFragmentAN.hh"
#include "globals.hh"
smr_initialize( &smr, smr_status_Ok, 0 );
map = MCGIDI_map_readFile( &smr, NULL, dataDirectory.c_str( ) );
if( !smr_isOk( &smr ) ) {
smr_print( &smr, 1 );
throw 1;
}
}
/*
***************************************************************
*/
G4GIDI_map::~G4GIDI_map( void ) {
class G4FermiSplitter
{
public:
static G4double DecayWeight(const G4FermiFragmentVector& split, G4FermiAtomicMass atomicMass,
G4double totalEnergy);
if( map != NULL ) MCGIDI_map_free( NULL, map );
smr_release( &smr );
}
/*
***************************************************************
*/
std::string G4GIDI_map::fileName( void ) {
static G4double SplitFactor(const G4FermiFragmentVector& split, G4FermiAtomicMass atomicMass);
return( map->mapFileName );
}
/*
***************************************************************
*/
std::string G4GIDI_map::path( void ) {
static G4double KineticFactor(const G4FermiFragmentVector& split, G4double totalEnergy);
return( map->path );
}
static void GenerateSplits(G4FermiNucleiData nucleiData,
std::vector<G4FermiFragmentVector>& splits);
static std::vector<G4FermiFragmentVector> GenerateSplits(G4FermiNucleiData nucleiData);
};
#endif // G4FERMISPLITTER_HH
@@ -23,29 +23,28 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
/*
# <<BEGIN-copyright>>
# <<END-copyright>>
*/
#ifndef G4GIDI_map_h_included
#define G4GIDI_map_h_included 1
//
// G4FermiBreakUpAN alternative FermiBreakUp model
// by A. Novikov (January 2025)
//
#include <string>
//using namespace std;
#ifndef G4FERMISTABLEFRAGMENT_HH
#define G4FERMISTABLEFRAGMENT_HH
#include <MCGIDI_map.h>
#include "G4VFermiFragmentAN.hh"
class G4GIDI_map {
class G4FermiStableFragment : public G4VFermiFragmentAN
{
public:
public:
GIDI::statusMessageReporting smr;
GIDI::MCGIDI_map *map;
G4FermiStableFragment(G4FermiAtomicMass atomicMass, G4FermiChargeNumber chargeNumber,
G4int polarization, G4double excitationEnergy);
G4GIDI_map( const std::string &dataDirectory );
~G4GIDI_map( );
void AppendDecayFragments(const G4LorentzVector& momentum,
std::vector<G4FermiParticle>& fragments) const override;
std::string path( void );
std::string fileName( void );
private:
void DoInitialize() override;
};
#endif // End of G4GIDI_map_h_included
#endif // G4FERMISTABLEFRAGMENT_HH
@@ -0,0 +1,90 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// G4FermiBreakUpAN alternative FermiBreakUp model
// by A. Novikov (January 2025)
//
#ifndef G4FERMIUNSTABLEFRAGMENT_HH
#define G4FERMIUNSTABLEFRAGMENT_HH
#include "G4VFermiFragmentAN.hh"
class G4FermiUnstableFragment : public G4VFermiFragmentAN
{
public:
G4FermiUnstableFragment(G4FermiAtomicMass atomicMass, G4FermiChargeNumber chargeNumber,
G4int polarization, G4double excitationEnergy,
std::vector<G4FermiNucleiData>&& decayData);
void AppendDecayFragments(const G4LorentzVector& momentum,
std::vector<G4FermiParticle>& particles) const override;
private:
void DoInitialize() override;
std::vector<G4FermiNucleiData> decayData_;
std::vector<G4double> masses_;
};
#define FERMI_ADD_UNSTABLE_FRAGMENT(NAME, FRAGMENTS) \
inline G4FermiUnstableFragment NAME(G4FermiAtomicMass atomicMass, \
G4FermiChargeNumber chargeNumber, G4int polarization, \
G4double excitationEnergy) \
{ \
return G4FermiUnstableFragment(atomicMass, chargeNumber, polarization, excitationEnergy, \
FRAGMENTS); \
}
// He5 ----> alpha + neutron
FERMI_ADD_UNSTABLE_FRAGMENT(He5Fragment, std::vector<G4FermiNucleiData>({
G4FermiNucleiData{4_m, 2_c},
G4FermiNucleiData{1_m, 0_c},
}))
// B9 ----> alpha + alpha + proton
FERMI_ADD_UNSTABLE_FRAGMENT(B9Fragment, std::vector<G4FermiNucleiData>({
G4FermiNucleiData{4_m, 2_c},
G4FermiNucleiData{4_m, 2_c},
G4FermiNucleiData{1_m, 1_c},
}))
// Be8 ----> alpha + alpha
FERMI_ADD_UNSTABLE_FRAGMENT(Be8Fragment, std::vector<G4FermiNucleiData>({
G4FermiNucleiData{4_m, 2_c},
G4FermiNucleiData{4_m, 2_c},
}))
// Li5 ----> alpha + proton
FERMI_ADD_UNSTABLE_FRAGMENT(Li5Fragment, std::vector<G4FermiNucleiData>({
G4FermiNucleiData{4_m, 2_c},
G4FermiNucleiData{1_m, 1_c},
}))
#undef FERMI_ADD_UNSTABLE_FRAGMENT
#endif // G4FERMIUNSTABLEFRAGMENT_HH
@@ -44,18 +44,18 @@ public:
G4VFermiBreakUp() {};
virtual ~G4VFermiBreakUp() = default;
virtual void Initialise() = 0;
virtual void Initialise() {};
// check if the Fermi Break Up model can be used
// mass is an effective mass of a fragment
virtual G4bool IsApplicable(G4int Z, G4int A, G4double eexc) const = 0;
virtual G4bool IsApplicable(G4int /*Z*/, G4int /*A*/, G4double /*Eexc*/) const
{ return false; };
// vector of products is added to the provided vector
// if no decay channel is found out for the primary fragment
// then it is added to the results vector
// if primary decays then it is deleted
virtual void BreakFragment(G4FragmentVector* results,
G4Fragment* theNucleus) = 0;
virtual void BreakFragment(G4FragmentVector* /*results*/,
G4Fragment* /*theNucleus*/) {};
G4VFermiBreakUp(const G4VFermiBreakUp &right) = delete;
const G4VFermiBreakUp & operator=(const G4VFermiBreakUp &right) = delete;
@@ -0,0 +1,91 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// G4FermiBreakUpAN alternative FermiBreakUp model
// by A. Novikov (January 2025)
//
#ifndef G4VFERMIFRAGMENTAN_HH
#define G4VFERMIFRAGMENTAN_HH
#include "G4FermiDataTypes.hh"
#include "G4FermiParticle.hh"
#include "globals.hh"
#include <vector>
class G4VFermiFragmentAN;
using G4FermiFragmentVector = std::vector<const G4VFermiFragmentAN*>;
class G4VFermiFragmentAN
{
public:
G4VFermiFragmentAN(G4FermiAtomicMass atomicMass, G4FermiChargeNumber chargeNumber,
G4int polarization, G4double excitationEnergy);
G4VFermiFragmentAN(const G4VFermiFragmentAN&) = delete;
G4VFermiFragmentAN& operator=(const G4VFermiFragmentAN&) = delete;
~G4VFermiFragmentAN() = default;
void Initialize();
std::vector<G4FermiParticle> GetDecayFragments(const G4LorentzVector& momentum) const;
virtual void AppendDecayFragments(const G4LorentzVector& momentum,
std::vector<G4FermiParticle>& particles) const = 0;
G4FermiAtomicMass GetAtomicMass() const;
G4FermiChargeNumber GetChargeNumber() const;
G4int GetPolarization() const;
G4double GetExcitationEnergy() const;
G4double GetMass() const;
G4double GetTotalEnergy() const;
protected:
virtual void DoInitialize() = 0;
G4FermiAtomicMass atomicMass_; // A
G4FermiChargeNumber chargeNumber_; // Z
G4int polarization_;
G4double groudStateMass_;
G4double excitationEnergy_;
};
namespace std
{
ostream& operator<<(ostream&, const G4VFermiFragmentAN&);
} // namespace std
#endif // G4VFERMIFRAGMENTAN_HH
@@ -4,20 +4,41 @@
geant4_add_module(G4hadronic_deex_fermi_breakup
PUBLIC_HEADERS
G4FermiBreakUpUtil.hh
G4FermiBreakUpAN.hh
G4FermiBreakUpVI.hh
G4FermiChannels.hh
G4FermiDataTypes.hh
G4FermiFragment.hh
G4FermiFragmentPoolAN.hh
G4FermiFragmentsPoolVI.hh
G4FermiIntegerPartition.hh
G4FermiNucleiProperties.hh
G4FermiPair.hh
G4FermiParticle.hh
G4FermiPhaseDecay.hh
G4FermiPhaseSpaceDecay.hh
G4FermiSplitter.hh
G4FermiStableFragment.hh
G4FermiUnstableFragment.hh
G4VFermiBreakUp.hh
G4VFermiFragmentAN.hh
SOURCES
G4FermiBreakUpUtil.cc
G4FermiBreakUpAN.cc
G4FermiBreakUpVI.cc
G4FermiDataTypes.cc
G4FermiFragment.cc
G4FermiFragmentPoolAN.cc
G4FermiFragmentsPoolVI.cc
G4FermiIntegerPartition.cc
G4FermiNucleiProperties.cc
G4FermiPair.cc
G4FermiPhaseSpaceDecay.cc)
G4FermiParticle.cc
G4FermiPhaseSpaceDecay.cc
G4FermiSplitter.cc
G4FermiStableFragment.cc
G4FermiUnstableFragment.cc
G4VFermiFragmentAN.cc)
geant4_module_link_libraries(G4hadronic_deex_fermi_breakup
PUBLIC
@@ -26,5 +47,6 @@ geant4_module_link_libraries(G4hadronic_deex_fermi_breakup
G4hepgeometry
G4heprandom
PRIVATE
G4baryons
G4hadronic_deex_management
G4partman)
@@ -0,0 +1,298 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// G4FermiBreakUpAN alternative FermiBreakUp model
// by A. Novikov (January 2025)
//
#include "G4FermiBreakUpAN.hh"
#include "G4FermiDataTypes.hh"
#include "G4FermiFragmentPoolAN.hh"
#include "G4FermiNucleiProperties.hh"
#include "G4FermiParticle.hh"
#include "G4FermiPhaseDecay.hh"
#include "G4FermiSplitter.hh"
#include "G4VFermiFragmentAN.hh"
#include "G4BaryonConstructor.hh"
#include "G4NucleiProperties.hh"
#include "G4PhysicalConstants.hh"
#include "G4PhysicsModelCatalog.hh"
#include "G4ThreeVector.hh"
#include "Randomize.hh"
#include <numeric>
#include <functional>
#ifdef G4VERBOSE
# define G4FERMI_VERBOSE 1
#else
# define G4FERMI_VERBOSE 0
#endif
#define FERMI_LOG_MSG(verbosity, level, msg) \
do { \
if (G4FERMI_VERBOSE) { \
if ((verbosity) >= (level)) { \
G4cout << __FILE__ << ':' << __LINE__ << " in function \"" << __FUNCTION__ << "\"\n" \
<< msg << G4endl; \
} \
} \
} while (0)
constexpr G4int FERMI_DEBUG = 2;
#define FERMI_LOG_WARN(verbosity, msg) FERMI_LOG_MSG(verbosity, FERMI_WARN, msg)
#define FERMI_LOG_DEBUG(verbosity, msg) FERMI_LOG_MSG(verbosity, FERMI_DEBUG, msg)
namespace
{
constexpr const char* SPACES_OFFSET = " ";
std::size_t SampleWeightDistribution(const std::vector<G4double>& weights)
{
const auto totalWeight = std::accumulate(weights.begin(), weights.end(), 0.);
FERMI_ASSERT_MSG(totalWeight > 0., "Invalid weights: all values are zero");
const auto targetWeight = G4RandFlat::shoot() * totalWeight;
G4double cummulativeWeight = 0;
for (std::size_t i = 0; i < weights.size(); ++i) {
cummulativeWeight += weights[i];
if (cummulativeWeight >= targetWeight) {
return i;
}
}
return weights.size() - 1;
}
G4String LogProducts(const std::vector<G4FermiParticle>& particles)
{
std::ostringstream out;
out << "[\n";
for (const auto& particle : particles) {
out << SPACES_OFFSET << particle << ";\n";
}
out << "]";
return std::move(out).str();
}
G4LorentzVector ChangeFrameOfReference(const G4LorentzVector& vec, const G4ThreeVector& boost)
{
auto copy = vec;
copy.boost(boost);
return copy;
}
G4String LogSplit(const G4FermiFragmentVector& split)
{
std::ostringstream out;
out << "[\n";
for (const auto fragmentPtr : split) {
out << SPACES_OFFSET << *fragmentPtr << ";\n";
}
out << "]";
return std::move(out).str();
}
std::size_t GetSlot(G4FermiAtomicMass atomicMass, G4FermiChargeNumber chargeNumber)
{
const auto mass = static_cast<std::uint32_t>(atomicMass);
const auto charge = static_cast<std::uint32_t>(chargeNumber);
return (mass * (mass + 1)) / 2 + charge;
}
} // namespace
G4FermiBreakUpAN::PossibleSplits::PossibleSplits(const G4FermiAtomicMass maxAtomicMass)
{
const auto maxMass = static_cast<std::uint32_t>(maxAtomicMass);
splits_.resize(maxMass * (maxMass + 1) / 2);
}
const std::vector<G4FermiFragmentVector>&
G4FermiBreakUpAN::PossibleSplits::GetSplits(const G4FermiAtomicMass atomicMass,
const G4FermiChargeNumber chargeNumber) const
{
const auto slot = GetSlot(atomicMass, chargeNumber);
return splits_.at(slot);
}
void G4FermiBreakUpAN::PossibleSplits::InsertSplits(const G4FermiAtomicMass atomicMass,
const G4FermiChargeNumber chargeNumber,
std::vector<G4FermiFragmentVector>&& splits)
{
const auto slot = GetSlot(atomicMass, chargeNumber);
if (slot >= splits_.size()) {
splits_.resize(slot + static_cast<std::uint32_t>(atomicMass));
}
splits_[slot] = std::move(splits);
}
G4FermiBreakUpAN::G4FermiBreakUpAN(G4int verbosity)
: splits_(G4FermiAtomicMass(MAX_A)),
secID_(G4PhysicsModelCatalog::GetModelID("model_G4FermiBreakUpVI")),
verbosity_(verbosity)
{}
std::vector<G4FermiParticle> G4FermiBreakUpAN::BreakItUp(const G4FermiParticle& particle) const
{
FERMI_LOG_DEBUG(verbosity_, "Breaking up particle: " << particle);
if (particle.GetExcitationEnergy() < 0.) {
FERMI_LOG_DEBUG(verbosity_, "G4FermiParticle is stable with excitation energy = "
<< particle.GetExcitationEnergy());
return {particle};
}
const auto& splits = splits_.GetSplits(particle.GetAtomicMass(), particle.GetChargeNumber());
FERMI_LOG_DEBUG(verbosity_,
"Selecting Split for " << particle << " from " << splits.size() << " splits");
if (splits.empty()) {
FERMI_LOG_DEBUG(verbosity_, "No splits found");
return {particle};
}
// get phase space weights for every split
// we can't cache them, because calculations is probabilistic
weights_.resize(splits.size());
std::transform(splits.begin(), splits.end(), weights_.begin(),
[atomicMass = particle.GetAtomicMass(),
totalEnergy = particle.GetMomentum().m()](const auto& split) {
return G4FermiSplitter::DecayWeight(split, atomicMass, totalEnergy);
});
if (std::all_of(weights_.begin(), weights_.end(), [](auto weight) { return weight == 0.; })) {
FERMI_LOG_DEBUG(verbosity_, "Every split has zero weight");
return {particle};
}
const auto& chosenSplit = splits[SampleWeightDistribution(weights_)];
FERMI_LOG_DEBUG(verbosity_,
"From " << splits.size() << " splits chosen split: " << LogSplit(chosenSplit));
return SplitToParticles(particle, chosenSplit);
}
void G4FermiBreakUpAN::Initialise()
{
if (G4NucleiProperties::GetNuclearMass(2, 0) <= 0.) {
G4BaryonConstructor pCBar;
pCBar.ConstructParticle();
}
G4FermiNucleiProperties::Instance().Initialize();
{
auto pool = G4FermiFragmentPoolAN::DefaultPoolANSource();
pool.Initialize();
G4FermiFragmentPoolAN::Instance().Initialize(pool);
}
// order is important here, we use G4FermiFragmentPool to create splits!
splits_ = PossibleSplits();
for (auto a = 1; a < MAX_A; ++a) {
for (auto z = 0; z <= a; ++z) {
const auto atomicMass = G4FermiAtomicMass(a);
const auto chargeNumber = G4FermiChargeNumber(z);
splits_.InsertSplits(atomicMass, chargeNumber,
G4FermiSplitter::GenerateSplits({atomicMass, chargeNumber}));
}
}
}
G4bool G4FermiBreakUpAN::IsApplicable(G4int Z, G4int A, G4double /* eexc */) const
{
return Z < MAX_Z && A < MAX_A;
}
void G4FermiBreakUpAN::BreakFragment(G4FragmentVector* results, G4Fragment* theNucleus)
{
if (theNucleus == nullptr || results == nullptr) {
G4ExceptionDescription ed;
ed << "G4Fragment or result G4FragmentVector is not set in FermiBreakUp";
G4Exception("G4FermiBreakUpAN::BreakFragment()", "Fermi003", FatalErrorInArgument, ed);
return;
}
const auto particle =
G4FermiParticle(G4FermiAtomicMass(theNucleus->GetA_asInt()),
G4FermiChargeNumber(theNucleus->GetZ_asInt()), theNucleus->GetMomentum());
const auto fragments = BreakItUp(particle);
// decay impossible
if (fragments.size() <= 1) { return; }
const auto creationTime = theNucleus->GetCreationTime();
// primary should be deleted
delete theNucleus;
for (const auto& fragment : fragments) {
auto fr = new G4Fragment(static_cast<G4int>(fragment.GetAtomicMass()),
static_cast<G4int>(fragment.GetChargeNumber()),
fragment.GetMomentum());
results->push_back(fr);
fr->SetCreationTime(creationTime);
fr->SetCreatorModelID(secID_);
}
}
std::vector<G4FermiParticle>
G4FermiBreakUpAN::SplitToParticles(const G4FermiParticle& sourceParticle,
const G4FermiFragmentVector& split) const
{
std::vector<G4double> splitMasses(split.size());
std::transform(split.begin(), split.end(), splitMasses.begin(),
std::mem_fn(&G4VFermiFragmentAN::GetTotalEnergy));
G4FermiPhaseDecay phaseSampler;
std::vector<G4LorentzVector> particlesMomentum
= phaseSampler.CalculateDecay(sourceParticle.GetMomentum(), splitMasses);
if (particlesMomentum.empty()) {
return {sourceParticle};
}
// Go back to the Lab Frame
std::vector<G4FermiParticle> particleSplit;
particleSplit.reserve(2 * split.size());
const auto boostVector = sourceParticle.GetMomentum().boostVector();
for (std::size_t fragmentIdx = 0; fragmentIdx < split.size(); ++fragmentIdx) {
const auto fragmentMomentum =
ChangeFrameOfReference(particlesMomentum[fragmentIdx], boostVector);
split[fragmentIdx]->AppendDecayFragments(fragmentMomentum, particleSplit);
}
FERMI_LOG_DEBUG(verbosity_, "Break up products: " << LogProducts(particleSplit));
return particleSplit;
}
@@ -71,7 +71,7 @@ void G4FermiBreakUpVI::Initialise()
fElim = param->GetFBUEnergyLimit();
fTimeLim = param->GetMaxLifeTime();
if (verbose > 1) {
G4cout << "### G4FermiBreakUpVI::Initialise(): the pool is initilized="
G4cout << "### G4FermiBreakUpVI::Initialise(): the pool is initialized="
<< fPool->IsInitialized() << " fTolerance(eV)=" << fTolerance/CLHEP::eV
<< " Elim(MeV)=" << fElim/CLHEP::MeV << G4endl;
}
@@ -0,0 +1,69 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// G4FermiBreakUpAN alternative FermiBreakUp model
// by A. Novikov (January 2025)
//
#include "G4FermiDataTypes.hh"
std::string std::to_string(G4FermiAtomicMass mass)
{
return std::to_string(G4FermiAtomicMass::ValueType(mass));
}
std::string std::to_string(G4FermiChargeNumber charge)
{
return std::to_string(G4FermiChargeNumber::ValueType(charge));
}
std::ostream& std::operator<<(std::ostream& out, const G4FermiAtomicMass& mass)
{
out << G4FermiAtomicMass::ValueType(mass);
return out;
}
std::istream& std::operator>>(std::istream& in, G4FermiAtomicMass& mass)
{
G4FermiAtomicMass::ValueType val;
in >> val;
mass = G4FermiAtomicMass(val);
return in;
}
std::ostream& std::operator<<(std::ostream& out, const G4FermiChargeNumber& charge)
{
out << G4FermiChargeNumber::ValueType(charge);
return out;
}
std::istream& std::operator>>(std::istream& in, G4FermiChargeNumber& charge)
{
G4FermiChargeNumber::ValueType val;
in >> val;
charge = G4FermiChargeNumber(val);
return in;
}
@@ -0,0 +1,236 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// G4FermiBreakUpAN alternative FermiBreakUp model
// by A. Novikov (January 2025)
//
//
// Created by Artem Novikov on 30.01.2024.
//
#include "G4FermiFragmentPoolAN.hh"
#include "G4FermiDataTypes.hh"
#include "G4VFermiFragmentAN.hh"
#include "G4FermiStableFragment.hh"
#include "G4FermiUnstableFragment.hh"
#include "G4PhysicalConstants.hh"
#include "G4SystemOfUnits.hh"
namespace
{
std::size_t GetSlot(G4FermiAtomicMass atomicMass, G4FermiChargeNumber chargeNumber)
{
const auto mass = static_cast<std::uint32_t>(atomicMass);
const auto charge = static_cast<std::uint32_t>(chargeNumber);
return (mass * (mass + 1)) / 2 + charge;
}
} // namespace
G4FermiFragmentPoolAN::G4FermiFragmentPoolAN()
{
auto pool = G4FermiFragmentPoolAN::DefaultPoolANSource();
pool.Initialize();
Initialize(pool);
}
std::size_t G4FermiFragmentPoolAN::Count(G4FermiAtomicMass atomicMass,
G4FermiChargeNumber chargeNumber) const
{
// if (unlikely(static_cast<std::uint32_t>(atomicMass) < static_cast<std::uint32_t>(chargeNumber)))
if (static_cast<std::uint32_t>(atomicMass) < static_cast<std::uint32_t>(chargeNumber)) {
return 0;
}
const auto slot = GetSlot(atomicMass, chargeNumber);
// if (unlikely(slot >= fragments_.size())) {
if (slot >= fragments_.size()) {
return 0;
}
return fragments_[slot].size();
}
G4FermiFragmentPoolAN::IteratorRange
G4FermiFragmentPoolAN::GetFragments(G4FermiAtomicMass atomicMass,
G4FermiChargeNumber chargeNumber) const
{
// if (unlikely(static_cast<std::uint32_t>(atomicMass) < static_cast<std::uint32_t>(chargeNumber)))
if (static_cast<std::uint32_t>(atomicMass) < static_cast<std::uint32_t>(chargeNumber)) {
return {EmptyContainer_.begin(), EmptyContainer_.end()};
}
const auto slot = GetSlot(atomicMass, chargeNumber);
if (slot >= fragments_.size()) {
return {EmptyContainer_.begin(), EmptyContainer_.end()};
}
return {fragments_[slot].begin(), fragments_[slot].end()};
}
void G4FermiFragmentPoolAN::AddFragment(const G4VFermiFragmentAN& fragment)
{
const auto slot = GetSlot(fragment.GetAtomicMass(), fragment.GetChargeNumber());
if (slot >= fragments_.size()) {
fragments_.resize(slot + static_cast<std::uint32_t>(fragment.GetAtomicMass()));
}
fragments_[slot].push_back(&fragment);
}
G4FermiFragmentPoolAN::DefaultPoolANSource::DefaultPoolANSource()
{
#define FERMI_CONCAT(x, y) x##y
#define FERMI_INSTANTIATE_MACRO(x, y) FERMI_CONCAT(x, y)
#define FERMI_ADD_FRAGMENT_IMPL(NAME, VALUE) \
static auto NAME = VALUE; \
push_back(&NAME);
// automatic unique names are added
#define FERMI_ADD_FRAGMENT(VALUE) \
FERMI_ADD_FRAGMENT_IMPL(FERMI_INSTANTIATE_MACRO(G4VFermiFragmentAN, __COUNTER__), VALUE)
FERMI_ADD_FRAGMENT(G4FermiStableFragment(1_m, 0_c, 2, 0.00 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(1_m, 1_c, 2, 0.00 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(2_m, 1_c, 3, 0.00 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(3_m, 1_c, 2, 0.00 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(3_m, 2_c, 2, 0.00 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(4_m, 2_c, 1, 0.00 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(He5Fragment(5_m, 2_c, 4, 16.76 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(Li5Fragment(5_m, 3_c, 4, 16.66 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(6_m, 2_c, 1, 0.00 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(6_m, 3_c, 3, 0.00 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(6_m, 3_c, 1, 3.56 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(7_m, 3_c, 4, 0.00 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(7_m, 3_c, 2, 0.48 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(7_m, 4_c, 4, 0.00 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(7_m, 4_c, 2, 0.43 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(8_m, 3_c, 5, 0.00 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(8_m, 3_c, 3, 0.98 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(Be8Fragment(8_m, 4_c, 1, 0.00 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(9_m, 4_c, 4, 0.00 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(B9Fragment(9_m, 5_c, 4, 0.00 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(10_m, 4_c, 1, 0.00 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(10_m, 4_c, 5, 3.37 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(10_m, 4_c, 8, 5.96 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(10_m, 4_c, 1, 6.18 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(10_m, 4_c, 5, 6.26 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(10_m, 5_c, 7, 0.00 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(10_m, 5_c, 3, 0.72 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(10_m, 5_c, 1, 1.74 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(10_m, 5_c, 3, 2.15 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(10_m, 5_c, 5, 3.59 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(10_m, 6_c, 3, 0.00 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(10_m, 6_c, 5, 3.35 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(11_m, 5_c, 4, 0.00 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(11_m, 5_c, 2, 2.13 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(11_m, 5_c, 6, 4.44 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(11_m, 5_c, 4, 5.02 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(11_m, 5_c, 10, 6.76 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(11_m, 5_c, 6, 7.29 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(11_m, 5_c, 4, 7.98 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(11_m, 5_c, 6, 8.56 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(11_m, 6_c, 4, 0.00 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(11_m, 6_c, 2, 2.00 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(11_m, 6_c, 6, 4.32 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(11_m, 6_c, 4, 4.80 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(11_m, 6_c, 2, 6.34 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(11_m, 6_c, 8, 6.48 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(11_m, 6_c, 6, 6.90 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(11_m, 6_c, 4, 7.50 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(11_m, 6_c, 4, 8.10 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(11_m, 6_c, 6, 8.42 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(11_m, 6_c, 8, 8.66 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(12_m, 5_c, 3, 0.00 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(12_m, 5_c, 5, 0.95 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(12_m, 5_c, 5, 1.67 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(12_m, 5_c, 4, 2.65 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(12_m, 6_c, 1, 0.00 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(12_m, 6_c, 5, 4.44 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(13_m, 6_c, 2, 0.00 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(13_m, 6_c, 2, 3.09 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(13_m, 6_c, 4, 3.68 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(13_m, 6_c, 6, 3.85 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(13_m, 7_c, 2, 0.00 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(14_m, 6_c, 1, 0.00 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(14_m, 6_c, 3, 6.09 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(14_m, 6_c, 8, 6.69 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(14_m, 6_c, 6, 6.96 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(14_m, 6_c, 5, 7.34 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(14_m, 7_c, 3, 0.00 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(14_m, 7_c, 1, 2.31 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(14_m, 7_c, 3, 3.95 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(14_m, 7_c, 1, 4.92 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(14_m, 7_c, 5, 5.11 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(14_m, 7_c, 3, 5.69 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(14_m, 7_c, 7, 5.83 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(14_m, 7_c, 3, 6.20 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(14_m, 7_c, 7, 6.44 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(14_m, 7_c, 5, 7.03 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(15_m, 7_c, 2, 0.00 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(15_m, 7_c, 8, 5.28 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(15_m, 7_c, 4, 6.32 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(15_m, 7_c, 10, 7.22 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(15_m, 7_c, 8, 7.57 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(15_m, 7_c, 2, 8.31 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(15_m, 7_c, 4, 8.57 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(15_m, 7_c, 14, 9.15 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(15_m, 7_c, 14, 9.79 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(15_m, 7_c, 8, 10.00 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(15_m, 8_c, 2, 0.00 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(15_m, 8_c, 8, 5.22 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(15_m, 8_c, 4, 6.18 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(15_m, 8_c, 10, 6.83 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(15_m, 8_c, 8, 7.28 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(16_m, 7_c, 5, 0.00 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(16_m, 7_c, 1, 0.12 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(16_m, 7_c, 7, 0.30 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(16_m, 7_c, 3, 0.40 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(16_m, 8_c, 1, 0.00 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(16_m, 8_c, 8, 6.10 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(16_m, 8_c, 5, 6.92 * CLHEP::MeV));
FERMI_ADD_FRAGMENT(G4FermiStableFragment(16_m, 8_c, 3, 7.12 * CLHEP::MeV));
#undef FERMI_ADD_FRAGMENT
#undef FERMI_ADD_FRAGMENT_IMPL
#undef FERMI_INSTANTIATE_MACRO
#undef FERMI_CONCAT
}
void G4FermiFragmentPoolAN::DefaultPoolANSource::Initialize()
{
for (auto & fragmentPtr : *this) {
fragmentPtr->Initialize();
}
}
@@ -0,0 +1,117 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// G4FermiBreakUpAN alternative de-excitation model
// by A. Novikov (January 2025)
//
#include "G4FermiIntegerPartition.hh"
G4integerPartition::G4integerPartition(std::uint32_t number, std::uint32_t termsCount,
std::uint32_t base)
: number_(number), termsCount_(termsCount), base_(base)
{}
G4integerPartition::Iterator G4integerPartition::begin() const
{
return {number_, termsCount_, base_};
}
G4integerPartition::Iterator G4integerPartition::end() const
{
return {};
}
/////////////////////////////////// ITERATOR //////////////////////////////
G4integerPartition::Iterator::pointer G4integerPartition::Iterator::operator->() const
{
return &partition_;
}
G4integerPartition::Iterator::reference G4integerPartition::Iterator::operator*() const
{
return partition_;
}
G4integerPartition::Iterator& G4integerPartition::Iterator::operator++()
{
NextPartition();
return *this;
}
G4integerPartition::Iterator G4integerPartition::Iterator::operator++(int)
{
auto copy = *this;
NextPartition();
return copy;
}
G4bool G4integerPartition::Iterator::operator==(const G4integerPartition::Iterator& other) const
{
return partition_ == other.partition_;
}
G4bool G4integerPartition::Iterator::operator!=(const G4integerPartition::Iterator& other) const
{
return partition_ != other.partition_;
}
G4integerPartition::Iterator::Iterator(std::uint32_t number, std::uint32_t termsCount,
std::uint32_t base)
: partition_(termsCount, 0)
{
// No possible partitions
if (number < base * termsCount || termsCount == 0 || number == 0) {
return;
}
std::fill(partition_.begin(), partition_.end(), base);
partition_[0] = number - base * (termsCount - 1);
}
void G4integerPartition::Iterator::NextPartition()
{
std::uint32_t accumulated = 0;
for (auto partitionLast = std::next(partition_.begin()); partitionLast != partition_.end();
++partitionLast)
{
if (partition_.front() >= *partitionLast + 2) {
--partition_.front();
++(*partitionLast);
auto newValue = *partitionLast;
std::fill(std::next(partition_.begin()), partitionLast, newValue);
partition_.front() +=
accumulated - newValue * (std::distance(partition_.begin(), partitionLast) - 1);
return;
}
accumulated += *partitionLast;
}
// last partition
partition_.clear();
}
@@ -0,0 +1,106 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// G4FermiBreakUpAN alternative FermiBreakUp model
// by A. Novikov (January 2025)
//
#include "G4FermiNucleiProperties.hh"
#include <G4BaryonConstructor.hh>
#include <G4NucleiProperties.hh>
#include <G4PhysicalConstants.hh>
namespace
{
std::size_t GetSlot(G4FermiAtomicMass atomicMass, G4FermiChargeNumber chargeNumber)
{
const auto mass = static_cast<std::uint32_t>(atomicMass);
const auto charge = static_cast<std::uint32_t>(chargeNumber);
return (mass * (mass + 1)) / 2 + charge;
}
} // namespace
G4FermiNucleiProperties::G4FermiNucleiProperties()
{
for (auto a = 1; a < MAX_A; ++a) {
for (auto z = 0; z <= a; ++z) {
const auto atomicMass = G4FermiAtomicMass(a);
const auto chargeNumber = G4FermiChargeNumber(z);
const auto mass = G4NucleiProperties::GetNuclearMass(a, z);
if (mass > 0.) {
InsertNuclei(atomicMass, chargeNumber, mass, G4NucleiProperties::IsInStableTable(a, z));
}
}
}
}
G4double G4FermiNucleiProperties::GetNuclearMassImpl(G4FermiAtomicMass atomicMass,
G4FermiChargeNumber chargeNumber) const
{
FERMI_ASSERT_MSG(static_cast<std::uint32_t>(atomicMass)
>= static_cast<std::uint32_t>(chargeNumber),
"invalid nuclei A = " << atomicMass << ", Z = " << chargeNumber);
const auto slot = GetSlot(atomicMass, chargeNumber);
if (slot < nucleiMasses_.size() && nucleiMasses_[slot].isCached) {
return nucleiMasses_[slot].mass;
}
return G4NucleiProperties::GetNuclearMass(G4int(atomicMass), G4int(chargeNumber));
}
G4bool G4FermiNucleiProperties::IsStableImpl(G4FermiAtomicMass atomicMass,
G4FermiChargeNumber chargeNumber) const
{
if (atomicMass < 1_m || chargeNumber < 0_c
|| static_cast<std::uint32_t>(chargeNumber)
> static_cast<std::uint32_t>(atomicMass))
{
return false;
}
const auto slot = GetSlot(atomicMass, chargeNumber);
return slot < nucleiMasses_.size() && nucleiMasses_[slot].isStable;
}
void G4FermiNucleiProperties::InsertNuclei(G4FermiAtomicMass atomicMass,
G4FermiChargeNumber chargeNumber, G4double mass,
G4bool isStable)
{
const auto slot = GetSlot(atomicMass, chargeNumber);
if (slot >= nucleiMasses_.size()) {
nucleiMasses_.resize(slot + static_cast<std::uint32_t>(atomicMass));
}
nucleiMasses_[slot] = G4FermiMassData{
mass, // mass
isStable, // isStable
true, // isCached
};
}
@@ -0,0 +1,111 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// G4FermiBreakUpAN alternative de-excitation model
// by A. Novikov (January 2025)
//
#include "G4FermiParticle.hh"
#include "G4FermiDataTypes.hh"
#include "G4FermiNucleiProperties.hh"
#include <G4PhysicalConstants.hh>
#include <iomanip>
G4FermiParticle::G4FermiParticle(G4FermiAtomicMass atomicMass, G4FermiChargeNumber chargeNumber,
const G4LorentzVector& momentum)
: atomicMass_(atomicMass), chargeNumber_(chargeNumber), momentum_(momentum)
{
FERMI_ASSERT_MSG(static_cast<std::uint32_t>(atomicMass_)
>= static_cast<std::uint32_t>(chargeNumber),
"imposible particle: A = " << atomicMass_ << ", Z = " << chargeNumber);
RecalculateExcitationEnergy();
}
G4FermiAtomicMass G4FermiParticle::GetAtomicMass() const
{
return atomicMass_;
}
G4FermiChargeNumber G4FermiParticle::GetChargeNumber() const
{
return chargeNumber_;
}
const G4LorentzVector& G4FermiParticle::GetMomentum() const
{
return momentum_;
}
G4double G4FermiParticle::GetExcitationEnergy() const
{
return excitationEnergy_;
}
G4bool G4FermiParticle::IsStable() const
{
return excitationEnergy_ <= 0.;
}
void G4FermiParticle::RecalculateExcitationEnergy()
{
excitationEnergy_ =
momentum_.mag() - G4FermiNucleiProperties::GetNuclearMass(atomicMass_, chargeNumber_);
if (excitationEnergy_ < 0.) {
if (excitationEnergy_ < -10.0 * CLHEP::eV) {
G4ExceptionDescription ed;
ed << "Excitation energy is too negative: " << excitationEnergy_ / CLHEP::MeV << " MeV";
G4Exception("G4FermiParticle::RecalculateExcitationEnergy()", "Fermi001", JustWarning, ed);
}
excitationEnergy_ = 0.;
}
}
std::ostream& std::operator<<(std::ostream& out, const G4FermiParticle& particle)
{
const auto oldFlags = out.flags();
const auto oldUserPrecision = out.precision();
out.setf(std::ios::floatfield);
out << "FermiParticle: { A = " << particle.GetAtomicMass()
<< ", Z = " << particle.GetChargeNumber();
out.setf(std::ios::scientific, std::ios::floatfield);
out << std::setprecision(3) << ", U = " << particle.GetExcitationEnergy() / CLHEP::MeV << " MeV"
<< ", IsGroundState = " << (particle.IsStable() ? "yes" : "no") << ", P = ("
<< particle.GetMomentum().x() / CLHEP::MeV << ", " << particle.GetMomentum().y() / CLHEP::MeV
<< ", " << particle.GetMomentum().z() / CLHEP::MeV
<< ") MeV, E = " << particle.GetMomentum().t() / CLHEP::MeV << " MeV}"
<< " }";
out.setf(oldFlags, std::ios::floatfield);
out.precision(oldUserPrecision);
return out;
}
@@ -36,12 +36,12 @@
#include "G4FermiPhaseSpaceDecay.hh"
#include "Randomize.hh"
#include "G4RandomDirection.hh"
#include "G4Pow.hh"
#include <CLHEP/Units/SystemOfUnits.h>
#include <CLHEP/Units/PhysicalConstants.h>
#include <CLHEP/Random/RandomEngine.h>
#include "G4SystemOfUnits.hh"
#include "G4PhysicalConstants.hh"
G4FermiPhaseSpaceDecay::G4FermiPhaseSpaceDecay()
{
@@ -0,0 +1,304 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// G4FermiBreakUpAN alternative de-excitation model
// by A. Novikov (January 2025)
//
#include "G4FermiSplitter.hh"
#include "G4FermiDataTypes.hh"
#include "G4FermiFragmentPoolAN.hh"
#include "G4FermiIntegerPartition.hh"
#include "G4VFermiFragmentAN.hh"
#include <G4PhysicalConstants.hh>
#include <iterator>
#include <numeric>
#include <optional>
#include <functional>
namespace
{
// Kappa = V/V_0 it is used in calculation of Coulomb energy, Kappa is dimensionless
constexpr G4double Kappa = 1.0;
// Nuclear radius R0 (is a model parameter)
constexpr G4double R0 = 1.3 * CLHEP::fermi;
G4double CoulombBarrier(const G4FermiFragmentVector& split)
{
// Coulomb Barrier (MeV) for given channel with K fragments.
static const G4double COEF =
(3. / 5.) * (CLHEP::elm_coupling / R0) * std::cbrt(1. / (1. + Kappa));
std::uint32_t atomicMassSum = 0.;
std::uint32_t chargeSum = 0.;
G4double CoulombEnergy = 0.;
for (const auto fragmentPtr : split) {
auto mass = static_cast<std::uint32_t>(fragmentPtr->GetAtomicMass());
auto charge = static_cast<std::uint32_t>(fragmentPtr->GetChargeNumber());
CoulombEnergy += std::pow(charge, 2) / std::cbrt(static_cast<G4double>(mass));
atomicMassSum += mass;
chargeSum += charge;
}
CoulombEnergy -=
std::pow(static_cast<G4double>(chargeSum), 2) / std::cbrt(static_cast<G4double>(atomicMassSum));
return -COEF * CoulombEnergy;
}
G4double SpinFactor(const G4FermiFragmentVector& split)
{
G4double factor = 1;
for (const auto fragmentPtr : split) {
factor *= fragmentPtr->GetPolarization();
}
return factor;
}
G4double KineticEnergy(const G4FermiFragmentVector& split, G4double totalEnergy)
{
auto kineticEnergy = totalEnergy;
for (const auto fragmentPtr : split) {
kineticEnergy -= fragmentPtr->GetTotalEnergy();
}
// skip columb calculation for optimization purposes
if (kineticEnergy <= 0.) {
return kineticEnergy;
}
return kineticEnergy - CoulombBarrier(split);
}
G4double MassFactor(const G4FermiFragmentVector& split)
{
G4double massSum = 0.;
G4double massProduct = 1.;
for (const auto fragmentPtr : split) {
const auto fragmentMass = fragmentPtr->GetMass();
massProduct *= fragmentMass;
massSum += fragmentMass;
}
auto massFactor = massProduct / massSum;
massFactor *= std::sqrt(massFactor);
return massFactor;
}
std::size_t Factorial(const std::size_t n)
{
std::size_t factorial = 1;
for (std::size_t i = 2; i <= n; ++i) {
factorial *= i;
}
return factorial;
}
G4double ConfigurationFactor(const G4FermiFragmentVector& split)
{
// get all mass numbers and count repetitions
std::vector<G4FermiAtomicMass> masses(split.size());
std::transform(split.begin(), split.end(), masses.begin(),
std::mem_fn(&G4VFermiFragmentAN::GetAtomicMass));
std::sort(masses.begin(), masses.end());
// avoid overflow with floats
// TODO: optimize with ints maybe
G4double factor = 1;
std::size_t repeatCount = 1; // we skip first, so start with 1
for (std::size_t i = 1; i < masses.size(); ++i) {
if (masses[i] != masses[i - 1]) {
factor *= static_cast<G4double>(Factorial(repeatCount));
repeatCount = 0;
}
++repeatCount;
}
factor *= static_cast<G4double>(Factorial(repeatCount));
return factor;
}
G4double ConstFactor(G4FermiAtomicMass atomicMass, std::size_t fragmentsCount)
{
static const G4double COEF =
std::pow(R0 / CLHEP::hbarc, 3) * Kappa * std::sqrt(2.0 / CLHEP::pi) / 3.0;
return std::pow(COEF * static_cast<G4double>(atomicMass), fragmentsCount - 1);
}
G4double GammaFactor(std::size_t fragmentsCount)
{
G4double gamma = 1.0;
G4double arg = 3.0 * static_cast<G4double>(fragmentsCount - 1) / 2.0 - 1.0;
while (arg > 1.1) {
gamma *= arg;
arg -= 1;
}
if (fragmentsCount % 2 == 0) {
gamma *= std::sqrt(CLHEP::pi);
}
return gamma;
}
} // namespace
G4double G4FermiSplitter::DecayWeight(const G4FermiFragmentVector& split,
G4FermiAtomicMass atomicMass, G4double totalEnergy)
{
const auto kineticEnergy = KineticEnergy(split, totalEnergy); // in MeV
// Check that there is enough energy to produce K fragments
if (kineticEnergy <= 0.) {
return 0.;
}
const auto power = 3.0 * static_cast<G4double>(split.size() - 1) / 2.0 - 1.;
const auto kineticFactor = std::pow(kineticEnergy, power);
// Spin factor S_n
const auto spinFactor = SpinFactor(split);
// Calculate MassFactor
const auto massFactor = MassFactor(split);
// This is the constant (doesn't depend on energy) part
const auto coef = ConstFactor(atomicMass, split.size());
// Calculation of 1/gamma(3(k-1)/2)
const auto gamma = GammaFactor(split.size());
// Permutation Factor G_n
const auto permutationFactor = ConfigurationFactor(split);
return coef * kineticFactor * massFactor * spinFactor / (permutationFactor * gamma);
}
namespace
{
constexpr std::size_t ExpectedSplitSize = 100;
void ThrowOnInvalidInputs(G4FermiNucleiData nucleiData)
{
FERMI_ASSERT_MSG(nucleiData.atomicMass > 0_m && nucleiData.chargeNumber >= 0_c,
"Non valid arguments A = " << nucleiData.atomicMass
<< " Z = " << nucleiData.chargeNumber);
FERMI_ASSERT_MSG(static_cast<std::uint32_t>(nucleiData.chargeNumber)
<= static_cast<std::uint32_t>(nucleiData.atomicMass),
"Non physical arguments = " << nucleiData.atomicMass
<< " Z = " << nucleiData.chargeNumber);
}
std::vector<G4FermiFragmentVector> PossibleSplits(const G4FermiPartition& massPartition,
const G4FermiPartition& chargePartition)
{
auto& fragmentPool = G4FermiFragmentPoolAN::Instance();
const auto fragmentCount = massPartition.size();
// count all possible splits due to multiplicity of fragments
std::size_t splitsCount = 1;
for (std::size_t fragmentIdx = 0; fragmentIdx < fragmentCount; ++fragmentIdx) {
splitsCount *= fragmentPool.Count(G4FermiAtomicMass(massPartition[fragmentIdx]),
G4FermiChargeNumber(chargePartition[fragmentIdx]));
if (splitsCount == 0) {
return {};
}
}
// allocate in advance
std::vector<G4FermiFragmentVector> splits(splitsCount, G4FermiFragmentVector(fragmentCount));
// incrementally build splits
// !! chosen order matters, because later there we need to remove duplicates
std::size_t groupSize = splitsCount;
for (std::size_t fragmentIdx = 0; fragmentIdx < fragmentCount; ++fragmentIdx) {
const auto fragmentRange =
fragmentPool.GetFragments(G4FermiAtomicMass(massPartition[fragmentIdx]),
G4FermiChargeNumber(chargePartition[fragmentIdx]));
// no remainder here!
const std::size_t multiplicity = std::distance(fragmentRange.begin(), fragmentRange.end());
groupSize /= multiplicity;
for (std::size_t offset = 0; offset < splitsCount;) {
for (const auto fragmentPtr : fragmentRange) {
for (std::size_t pos = 0; pos < groupSize; ++pos) {
splits[offset + pos][fragmentIdx] = fragmentPtr;
}
offset += groupSize;
}
}
}
// remove duplicate splits
for (auto& split : splits) {
std::sort(split.begin(), split.end(), std::greater<>());
// greater, because they already partially sorted as greater due to integer partition
}
const auto uniqueEndIt = std::unique(splits.begin(), splits.end());
splits.resize(uniqueEndIt - splits.begin());
return splits;
}
} // namespace
std::vector<G4FermiFragmentVector> G4FermiSplitter::GenerateSplits(G4FermiNucleiData nucleiData)
{
std::vector<G4FermiFragmentVector> splits;
GenerateSplits(nucleiData, splits);
return splits;
}
void G4FermiSplitter::GenerateSplits(G4FermiNucleiData nucleiData,
std::vector<G4FermiFragmentVector>& splits)
{
ThrowOnInvalidInputs(nucleiData);
splits.reserve(ExpectedSplitSize);
// let's split nucleus into 2, ..., A fragments
const auto maxFragmentsCount = static_cast<std::uint32_t>(nucleiData.atomicMass);
for (std::uint32_t fragmentCount = 2; fragmentCount <= maxFragmentsCount; ++fragmentCount) {
// Form all possible partition by combination of A partitions and Z partitions (Z partitions
// include null parts)
for (auto& massPartition : G4integerPartition(nucleiData.atomicMass, fragmentCount, 1)) {
for (auto& chargePartition : G4integerPartition(nucleiData.chargeNumber, fragmentCount, 0)) {
// Some splits are invalid, some nuclei doesn't exist
if (auto partitionSplits = PossibleSplits(massPartition, chargePartition);
!partitionSplits.empty()) {
splits.insert(splits.end(), std::make_move_iterator(partitionSplits.begin()),
std::make_move_iterator(partitionSplits.end()));
}
}
}
}
}
@@ -23,17 +23,22 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
/*
# <<BEGIN-copyright>>
# <<END-copyright>>
*/
#ifndef G4GIDI_Misc_h_included
#define G4GIDI_Misc_h_included 1
//
// G4FermiBreakUpAN alternative FermiBreakUp model
// by A. Novikov (January 2025)
//
#include <MCGIDI_map.h>
#include "G4FermiStableFragment.hh"
char *G4GIDI_Misc_Z_A_m_ToName( int iZ, int iA, int im = 0 );
char *G4GIDI_Misc_channelCompound( char *particle1, char *particle2 );
int getNamesOfAvailableTargets_walker( GIDI::MCGIDI_mapEntry *entry, int level, void *userData );
G4FermiStableFragment::G4FermiStableFragment(G4FermiAtomicMass atomicMass, G4FermiChargeNumber chargeNumber,
G4int polarization, G4double excitationEnergy)
: G4VFermiFragmentAN(atomicMass, chargeNumber, polarization, excitationEnergy)
{}
#endif // End of G4GIDI_Misc_h_included
void G4FermiStableFragment::AppendDecayFragments(const G4LorentzVector& momentum,
std::vector<G4FermiParticle>& fragments) const
{
fragments.emplace_back(G4FermiParticle(GetAtomicMass(), GetChargeNumber(), momentum));
}
void G4FermiStableFragment::DoInitialize() {}
@@ -0,0 +1,66 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// G4FermiBreakUpAN alternative FermiBreakUp model
// by A. Novikov (January 2025)
//
#include "G4FermiUnstableFragment.hh"
#include "G4FermiNucleiProperties.hh"
#include "G4FermiPhaseDecay.hh"
G4FermiUnstableFragment::G4FermiUnstableFragment(G4FermiAtomicMass atomicMass,
G4FermiChargeNumber chargeNumber,
G4int polarization, G4double excitationEnergy,
std::vector<G4FermiNucleiData>&& decayData)
: G4VFermiFragmentAN(atomicMass, chargeNumber, polarization, excitationEnergy),
decayData_(std::move(decayData))
{}
void G4FermiUnstableFragment::AppendDecayFragments(const G4LorentzVector& momentum,
std::vector<G4FermiParticle>& fragments) const
{
G4FermiPhaseDecay phaseDecay;
auto fragmentsMomentum = phaseDecay.CalculateDecay(momentum, masses_);
const auto boostVector = momentum.boostVector();
for (std::size_t i = 0; i < decayData_.size(); ++i) {
fragments.emplace_back(decayData_[i].atomicMass, decayData_[i].chargeNumber,
fragmentsMomentum[i].boost(boostVector));
}
}
void G4FermiUnstableFragment::DoInitialize()
{
masses_.clear();
masses_.reserve(decayData_.size());
for (const auto& decayFragment : decayData_) {
masses_.emplace_back(G4FermiNucleiProperties::GetNuclearMass(decayFragment.atomicMass,
decayFragment.chargeNumber));
}
}
@@ -0,0 +1,110 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// G4FermiBreakUpAN alternative FermiBreakUp model
// by A. Novikov (January 2025)
//
#include "G4VFermiFragmentAN.hh"
#include "G4FermiNucleiProperties.hh"
#include "G4PhysicalConstants.hh"
#include "G4SystemOfUnits.hh"
#include "Randomize.hh"
#include <iomanip>
G4VFermiFragmentAN::G4VFermiFragmentAN(G4FermiAtomicMass atomicMass,
G4FermiChargeNumber chargeNumber,
G4int polarization, G4double excitationEnergy)
: atomicMass_(atomicMass),
chargeNumber_(chargeNumber),
polarization_(polarization),
excitationEnergy_(excitationEnergy)
{
groudStateMass_ = CLHEP::proton_mass_c2;
}
void G4VFermiFragmentAN::Initialize()
{
groudStateMass_ = G4FermiNucleiProperties::GetNuclearMass(atomicMass_, chargeNumber_);
DoInitialize();
}
std::vector<G4FermiParticle>
G4VFermiFragmentAN::GetDecayFragments(const G4LorentzVector& momentum) const
{
std::vector<G4FermiParticle> result;
AppendDecayFragments(momentum, result);
return result;
}
G4FermiAtomicMass G4VFermiFragmentAN::GetAtomicMass() const
{
return atomicMass_;
}
G4FermiChargeNumber G4VFermiFragmentAN::GetChargeNumber() const
{
return chargeNumber_;
}
G4int G4VFermiFragmentAN::GetPolarization() const
{
return polarization_;
}
G4double G4VFermiFragmentAN::GetExcitationEnergy() const
{
return excitationEnergy_;
}
G4double G4VFermiFragmentAN::GetMass() const
{
return groudStateMass_;
}
G4double G4VFermiFragmentAN::GetTotalEnergy() const
{
return GetMass() + GetExcitationEnergy();
}
std::ostream& std::operator<<(std::ostream& out, const G4VFermiFragmentAN& fragment)
{
const auto oldFlags = out.flags();
const auto oldUserPrecision = out.precision();
out.setf(std::ios::floatfield);
out << "FermiFragment: { A = " << fragment.GetAtomicMass()
<< ", Z = " << fragment.GetChargeNumber() << ", pol = " << fragment.GetPolarization();
out.setf(std::ios::scientific, std::ios::floatfield);
out << std::setprecision(3) << ", U = " << fragment.GetExcitationEnergy() / CLHEP::MeV << " }";
out.setf(oldFlags, std::ios::floatfield);
out.precision(oldUserPrecision);
return out;
}
@@ -31,13 +31,18 @@
#define G4GEMChannelVI_h 1
#include "G4VEvaporationChannel.hh"
#include "G4VSIntegration.hh"
class G4PairingCorrection;
class G4VCoulombBarrier;
class G4LevelManager;
class G4GEMProbabilityVI;
class G4NuclearLevelData;
class G4HadronNucleonXsc;
class G4InterfaceToXS;
class G4ParticleDefinition;
class G4Pow;
class G4GEMChannelVI : public G4VEvaporationChannel
class G4GEMChannelVI : public G4VEvaporationChannel, public G4VSIntegration
{
public:
@@ -47,10 +52,16 @@ public:
void Initialise() override;
G4double ProbabilityDensityFunction(G4double ekin) override;
G4double GetEmissionProbability(G4Fragment* theNucleus) override;
G4Fragment* EmittedFragment(G4Fragment* theNucleus) override;
const G4String& ModelName() const override;
G4double GetCurrentXS() { return recentXS; };
void Dump() const override;
G4GEMChannelVI(const G4GEMChannelVI & right) = delete;
@@ -60,37 +71,56 @@ public:
private:
G4double CrossSection(G4double ekin);
G4double CorrectExcitation(G4double energy, const G4LevelManager*);
G4NuclearLevelData* nData;
const G4VCoulombBarrier* cBarrier;
const G4PairingCorrection* pairingCorrection;
G4GEMProbabilityVI* fProbability;
const G4LevelManager* lManagerEvap{nullptr};
const G4LevelManager* lManagerRes{nullptr};
G4HadronNucleonXsc* fHNXsc{nullptr};
G4InterfaceToXS* fXSection{nullptr};
G4Pow* g4pow;
const G4ParticleDefinition* fProton;
const G4ParticleDefinition* fNeutron;
G4double fEvapMass;
G4double fEvapMass2;
G4double fMass{0.0};
G4double fResMass{0.0};
G4double fExc{0.0};
G4double fEvapMass; // ground state mass of the evaporated fragment
G4double fEvapMass2; // ground state mass of the evaporated fragment square
G4double fMass{0.0}; // mass of the initial fragment
G4double fResMass{0.0}; // ground state mass of the residual fragment
G4double fResA13{0.0}; //
G4double fFragExc{0.0}; // excitation energy of the evaporated fragment
G4double fEvapExc{0.0}; // excitation energy of the evaporated fragment
G4double fResExc{0.0}; // excitation energy of the residual fragment
G4double bCoulomb{0.0};
G4double fLimEXS{0.0};
G4double fDeltaEvap{0.0};
G4double fE0{0.0};
G4double fE1{0.0};
G4double a0{0.0};
G4double a1{0.0};
G4double delta0{0.0};
G4double delta1{0.0};
G4double recentXS{0.0};
G4double fEnergyLimitXS{0.0};
G4double fTolerance;
G4double fCoeff;
G4int A;
G4int Z;
G4int evapA;
G4int evapZ;
G4int resA{0};
G4int resZ{0};
G4int fragA{0};
G4int fragZ{0};
G4int fVerbose{1};
G4int nProb{1};
G4int nProbEvap{1};
G4int nProbRes{1};
G4int indexC{7};
G4int secID;
G4int indexC;
// evaporation fragment data
struct evapData {
G4double exc{0.0}; // excitation
G4double ekin1{0.0}; // min kinetic energy
G4double ekin2{0.0}; // max kinetic energy
G4double prob{0.0}; // probability
};
evapData fEData[10];
G4String fModelName;
};
#endif
@@ -231,7 +231,12 @@ geant4_module_link_libraries(G4hadronic_deex_gem_evaporation
G4hadronic_deex_fission
G4hadronic_deex_management
G4hadronic_deex_util
G4hepnumerics
G4heprandom
G4partman
PRIVATE
G4hadronic_util)
G4baryons
G4ions
G4hadronic_util
G4hadronic_xsect
G4ions)
@@ -39,7 +39,7 @@ std::vector<G4VEvaporationChannel*>* G4EvaporationGEMFactoryVI::GetChannel()
{
std::vector<G4VEvaporationChannel*> * theChannel =
new std::vector<G4VEvaporationChannel*>;
theChannel->reserve(81);
theChannel->reserve(83);
theChannel->push_back( thePhotonEvaporation ); // Photon Channel
theChannel->push_back( new G4CompetitiveFission() ); // Fission Channel
@@ -32,6 +32,7 @@
#include "G4GEMProbabilityVI.hh"
#include "G4VCoulombBarrier.hh"
#include "G4CoulombBarrier.hh"
#include "G4DeexPrecoUtility.hh"
#include "G4PairingCorrection.hh"
#include "G4NuclearLevelData.hh"
#include "G4LevelManager.hh"
@@ -39,165 +40,310 @@
#include "G4RandomDirection.hh"
#include "G4PhysicsModelCatalog.hh"
#include "Randomize.hh"
#include "G4Exp.hh"
#include "G4Log.hh"
#include "G4Pow.hh"
#include "G4Neutron.hh"
#include "G4Proton.hh"
#include "G4Deuteron.hh"
#include "G4Triton.hh"
#include "G4He3.hh"
#include "G4Alpha.hh"
#include "G4InterfaceToXS.hh"
#include "G4IsotopeList.hh"
#include "G4HadronNucleonXsc.hh"
#include "G4NuclearRadii.hh"
namespace
{
const G4double minExc = 1.0*CLHEP::MeV;
const G4int nProbMax = 10;
G4double prob[nProbMax] = {0.0};
}
G4GEMChannelVI::G4GEMChannelVI(G4int theA, G4int theZ)
: A(theA), Z(theZ)
: evapA(theA), evapZ(theZ)
{
G4NuclearLevelData* nData = G4NuclearLevelData::GetInstance();
nData = G4NuclearLevelData::GetInstance();
pairingCorrection = nData->GetPairingCorrection();
const G4LevelManager* lManager = nullptr;
if (A > 4) { lManager = nData->GetLevelManager(Z, A); }
fEvapMass = G4NucleiProperties::GetNuclearMass(A, Z);
if (evapZ > 2) { lManagerEvap = nData->GetLevelManager(evapZ, evapA); }
fEvapMass = G4NucleiProperties::GetNuclearMass(evapA, evapZ);
fEvapMass2 = fEvapMass*fEvapMass;
cBarrier = new G4CoulombBarrier(A, Z);
fProbability = new G4GEMProbabilityVI(A, Z, lManager);
cBarrier = new G4CoulombBarrier(evapA, evapZ);
fCoeff = CLHEP::millibarn/((CLHEP::pi*CLHEP::hbarc)*(CLHEP::pi*CLHEP::hbarc));
fTolerance = 50*CLHEP::keV;
fCoeff = fEvapMass*CLHEP::millibarn
/((CLHEP::pi*CLHEP::hbarc)*(CLHEP::pi*CLHEP::hbarc));
std::ostringstream ss;
ss << "GEMVI_" << "Z" << evapZ << "_A" << evapA;
fModelName = ss.str();
fNeutron = G4Neutron::Neutron();
fProton = G4Proton::Proton();
secID = G4PhysicsModelCatalog::GetModelID("model_G4GEMChannelVI");
if (Z == 0 && A == 1) {
const G4ParticleDefinition* part = nullptr;
if (evapZ == 0 && evapA == 1) {
indexC = 0;
fCoeff *= 2.0;
} else if (Z == 1 && A == 1) {
part = fNeutron;
} else if (evapZ == 1 && evapA == 1) {
indexC = 1;
fCoeff *= 2.0;
} else if (Z == 1 && A == 2) {
part = fProton;
} else if (evapZ == 1 && evapA == 2) {
indexC = 2;
fCoeff *= 3.0;
} else if (Z == 1 && A == 3) {
part = G4Deuteron::Deuteron();
} else if (evapZ == 1 && evapA == 3) {
indexC = 3;
fCoeff *= 2.0;
} else if (Z == 2 && A == 3) {
part = G4Triton::Triton();
} else if (evapZ == 2 && evapA == 3) {
indexC = 4;
fCoeff *= 2.0;
} else if (Z == 2 && A == 4) {
part = G4He3::He3();
} else if (evapZ == 2 && evapA == 4) {
indexC = 5;
} else {
indexC = 6;
part = G4Alpha::Alpha();
}
g4pow = G4Pow::GetInstance();
//G4double de = (0 == indexC) ? 0.15*CLHEP::MeV : 0.25*CLHEP::MeV;
G4double de = 0.125*CLHEP::MeV;
InitialiseIntegrator(0.01, 0.25, 1.1, de, 0.1*CLHEP::MeV, 2*CLHEP::MeV);
if (indexC <= 6) { fXSection = new G4InterfaceToXS(part, indexC); }
else { fHNXsc = new G4HadronNucleonXsc(); }
}
G4GEMChannelVI::~G4GEMChannelVI()
{
delete cBarrier;
delete fProbability;
delete fHNXsc;
delete fXSection;
}
void G4GEMChannelVI::Initialise()
{
fProbability->Initialise();
G4VEvaporationChannel::Initialise();
}
G4double G4GEMChannelVI::GetEmissionProbability(G4Fragment* fragment)
{
fProbability->ResetProbability();
fragZ = fragment->GetZ_asInt();
fragA = fragment->GetA_asInt();
resZ = fragZ - Z;
resA = fragA - A;
if(resA < A || resA < resZ || resZ < 0 || (resA == A && resZ < Z)) {
return 0.0;
}
resZ = fragZ - evapZ;
resA = fragA - evapA;
// to avoid double counting
if (resA < evapA || resA < resZ || resZ < 1 ||
(resA == evapA && resZ < evapZ)) { return 0.0; }
fExc = fragment->GetExcitationEnergy();
fMass = fragment->GetGroundStateMass() + fExc;
fFragExc = fragment->GetExcitationEnergy();
fMass = fragment->GetGroundStateMass() + fFragExc;
fResMass = G4NucleiProperties::GetNuclearMass(resA, resZ);
fResA13 = g4pow->Z13(resA);
// limit for the case when both evaporation and residual
// fragments are in ground states
if (fMass <= fEvapMass + fResMass) { return 0.0; }
if (Z > 0) {
a0 = nData->GetLevelDensity(fragZ, fragA, fFragExc);
delta0 = nData->GetPairingCorrection(fragZ, fragA);
delta1 = nData->GetPairingCorrection(resZ, resA);
fE0 = std::max(fFragExc - delta0, 0.0);
if (indexC > 0) {
bCoulomb = cBarrier->GetCoulombBarrier(resA, resZ, 0.0);
}
G4double de = fMass - fEvapMass - fResMass - bCoulomb;
nProb = (G4int)(de/minExc);
if (nProb <= 1 || indexC < 6 || resA <= 4) {
nProb = 1;
fLimEXS = 2*bCoulomb;
} else {
nProb = std::min(nProb, nProbMax);
fLimEXS = lowEnergyLimitMeV[resZ];
if (0.0 == fLimEXS) { fLimEXS = CLHEP::MeV; }
}
G4double de = fMass - fEvapMass - fResMass - 0.5*bCoulomb;
if (de <= 0.0) { return 0.0; }
nProbEvap = 1;
fDeltaEvap = de;
if (7 == indexC) {
G4int n = (G4int)(de/minExc) + 1;
nProbEvap = std::min(n, nProbMax);
if (nProbEvap > 1) { fDeltaEvap /= (G4double)(nProbEvap - 1); }
}
if (2 < fVerbose) {
G4cout << "## G4GEMChannelVI::GetEmissionProbability fragZ="
<< fragZ << " fragA=" << fragA << " Z=" << Z << " A=" << A
<< " Eex(MeV)=" << fExc << " nProb=" << nProb
<< G4endl;
<< fragZ << " fragA=" << fragA << " Z=" << evapZ << " A=" << evapA
<< " Eex(MeV)=" << fFragExc << " nProbEvap=" << nProbEvap
<< " nProbRes=" << nProbRes << " CB=" << bCoulomb
<< " Elim=" << fEnergyLimitXS << G4endl;
}
fProbability->SetDecayKinematics(resZ, resA, fResMass, fMass);
G4double sump = 0.0;
for (G4int i=0; i<nProb; ++i) {
G4double exc = std::min(minExc*i, de);
G4double m1 = fEvapMass + exc;
G4double e2 = 0.5*((fMass-fResMass)*(fMass+fResMass) + m1*m1)/fMass - m1;
G4double m2 = fMass - m1 - 0.5*bCoulomb;
if (m2 < fResMass) {
nProb = i;
break;
}
G4double e1 = std::max(0.5*((fMass-m2)*(fMass+m2) + m1*m1)/fMass - m1, 0.0);
if (e1 >= e2) {
nProb = i;
break;
}
sump += fProbability->TotalProbability(*fragment, e1, e2, bCoulomb, fExc, exc);
fEData[i].exc = exc;
fEData[i].ekin1 = e1;
fEData[i].ekin2 = e2;
fEData[i].prob = sump;
// m1 is the mass of emitted excited fragment
// e2 - free energy in the 2-body decay
G4double sump = 0.0;
for (G4int i=0; i<nProbEvap; ++i) {
fEvapExc = fDeltaEvap*i;
G4double m1 = fEvapMass + fEvapExc;
G4double e2 = fMass - m1 - fResMass;
e2 = std::max(e2, 0.0);
G4double p = (e2 > 0.5*bCoulomb) ? ComputeIntegral(0.5*bCoulomb, e2) : 0.0;
sump += p;
prob[i] = sump;
}
sump /= (G4double)nProbEvap;
return sump;
}
G4double G4GEMChannelVI::ProbabilityDensityFunction(G4double e)
{
// e is free energy
G4double m1 = fEvapMass + fEvapExc;
fResExc = fMass - m1 - fResMass - e;
if (fResExc <= 0.0 || 0.0 == e) { return 0.0; }
fE1 = std::max(fResExc - delta1, 0.0);
a1 = nData->GetLevelDensity(resZ, resA, fResExc);
G4double m2 = fResMass + fResExc;
G4double elab = 0.5*(fMass + m1 + m2)*(fMass - m1 - m2)/m2;
G4double xs = CrossSection(elab);
G4double res =
fCoeff*G4Exp(2.0*(std::sqrt(a1*fE1) - std::sqrt(a0*fE0)))*elab*xs;
//G4cout << "e=" << e << " elab=" << elab << " xs=" << xs << " sig=" << res << G4endl;
return res;
}
G4double G4GEMChannelVI::CrossSection(G4double e)
{
if (indexC <= 5) {
G4int Z = std::min(resZ, ZMAXNUCLEARDATA);
G4double e1 = std::max(e, fLimEXS);
recentXS = fXSection->GetElementCrossSection(e1, Z)/CLHEP::millibarn;
if (e1 > e) {
recentXS *= (e1/e) *
G4DeexPrecoUtility::CorrectionFactor(indexC, Z, fResA13, bCoulomb, e, e1);
}
} else {
const G4double cInel = 2.4;
const G4double cTotal = 2.0;
if (e <= 0.5*bCoulomb) { return 0.0; }
G4double pTkin = e/(G4double)evapA;
G4int evapN = evapA - evapZ;
G4int resN = resA - resZ;
G4double tR = G4NuclearRadii::Radius(resZ, resA);
G4double pR = G4NuclearRadii::Radius(evapZ, evapA);
fHNXsc->HadronNucleonXscNS(fProton, fProton, pTkin);
G4double xs1 = fHNXsc->GetInelasticHadronNucleonXsc();
fHNXsc->HadronNucleonXscNS(fNeutron, fProton, pTkin);
G4double xs2 = fHNXsc->GetInelasticHadronNucleonXsc();
// nn x-section assumed to be the same as pp
G4double xs = (evapZ*resZ + evapN*resN)*xs1 + (evapZ*resN + evapN*resZ)*xs2;
G4double R2 = cTotal*CLHEP::pi*( pR*pR + tR*tR ); // basically 2piRR
recentXS = R2*G4Log(1.0 + cInel*xs/R2)*(1. - 0.5*bCoulomb/e)/cInel;
}
return recentXS;
}
G4Fragment* G4GEMChannelVI::EmittedFragment(G4Fragment* theNucleus)
{
// assumed, that TotalProbability(...) was already called
// if value iz zero no possiblity to sample final state
G4Fragment* evFragment = nullptr;
G4LorentzVector lv0 = theNucleus->GetMomentum();
G4double ekin;
G4double exc = 0.0;
G4double probMax = std::max(fEData[nProb - 1].prob, 0.0);
if (0.0 >= probMax) {
ekin = std::max(0.5*(fMass*fMass - fResMass*fResMass + fEvapMass2)
/fMass - fEvapMass, 0.0);
} else if (1 == nProb) {
ekin = fProbability->SampleEnergy(fEData[0].ekin1, fEData[0].ekin2,
bCoulomb, fExc, 0.0);
} else {
G4double p = G4UniformRand()*probMax;
G4int i{1};
for (; i<nProb; ++i) {
if (p <= fEData[i].prob) { break; }
lManagerRes = nData->GetLevelManager(resZ, resA);
G4double e2 = fMass - fEvapMass - fResMass;
fEvapExc = 0.0;
// sample excitation of the evaporation fragment
if (nProbEvap > 1) {
G4double q = prob[nProbEvap - 1];
if (q > 0.0) {
q *= G4UniformRand();
for (G4int i=0; i < nProbEvap; ++i) {
if (q <= prob[i]) {
G4double e1 = (0 == i) ? 0.0 :
fDeltaEvap*((i - 1) + (q - prob[i - 1])/(prob[i] - prob[i - 1]));
fEvapExc = CorrectExcitation(e1, lManagerEvap);
e2 -= fEvapExc;
e2 = std::max(e2, 0.0);
}
}
}
G4double e1 = fEData[i - 1].exc;
G4double e2 = fEData[i].exc;
G4double p1 = fEData[i - 1].prob;
G4double p2 = fEData[i].prob;
exc = e1 + (e2 - e1)*(p - p1)/(p2 - p1);
ekin = fProbability->SampleEnergy(fEData[i].ekin1, fEData[i].ekin2,
bCoulomb, fExc, exc);
}
G4double m1 = fEvapMass + exc;
if (ComputeIntegral(bCoulomb, e2) <= 0.0) { return evFragment; }
// sample free energy
G4double e = SampleValue();
// compute excitation of the residual fragment
fResExc = CorrectExcitation(e2 - e, lManagerRes);
// final kinematics
G4double m1 = fEvapMass + fEvapExc;
G4double m2 = fResMass + fResExc;
G4double ekin = 0.5*e*(e + 2*m2)/(e + m1 + m2);
G4LorentzVector lv(std::sqrt(ekin*(ekin + 2.0*m1))
*G4RandomDirection(), ekin + m1);
G4LorentzVector lv0 = theNucleus->GetMomentum();
lv.boost(lv0.boostVector());
evFragment = new G4Fragment(A, Z, lv);
lv0 -= lv;
evFragment = new G4Fragment(evapA, evapZ, lv);
evFragment->SetCreatorModelID(secID);
// residual
lv0 -= lv;
theNucleus->SetZandA_asInt(resZ, resA);
theNucleus->SetMomentum(lv0);
theNucleus->SetCreatorModelID(secID);
return evFragment;
}
}
G4double
G4GEMChannelVI::CorrectExcitation(G4double exc, const G4LevelManager* man)
{
if (exc <= 0.0 || nullptr == man) { return 0.0; }
std::size_t idx = man->NearestLevelIndex(exc);
// choose ground state
if (0 == idx) { return 0.0; }
// possible discrete level
G4double elevel = man->LevelEnergy(idx);
std::size_t ntrans{0};
if (std::abs(elevel - exc) < fTolerance) {
auto level = man->GetLevel(idx);
if (nullptr != level) {
ntrans = level->NumberOfTransitions();
G4int idxfl = man->FloatingLevel(idx);
// for floating level check levels with the same energy
if (idxfl > 0) {
auto newlevel = man->GetLevel(idx - 1);
G4double newenergy = man->LevelEnergy(idx - 1);
if (nullptr != newlevel && std::abs(elevel - newenergy) < fTolerance) {
std::size_t newntrans = newlevel->NumberOfTransitions();
if (newntrans > 0) {
elevel = newenergy;
ntrans = newntrans;
}
}
}
if (0 < ntrans) { return elevel; }
}
}
return exc;
}
const G4String& G4GEMChannelVI::ModelName() const
{
return fModelName;
}
void G4GEMChannelVI::Dump() const
{}
@@ -54,9 +54,9 @@ G4GEMProbabilityVI::G4GEMProbabilityVI(G4int anA, G4int aZ, const G4LevelManager
A13 = pG4pow->Z13(theA);
if(0 == aZ) {
ResetIntegrator(30, 0.25*CLHEP::MeV, 0.02);
ResetIntegrator(0.25*CLHEP::MeV, 0.005);
} else {
ResetIntegrator(30, 0.5*CLHEP::MeV, 0.03);
ResetIntegrator(0.5*CLHEP::MeV, 0.005);
}
}
@@ -80,6 +80,7 @@
#include "G4Evaporation.hh"
#include "G4PhotonEvaporation.hh"
#include "G4StatMF.hh"
#include "G4FermiBreakUpAN.hh"
#include "G4FermiBreakUpVI.hh"
#include "G4NuclearLevelData.hh"
#include "G4PhysicsModelCatalog.hh"
@@ -93,7 +94,7 @@ G4ExcitationHandler::G4ExcitationHandler()
nist = G4NistManager::Instance();
theMultiFragmentation = new G4StatMF();
theFermiModel = new G4FermiBreakUpVI();
theFermiModel = nullptr;
thePhotonEvaporation = new G4PhotonEvaporation();
SetEvaporation(new G4Evaporation(thePhotonEvaporation), true);
theResults.reserve(60);
@@ -123,6 +124,9 @@ G4ExcitationHandler::~G4ExcitationHandler()
void G4ExcitationHandler::SetParameters()
{
// initialisation only once
if (isInitialised) { return; }
G4NuclearLevelData* ndata = G4NuclearLevelData::GetInstance();
auto param = ndata->GetParameters();
isActive = true;
@@ -143,52 +147,70 @@ void G4ExcitationHandler::SetParameters()
// allowing local debug printout
fVerbose = std::max(fVerbose, param->GetVerbose());
if (isActive) {
// photon evaporation initialisation
if (nullptr == thePhotonEvaporation) {
SetPhotonEvaporation(new G4PhotonEvaporation());
}
thePhotonEvaporation->Initialise();
// FermiBreakUp initialisation
if (nullptr == theFermiModel) {
SetFermiModel(new G4FermiBreakUpVI());
auto type = param->GetFermiBreakUpType();
if (type == bModelVI) {
theFermiModel = new G4FermiBreakUpVI();
} else if (type == bModelAN) {
theFermiModel = new G4FermiBreakUpAN(fVerbose);
} else {
theFermiModel = new G4VFermiBreakUp();
}
SetFermiModel(theFermiModel);
}
theFermiModel->Initialise();
// multi-fragmentation initialisation
if (nullptr == theMultiFragmentation) {
SetMultiFragmentation(new G4StatMF());
}
// evaporation initialisation
if (nullptr == theEvaporation) {
SetEvaporation(new G4Evaporation(thePhotonEvaporation), true);
}
theEvaporation->SetPhotonEvaporation(thePhotonEvaporation);
theEvaporation->SetFermiBreakUp(theFermiModel);
SetDeexChannelsType(param->GetDeexChannelsType());
theEvaporation->InitialiseChannels();
}
theFermiModel->SetVerbose(fVerbose);
if(fVerbose > 1) {
if (fVerbose > 1) {
G4cout << "G4ExcitationHandler::SetParameters() done " << this << G4endl;
}
}
void G4ExcitationHandler::Initialise()
{
if(isInitialised) { return; }
if(fVerbose > 1) {
// initialisation only once
if (isInitialised) { return; }
if (fVerbose > 1) {
G4cout << "G4ExcitationHandler::Initialise() started " << this << G4endl;
}
G4DeexPrecoParameters* param =
G4NuclearLevelData::GetInstance()->GetParameters();
isInitialised = true;
SetParameters();
if(isActive) {
theFermiModel->Initialise();
theEvaporation->InitialiseChannels();
}
// dump level is controlled by parameter class
param->Dump();
isInitialised = true;
}
void G4ExcitationHandler::SetEvaporation(G4VEvaporation* ptr, G4bool flag)
{
if(nullptr != ptr && ptr != theEvaporation) {
if (!isInitialised && nullptr != ptr && ptr != theEvaporation) {
delete theEvaporation;
theEvaporation = ptr;
theEvaporation->SetPhotonEvaporation(thePhotonEvaporation);
theEvaporation->SetFermiBreakUp(theFermiModel);
isEvapLocal = flag;
if(fVerbose > 1) {
G4cout << "G4ExcitationHandler::SetEvaporation() " << ptr << " done for " << this << G4endl;
G4cout << "G4ExcitationHandler::SetEvaporation() " << ptr
<< " done for " << this << G4endl;
}
}
}
@@ -196,7 +218,7 @@ void G4ExcitationHandler::SetEvaporation(G4VEvaporation* ptr, G4bool flag)
void
G4ExcitationHandler::SetMultiFragmentation(G4VMultiFragmentation* ptr)
{
if(nullptr != ptr && ptr != theMultiFragmentation) {
if (!isInitialised && nullptr != ptr && ptr != theMultiFragmentation) {
delete theMultiFragmentation;
theMultiFragmentation = ptr;
}
@@ -204,25 +226,19 @@ G4ExcitationHandler::SetMultiFragmentation(G4VMultiFragmentation* ptr)
void G4ExcitationHandler::SetFermiModel(G4VFermiBreakUp* ptr)
{
if(nullptr != ptr && ptr != theFermiModel) {
if (!isInitialised && nullptr != ptr && ptr != theFermiModel) {
delete theFermiModel;
theFermiModel = ptr;
if(nullptr != theEvaporation) {
theEvaporation->SetFermiBreakUp(theFermiModel);
}
}
}
void
G4ExcitationHandler::SetPhotonEvaporation(G4VEvaporationChannel* ptr)
{
if(nullptr != ptr && ptr != thePhotonEvaporation) {
if (!isInitialised && nullptr != ptr && ptr != thePhotonEvaporation) {
delete thePhotonEvaporation;
thePhotonEvaporation = ptr;
if(nullptr != theEvaporation) {
theEvaporation->SetPhotonEvaporation(ptr);
}
if(fVerbose > 1) {
if (fVerbose > 1) {
G4cout << "G4ExcitationHandler::SetPhotonEvaporation() " << ptr
<< " for handler " << this << G4endl;
}
@@ -232,7 +248,7 @@ G4ExcitationHandler::SetPhotonEvaporation(G4VEvaporationChannel* ptr)
void G4ExcitationHandler::SetDeexChannelsType(G4DeexChannelType val)
{
G4Evaporation* evap = static_cast<G4Evaporation*>(theEvaporation);
if(fVerbose > 1) {
if (fVerbose > 1) {
G4cout << "G4ExcitationHandler::SetDeexChannelsType " << val
<< " for " << this << G4endl;
}
@@ -55,6 +55,20 @@ enum G4DeexChannelType
fDummy
};
enum G4PreCompoundType
{
eDefault = 0,
eDeexcitation,
ePrecoInterface
};
enum G4FermiBreakUpType
{
bModelVI = 0,
bModelAN,
bDummy
};
class G4StateManager;
class G4DeexParametersMessenger;
@@ -105,8 +119,10 @@ public:
inline G4int GetMinAForPreco() const;
// should be renamed
inline G4int GetPrecoModelType() const;
// should be renamed
inline G4int GetDeexModelType() const;
inline G4int GetTwoJMAX() const;
@@ -141,8 +157,11 @@ public:
inline G4DeexChannelType GetDeexChannelsType() const;
// Set methods
inline G4PreCompoundType GetPreCompoundType() const;
inline G4FermiBreakUpType GetFermiBreakUpType() const;
// Set methods
void SetLevelDensity(G4double);
void SetR0(G4double);
@@ -173,8 +192,10 @@ public:
void SetMinAForPreco(G4int);
// should be renamed
void SetPrecoModelType(G4int);
// should be renamed
void SetDeexModelType(G4int);
void SetTwoJMAX(G4int);
@@ -199,7 +220,7 @@ public:
void SetStoreICLevelData(G4bool);
// obsolete method (use previous)
// obsolete method (use SetStoreICLevelData)
void SetStoreAllLevels(G4bool);
void SetInternalConversionFlag(G4bool);
@@ -212,6 +233,10 @@ public:
void SetDeexChannelsType(G4DeexChannelType);
void SetPreCompoundType(G4PreCompoundType);
void SetFermiBreakUpType(G4FermiBreakUpType);
G4DeexPrecoParameters(const G4DeexPrecoParameters & right) = delete;
const G4DeexPrecoParameters& operator=
(const G4DeexPrecoParameters &right) = delete;
@@ -289,6 +314,8 @@ private:
// type of a set of de-exitation channels
G4DeexChannelType fDeexChannelType;
G4PreCompoundType fPreCompoundType;
G4FermiBreakUpType fFermiBreakUpType;
};
inline G4double G4DeexPrecoParameters::GetLevelDensity() const
@@ -446,4 +473,14 @@ inline G4DeexChannelType G4DeexPrecoParameters::GetDeexChannelsType() const
return fDeexChannelType;
}
inline G4PreCompoundType G4DeexPrecoParameters::GetPreCompoundType() const
{
return fPreCompoundType;
}
inline G4FermiBreakUpType G4DeexPrecoParameters::GetFermiBreakUpType() const
{
return fFermiBreakUpType;
}
#endif
@@ -64,23 +64,23 @@ public:
inline std::size_t NumberOfTransitions() const;
inline std::size_t FinalExcitationIndex(std::size_t idx) const;
inline std::size_t FinalExcitationIndex(const std::size_t idx) const;
inline G4int TransitionType(std::size_t idx) const;
inline G4int TransitionType(const std::size_t idx) const;
inline G4double GetTimeGamma() const;
inline G4float GammaProbability(std::size_t idx) const;
inline G4float GammaCumProbability(std::size_t idx) const;
inline G4float GammaCumProbability(const std::size_t idx) const;
inline G4float MultipolarityRatio(std::size_t idx) const;
inline G4float MultipolarityRatio(const std::size_t idx) const;
inline std::size_t SampleGammaTransition(G4double rndm) const;
inline std::size_t SampleGammaTransition(const G4double rndm) const;
inline G4int SampleShell(std::size_t idx, G4double rndm) const;
inline G4int SampleShell(const std::size_t idx, const G4double rndm) const;
inline const std::vector<G4float>* ShellProbabilty(std::size_t idx) const;
inline const std::vector<G4float>* ShellProbabilty(const std::size_t idx) const;
void StreamInfo(std::ostream& os) const;
@@ -139,7 +139,8 @@ inline G4float G4NucLevel::MultipolarityRatio(const std::size_t idx) const
inline std::size_t G4NucLevel::SampleGammaTransition(const G4double rndm) const
{
G4float x = rndm;
// this method called if length > 1
const G4float x = (G4float)rndm;
std::size_t idx = 0;
for(; idx<length; ++idx) {
if(x <= fGammaCumProbability[idx]) { break; }
@@ -153,15 +154,15 @@ G4NucLevel::SampleShell(const std::size_t idx, const G4double rndm) const
const std::vector<G4float>* prob = fShellProbability[idx];
G4int i(-1);
if(nullptr != prob) {
G4int nn = (G4int)prob->size();
G4float x = rndm;
const G4int nn = (G4int)prob->size();
const G4float x = (G4float)rndm;
for(i=0; i<nn; ++i) { if(x <= (*prob)[i]) { break; } }
}
return i;
}
inline const std::vector<G4float>*
G4NucLevel::ShellProbabilty(std::size_t idx) const
G4NucLevel::ShellProbabilty(const std::size_t idx) const
{
return fShellProbability[idx];
}
@@ -39,17 +39,20 @@
#include "globals.hh"
#include "G4Fragment.hh"
#include "G4VSIntegration.hh"
class G4NuclearLevelData;
class G4Pow;
class G4VEmissionProbability
class G4VEmissionProbability : G4VSIntegration
{
public:
explicit G4VEmissionProbability(G4int Z, G4int A);
virtual ~G4VEmissionProbability() = default;
~G4VEmissionProbability() override = default;
G4double ProbabilityDensityFunction(G4double energy) override;
virtual void Initialise();
@@ -93,7 +96,7 @@ public:
protected:
void ResetIntegrator(size_t nbin, G4double de, G4double eps);
void ResetIntegrator(G4double de, G4double eps);
G4double IntegrateProbability(G4double elow, G4double ehigh, G4double CB);
@@ -120,18 +123,8 @@ private:
G4double fExc = 0.0;
G4double fExcRes = 0.0;
G4double fE1 = 0.0;
G4double fE2 = 0.0;
G4double fP2 = 0.0;
G4double emin = 0.0;
G4double emax = 0.0;
G4double eCoulomb = 0.0;
G4double accuracy = 0.005;
G4double probmax = 0.0;
G4double elimit;
G4double fMaxLifeTime = 1.0;
G4bool fFD = false;
};
@@ -26,6 +26,7 @@ geant4_module_link_libraries(G4hadronic_deex_management
PUBLIC
G4globman
G4hadronic_util
G4hepnumerics
G4intercoms
PRIVATE
G4hadronic_deex_util
@@ -90,6 +90,8 @@ void G4DeexPrecoParameters::Initialise()
fMinExPerNucleounForMF = 200*CLHEP::GeV;
fDeexChannelType = fCombined;
fPreCompoundType = eDefault;
fFermiBreakUpType = bModelVI;
fDeexType = 3;
fTwoJMAX = 10;
@@ -299,16 +301,31 @@ void G4DeexPrecoParameters::SetDeexChannelsType(G4DeexChannelType val)
fDeexChannelType = val;
}
void G4DeexPrecoParameters::SetPreCompoundType(G4PreCompoundType val)
{
if(IsLocked()) { return; }
fPreCompoundType = val;
}
void G4DeexPrecoParameters::SetFermiBreakUpType(G4FermiBreakUpType val)
{
if(IsLocked()) { return; }
fFermiBreakUpType = val;
}
std::ostream& G4DeexPrecoParameters::StreamInfo(std::ostream& os) const
{
static const G4String namm[5] = {"Evaporation","GEM","Evaporation+GEM","GEMVI","Dummy"};
static const G4int nmm[5] = {8, 68, 68, 31, 0};
static const G4int nmm[5] = {8, 68, 68, 83, 0};
static const G4String nfbu[3] = {"ModelVI", "ModelAN", "Dummy"};
G4int idx = fDeexChannelType;
G4int jdx = fFermiBreakUpType;
G4long prec = os.precision(5);
os << "=======================================================================" << "\n";
os << "====== Geant4 Native Pre-compound Model Parameters ========" << "\n";
os << "=======================================================================" << "\n";
os << "Type of pre-compound model " << fPreCompoundType << "\n";
os << "Type of pre-compound inverse x-section " << fPrecoType << "\n";
os << "Pre-compound model active " << (!fPrecoDummy) << "\n";
os << "Pre-compound excitation low energy "
@@ -327,6 +344,7 @@ std::ostream& G4DeexPrecoParameters::StreamInfo(std::ostream& os) const
os << "Type of de-excitation inverse x-section " << fDeexType << "\n";
os << "Type of de-excitation factory " << namm[idx] << "\n";
os << "Number of de-excitation channels " << nmm[idx] << "\n";
os << "Type of Fermi BreakUp model " << nfbu[jdx] << "\n";
os << "Min excitation energy "
<< G4BestUnit(fMinExcitation, "Energy") << "\n";
os << "Min energy per nucleon for multifragmentation "
@@ -394,7 +394,7 @@ G4LevelReader::LevelManager(G4int Z, G4int A, std::ifstream& infile)
<< " isOK=" << isTransOK
<< G4endl;
}
if (0.0f < fNorm1) { fNorm1 = 1.0f/fNorm1; }
fNorm1 = (FLT_MIN < fNorm1) ? 1.0f/fNorm1 : 0.0f;
for (k=0; k<nt; ++k) {
vGammaCumProbability[k] *= fNorm1;
#ifdef G4VERBOSE
@@ -39,7 +39,7 @@
#include "G4Exp.hh"
G4VEmissionProbability::G4VEmissionProbability(G4int Z, G4int A)
: pVerbose(1), theZ(Z), theA(A), elimit(CLHEP::MeV)
: pVerbose(1), theZ(Z), theA(A)
{
pNuclearLevelData = G4NuclearLevelData::GetInstance();
pG4pow = G4Pow::GetInstance();
@@ -53,14 +53,14 @@ void G4VEmissionProbability::Initialise()
G4DeexPrecoParameters* param = pNuclearLevelData->GetParameters();
pVerbose = param->GetVerbose();
fFD = param->GetDiscreteExcitationFlag();
fMaxLifeTime = param->GetMaxLifeTime();
pTolerance = param->GetMinExcitation();
pWidth = param->GetNuclearLevelWidth();
}
void G4VEmissionProbability::ResetIntegrator(size_t, G4double de, G4double eps)
void G4VEmissionProbability::ResetIntegrator(G4double de, G4double eps)
{
if(de > 0.0) { elimit = de; }
if(eps > 0.0) { accuracy = eps; }
InitialiseIntegrator(eps, 0.25, 1.10, de, 0.1*CLHEP::MeV, 2*CLHEP::MeV);
}
G4double G4VEmissionProbability::EmissionProbability(const G4Fragment&, G4double)
@@ -78,158 +78,34 @@ G4double G4VEmissionProbability::IntegrateProbability(G4double elow,
G4double cb)
{
pProbability = 0.0;
if(elow >= ehigh) { return pProbability; }
if (elow >= ehigh) { return pProbability; }
emin = elow;
emax = ehigh;
eCoulomb = cb;
pProbability = ComputeIntegral(elow, ehigh);
const G4double edeltamin = 0.1*CLHEP::MeV;
const G4double edeltamax = 2*CLHEP::MeV;
G4double edelta = std::min(std::min(elimit, edeltamax), edeltamin);
G4double xbin = (emax - emin)/edelta + 1.0;
G4int ibin = std::max((G4int)xbin, 4);
// providing smart binning
G4int nbin = ibin*5;
edelta = (emax - emin)/ibin;
G4double x(emin), y(0.0);
G4double edelmicro = edelta*0.02;
probmax = ComputeProbability(x + edelmicro, eCoulomb);
G4double problast = probmax;
if(pVerbose > 1) {
G4cout << "### G4VEmissionProbability::IntegrateProbability: "
<< "probmax=" << probmax << " Emin=" << emin
<< " Emax=" << emax << " QB=" << cb << " nbin=" << nbin
<< G4endl;
}
fE1 = fE2 = fP2 = 0.0;
G4double emax0 = emax - edelmicro;
G4bool endpoint = false;
for(G4int i=0; i<nbin; ++i) {
x += edelta;
if(x >= emax0) {
x = emax0;
endpoint = true;
}
y = ComputeProbability(x, eCoulomb);
if(pVerbose > 2) {
G4cout << " " << i << ". E= " << x << " prob= " << y
<< " Edel= " << edelta << G4endl;
}
if(y >= probmax) {
probmax = y;
} else if(0.0 == fE1 && 2*y < probmax) {
fE1 = x;
}
G4double del = (y + problast)*edelta*0.5;
pProbability += del;
// end of the loop
if(del < accuracy*pProbability || endpoint) { break; }
problast = y;
// smart step definition
if(del != pProbability && del > 0.8*pProbability &&
0.7*edelta > edeltamin) {
edelta *= 0.7;
} else if(del < 0.1*pProbability && 1.5*edelta < edeltamax) {
edelta *= 1.5;
}
}
if(fE1 > emin && fE1 < emax) {
fE2 = std::max(0.5*(fE1 + emax), emax - edelta);
fP2 = 2*ComputeProbability(fE2, eCoulomb);
}
if(pVerbose > 1) {
G4cout << " Probability= " << pProbability << " probmax= "
<< probmax << " emin=" << emin << " emax=" << emax
<< " E1=" << fE1 << " E2=" << fE2 << G4endl;
if (pVerbose > 1) {
G4cout << "G4VEmissionProbability::IntegrateProbability Probability="
<< pProbability << " Z=" << theZ << " A=" << theA << G4endl;
}
return pProbability;
}
G4double G4VEmissionProbability::SampleEnergy()
{
static const G4double fact = 1.05;
static const G4double alim = 0.05;
static const G4double blim = 20.;
probmax *= fact;
// two regions with flat and exponential majorant
G4double del = emax - emin;
G4double p1 = 1.0;
G4double p2 = 0.0;
G4double a0 = 0.0;
G4double a1 = 1.0;
G4double x;
if(fE1 > 0.0 && fP2 > 0.0 && fP2 < 0.5*probmax) {
a0 = G4Log(probmax/fP2)/(fE2 - fE1);
del= fE1 - emin;
p1 = del;
x = a0*(emax - fE1);
if(x < blim) {
a1 = (x > alim) ? 1.0 - G4Exp(-x) : x*(1.0 - 0.5*x);
}
p2 = a1/a0;
p1 /= (p1 + p2);
p2 = 1.0 - p1;
}
if(pVerbose > 1) {
G4cout << "### G4VEmissionProbability::SampleEnergy: "
<< " Emin= " << emin << " Emax= " << emax
<< "/n E1=" << fE1 << " p1=" << p1
<< " probmax=" << probmax << " P2=" << fP2 << G4endl;
}
CLHEP::HepRandomEngine* rndm = G4Random::getTheEngine();
const G4int nmax = 1000;
G4double ekin, gg, gmax;
G4int n = 0;
do {
++n;
G4double q = rndm->flat();
if (p2 == 0.0) {
gmax = probmax;
ekin = del*q + emin;
} else if (q <= p1) {
gmax = probmax;
ekin = del*q/p1 + emin;
} else {
ekin = fE1 - G4Log(1.0 - (q - p1)*a1/p2)/a0;
x = a0*(ekin - fE1);
gmax = fP2;
if(x < blim) {
gmax = probmax*((x > alim) ? G4Exp(-x) : 1.0 - x*(1.0 - 0.5*x));
}
}
gg = ComputeProbability(ekin, eCoulomb);
if(pVerbose > 2) {
G4cout << " " << n
<< ". prob= " << gg << " probmax= " << probmax
<< " Ekin= " << ekin << G4endl;
}
if((gg > gmax || n > nmax) && pVerbose > 1) {
G4cout << "### G4VEmissionProbability::SampleEnergy for Z= " << theZ
<< " A= " << theA << " Eex(MeV)=" << fExc << " p1=" << p1
<< "\n Warning n= " << n
<< " prob/gmax=" << gg/gmax
<< " prob=" << gg << " gmax=" << gmax << " probmax=" << probmax
<< "\n Ekin= " << ekin << " Emin= " << emin
<< " Emax= " << emax << G4endl;
}
} while(gmax*rndm->flat() > gg && n < nmax);
G4double ekin = SampleValue();
G4double enew = FindRecoilExcitation(ekin);
if(pVerbose > 1) {
G4cout << "### SampleEnergy: Efinal= "
if (pVerbose > 1) {
G4cout << "### G4VEmissionProbability::SampleEnergy: Efin(MeV)= "
<< enew << " E=" << ekin << " Eexc=" << fExcRes << G4endl;
}
return enew;
}
G4double G4VEmissionProbability::ProbabilityDensityFunction(G4double e)
{
return ComputeProbability(e, eCoulomb);
}
G4double G4VEmissionProbability::FindRecoilExcitation(const G4double e)
{
G4double mass = pEvapMass + fExc;
@@ -241,7 +117,7 @@ G4double G4VEmissionProbability::FindRecoilExcitation(const G4double e)
fExcRes = mres - pResMass;
if(pVerbose > 1) {
if (pVerbose > 1) {
G4cout << "### FindRecoilExcitation for resZ= "
<< resZ << " resA= " << resA
<< " evaporated Z= " << theZ << " A= " << theA
@@ -253,7 +129,7 @@ G4double G4VEmissionProbability::FindRecoilExcitation(const G4double e)
fExcRes = 0.0;
return std::max(0.5*(m02 + m12 - m22)/pMass - mass, 0.0);
}
if(!fFD) { return e; }
if (!fFD) { return e; }
// select final state excitation
auto lManager = pNuclearLevelData->GetLevelManager(resZ, resA);
@@ -264,20 +140,19 @@ G4double G4VEmissionProbability::FindRecoilExcitation(const G4double e)
// find level
std::size_t idx = lManager->NearestLevelIndex(fExcRes);
auto level = lManager->GetLevel(idx);
auto level = lManager->GetLevel(idx);
G4double ltime = level->GetTimeGamma();
G4double elevel = lManager->LevelEnergy(idx);
// unstable level
if (level->GetTimeGamma() == 0.0) { return e; }
G4double efinal = e;
// is possible to use level energy?
G4double elevel = lManager->LevelEnergy(idx);
if (std::abs(elevel - fExcRes) > pWidth || pMass < mass + pResMass + elevel) {
return e;
if ((idx <= 1 || std::abs(elevel - fExcRes) <= pWidth || ltime >= fMaxLifeTime) &&
(pMass >= mass + pResMass + elevel)) {
G4double massR = pResMass + elevel;
G4double mr2 = massR*massR;
fExcRes = elevel;
efinal = std::max(0.5*(m02 + m12 - mr2)/pMass - mass, 0.0);
}
// long-lived level
G4double massR = pResMass + elevel;
G4double mr2 = massR*massR;
fExcRes = elevel;
return std::max(0.5*(m02 + m12 - mr2)/pMass - mass, 0.0);
return efinal;
}
@@ -177,7 +177,9 @@ G4double G4StatMFMicroPartition::CalcPartitionTemperature(G4double U,
// If this happens, T = 0 MeV, which means that probability for this
// partition will be 0
if (std::fabs(U + FreeInternalE0 - PartitionEnergy) < 0.003) return -1.0;
if (std::abs(U + FreeInternalE0 - PartitionEnergy) < 0.003) {
return -1.0;
}
// Calculate temperature by midpoint method
@@ -189,23 +191,26 @@ G4double G4StatMFMicroPartition::CalcPartitionTemperature(G4double U,
G4double Da = (U + FreeInternalE0 - GetPartitionEnergy(Ta))/U;
G4double Db = (U + FreeInternalE0 - GetPartitionEnergy(Tb))/U;
G4int maxit = 0;
// Loop checking, 05-Aug-2015, Vladimir Ivanchenko
while (Da*Db > 0.0 && maxit < 1000)
{
++maxit;
if (Da*Db < 0.0) {
G4bool yes = false;
for (G4int i = 0; i < 1000; ++i) {
Tb += 0.5*Tb;
Db = (U + FreeInternalE0 - GetPartitionEnergy(Tb))/U;
if (Da*Db >= 0.0) {
yes = true;
break;
}
}
if (!yes) { return -1.0; }
}
G4double eps = 1.0e-10*std::abs(Ta-Tb);
G4double eps = 1.0e-14*std::abs(Ta-Tb);
for (G4int i = 0; i < 1000; i++)
for (G4int i = 0; i < 1000; ++i)
{
Tmid = (Ta+Tb)/2.0;
if (std::fabs(Ta-Tb) <= eps) return Tmid;
if (std::abs(Ta-Tb) <= eps) { return Tmid; }
G4double Dmid = (U + FreeInternalE0 - GetPartitionEnergy(Tmid))/U;
if (std::fabs(Dmid) < 0.003) return Tmid;
if (std::abs(Dmid) < 0.003) { return Tmid; }
if (Da*Dmid < 0.0)
{
Tb = Tmid;
@@ -217,12 +222,7 @@ G4double G4StatMFMicroPartition::CalcPartitionTemperature(G4double U,
Da = Dmid;
}
}
// if we arrive here the temperature could not be calculated
G4cout << "G4StatMFMicroPartition::CalcPartitionTemperature: I can't calculate the temperature"
<< G4endl;
// and set probability to 0 returning T < 0
return -1.0;
return -1.0;
}
G4double G4StatMFMicroPartition::CalcPartitionProbability(G4double U,
@@ -234,70 +234,50 @@ G4double G4StatMFMicroPartition::CalcPartitionProbability(G4double U,
_Temperature = T;
G4Pow* g4calc = G4Pow::GetInstance();
G4int n = (G4int)_thePartition.size();
// Factorial of fragment multiplicity
G4double Fact = 1.0;
unsigned int i;
for (i = 0; i < _thePartition.size() - 1; i++)
{
G4double f = 1.0;
for (unsigned int ii = i+1; i< _thePartition.size(); i++)
{
if (_thePartition[i] == _thePartition[ii]) f++;
}
Fact *= f;
}
G4double Fact = g4calc->factorial(n);
G4double ProbDegeneracy = 1.0;
G4double ProbA32 = 1.0;
for (i = 0; i < _thePartition.size(); i++)
{
ProbDegeneracy *= GetDegeneracyFactor(_thePartition[i]);
ProbA32 *= _thePartition[i]*std::sqrt((G4double)_thePartition[i]);
}
// Compute entropy
G4double PartitionEntropy = 0.0;
for (i = 0; i < _thePartition.size(); i++)
{
// interaction entropy for alpha
if (_thePartition[i] == 4)
{
PartitionEntropy +=
2.0*T*_thePartition[i]/InvLevelDensity(_thePartition[i]);
}
// interaction entropy for Af > 4
else if (_thePartition[i] > 4)
{
PartitionEntropy +=
2.0*T*_thePartition[i]/InvLevelDensity(_thePartition[i])
- G4StatMFParameters::DBetaDT(T) * g4calc->Z23(_thePartition[i]);
}
G4double db = G4StatMFParameters::DBetaDT(T);
for (G4int i = 0; i < n; ++i) {
G4int par = _thePartition[i];
ProbDegeneracy *= GetDegeneracyFactor(par);
ProbA32 *= _thePartition[i]*std::sqrt((G4double)par);
// interaction entropy for alpha
if (par == 4) {
PartitionEntropy += 2.0 * T * par/InvLevelDensity(par);
}
// interaction entropy for Af > 4
else if (par > 4) {
PartitionEntropy += 2.0 * T * par/InvLevelDensity(par) - db * g4calc->Z23(par);
}
}
// Thermal Wave Lenght = std::sqrt(2 pi hbar^2 / nucleon_mass T)
G4double ThermalWaveLenght3 = 16.15*fermi/std::sqrt(T);
ThermalWaveLenght3 = ThermalWaveLenght3*ThermalWaveLenght3*ThermalWaveLenght3;
// Translational Entropy
G4double kappa = 1. + elm_coupling*(g4calc->Z13((G4int)_thePartition.size())-1.0)
/(G4StatMFParameters::Getr0()*g4calc->Z13(theA));
kappa = kappa*kappa*kappa;
kappa -= 1.;
G4double V0 = (4./3.)*pi*theA*G4StatMFParameters::Getr0()*G4StatMFParameters::Getr0()*
G4StatMFParameters::Getr0();
G4double FreeVolume = kappa*V0;
G4double TranslationalS = std::max(0.0, G4Log(ProbA32/Fact) +
(_thePartition.size()-1.0)*G4Log(FreeVolume/ThermalWaveLenght3) +
1.5*(_thePartition.size()-1.0) - 1.5*g4calc->logZ(theA));
G4double r0 = G4StatMFParameters::Getr0();
G4double kappa = 1. + elm_coupling*(g4calc->Z13(n) - 1.0)/(r0*g4calc->Z13(theA));
G4double V0 = (4./3.)*pi*theA*r0*r0*r0;
G4double FreeVolume = (kappa*kappa*kappa - 1.0)*V0;
G4double TranslationalS = G4Log(ProbA32/Fact)
+ (n - 1)*G4Log(FreeVolume/ThermalWaveLenght3)
+ 1.5*(n - 1) - 1.5*g4calc->logZ(theA);
TranslationalS = std::max(TranslationalS, 0.0);
PartitionEntropy += G4Log(ProbDegeneracy) + TranslationalS;
_Entropy = PartitionEntropy;
// And finally compute probability of fragment configuration
G4double exponent = PartitionEntropy-SCompound;
if (exponent > 300.0) exponent = 300.0;
G4double exponent = std::min(PartitionEntropy - SCompound, 200.);
return _Probability = G4Exp(exponent);
}
@@ -318,40 +298,37 @@ G4StatMFChannel * G4StatMFMicroPartition::ChooseZ(G4int A0, G4int Z0, G4double M
// Gives fragments charges
{
std::vector<G4int> FragmentsZ;
G4int n = (G4int)_thePartition.size();
G4int ZBalance = 0;
do
{
G4double CC = G4StatMFParameters::GetGamma0()*8.0;
G4int SumZ = 0;
for (unsigned int i = 0; i < _thePartition.size(); i++)
{
G4double ZMean;
G4double Af = _thePartition[i];
if (Af > 1.5 && Af < 4.5) ZMean = 0.5*Af;
else ZMean = Af*Z0/A0;
G4double ZDispersion = std::sqrt(Af * MeanT/CC);
G4int Zf;
do
{
Zf = static_cast<G4int>(G4RandGauss::shoot(ZMean,ZDispersion));
}
// Loop checking, 05-Aug-2015, Vladimir Ivanchenko
while (Zf < 0 || Zf > Af);
FragmentsZ.push_back(Zf);
SumZ += Zf;
}
ZBalance = Z0 - SumZ;
}
do {
G4double CC = G4StatMFParameters::GetGamma0()*8.0;
G4int SumZ = 0;
for (G4int i = 0; i < n; ++i) {
G4double ZMean;
G4double Af = _thePartition[i];
if (Af > 1.5 && Af < 4.5) { ZMean = 0.5*Af; }
else ZMean = Af*Z0/A0;
G4double ZDispersion = std::sqrt(Af * MeanT/CC);
G4int Zf;
do {
Zf = static_cast<G4int>(G4RandGauss::shoot(ZMean, ZDispersion));
}
// Loop checking, 05-Aug-2015, Vladimir Ivanchenko
while (Zf < 0 || Zf > Af);
FragmentsZ.push_back(Zf);
SumZ += Zf;
}
ZBalance = Z0 - SumZ;
}
// Loop checking, 05-Aug-2015, Vladimir Ivanchenko
while (std::abs(ZBalance) > 1);
FragmentsZ[0] += ZBalance;
G4StatMFChannel * theChannel = new G4StatMFChannel;
for (unsigned int i = 0; i < _thePartition.size(); i++)
{
theChannel->CreateFragment(_thePartition[i],FragmentsZ[i]);
}
for (G4int i = 0; i < n; ++i) {
theChannel->CreateFragment(_thePartition[i], FragmentsZ[i]);
}
return theChannel;
}
@@ -244,8 +244,8 @@ G4PhotonEvaporation::GetEmissionProbability(G4Fragment* nucleus)
// ignore gamma de-excitation for highly excited levels
if(A >= MAXGRDATA) { A = MAXGRDATA-1; }
static const G4float GREfactor = 5.0f;
G4double edelta = (G4double)(GREfactor*GRWidth[A] + GREnergy[A]);
static const G4double GREfactor = 5.0;
G4double edelta = GREfactor*(G4double)GRWidth[A] + (G4double)GREnergy[A];
if (fVerbose > 2)
G4cout << " GREnergy=" << GREnergy[A] << " GRWidth="<<GRWidth[A]
<< " Edelta=" << edelta <<G4endl;
@@ -481,7 +481,8 @@ G4PhotonEvaporation::GenerateGamma(G4Fragment* nucleus)
el = fLevelManager->LevelEnergy(fIndex);
}
// further decays will be discrete
if (std::abs(efinal - el) <= eLimit) {
ltime = fLevelManager->LifeTime(fIndex);
if (fIndex <= 1 || std::abs(efinal - el) <= eLimit || ltime >= fLocalTimeLimit) {
efinal = el;
finalDiscrete = true;
} else {
@@ -0,0 +1,63 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// Geant4 header G4DeexPrecoUtility
//
// Author V.Ivanchenko 19.05.2025
//
// Utilities used at initialisation of the de-excitation module
//
#ifndef G4DeexPrecoUtility_h
#define G4DeexPrecoUtility_h 1
#include "globals.hh"
class G4DeexPrecoUtility
{
public:
// compute correction factor
static G4double CorrectionFactor(const G4int index, const G4int Z,
const G4double A13, const G4double CB,
const G4double eKin, const G4double eKin0);
// Data comes from Dostrovsky, Fraenkel and Friedlander
// Physical Review, vol 116, num. 3 1959
static G4double ProtonKValue(const G4int Z);
static G4double AlphaKValue(const G4int Z);
static G4double ProtonCValue(const G4int Z);
static G4double AlphaCValue(const G4int Z);
};
#endif
@@ -13,6 +13,7 @@ geant4_add_module(G4hadronic_deex_util
G4CookPairingCorrections.hh
G4CookShellCorrections.hh
G4CoulombBarrier.hh
G4DeexPrecoUtility.hh
G4KalbachCrossSection.hh
G4PairingCorrection.hh
G4ShellCorrection.hh
@@ -28,6 +29,7 @@ geant4_add_module(G4hadronic_deex_util
G4CookPairingCorrections.cc
G4CookShellCorrections.cc
G4CoulombBarrier.cc
G4DeexPrecoUtility.cc
G4KalbachCrossSection.cc
G4PairingCorrection.cc
G4ShellCorrection.cc
@@ -39,7 +39,7 @@ G4CoulombBarrier::G4CoulombBarrier(G4int A, G4int Z)
: G4VCoulombBarrier(A, Z)
{
factor = CLHEP::elm_coupling*Z;
SetParameters(0.4*G4NuclearRadii::RadiusCB(Z, A), 1.5*CLHEP::fermi);
theRho = 0.5*G4NuclearRadii::RadiusCB(Z, A);
}
G4double G4CoulombBarrier::GetCoulombBarrier(
@@ -0,0 +1,127 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// Geant4 class G4DeexPrecoUtility
//
// Author V.Ivanchenko 19.05.2025
//
#include "G4DeexPrecoUtility.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4DeexPrecoUtility::CorrectionFactor(const G4int index, const G4int Z,
const G4double A13,
const G4double CB,
const G4double eKin,
const G4double eKin0)
{
G4double res = 1.0;
G4double x;
switch (index) {
case 0:
x = (2.12*A13 - 0.05)/(2.2*A13 + 0.76);
res = (eKin + x)/(eKin0 + x);
break;
case 1:
x = ProtonKValue(Z);
res = std::max(eKin - x*CB, 0.0)/(eKin0 - x*CB);
break;
case 2:
x = ProtonKValue(Z) + 0.06;
res = std::max(eKin - x*CB, 0.0)/(eKin0 - x*CB);
break;
case 3:
x = ProtonKValue(Z) + 0.12;
res = std::max(eKin - x*CB, 0.0)/(eKin0 - x*CB);
break;
case 4:
x = AlphaKValue(Z) + 0.12;
res = std::max(eKin - x*CB, 0.0)/(eKin0 - x*CB);
break;
default:
x = AlphaKValue(Z);
res = std::max(eKin - x*CB, 0.0)/(eKin0 - x*CB);
break;
}
return res;
}
G4double G4DeexPrecoUtility::ProtonKValue(const G4int Z)
{
G4double res;
if (10 >= Z) { res = 0.42; }
else if (20 >= Z) { res = 0.42 + (Z - 10)*0.016; }
else if (30 >= Z) { res = 0.58 + (Z - 20)*0.01; }
else if (50 >= Z) { res = 0.68 + (Z - 30)*0.0045; }
else if (70 > Z) { res = 0.77 + (Z - 50)*0.0015; }
else { res = 0.8; }
return res;
}
G4double G4DeexPrecoUtility::AlphaKValue(const G4int Z)
{
G4double res;
if (10 >= Z) { res = 0.68; }
else if (20 >= Z) { res = 0.68 + (Z - 10)*0.014; }
else if (30 >= Z) { res = 0.82 + (Z - 20)*0.009; }
else if (50 >= Z) { res = 0.91 + (Z - 30)*0.003; }
else if (70 > Z) { res = 0.97 + (Z - 50)*0.0005; }
else { res = 0.98; }
return res;
}
G4double G4DeexPrecoUtility::ProtonCValue(const G4int Z)
{
G4double res;
if (10 >= Z) { res = 0.50; }
else if (20 >= Z) { res = 0.50 - (Z - 10)*0.022; }
else if (30 >= Z) { res = 0.28 - (Z - 20)*0.008; }
else if (50 >= Z) { res = 0.20 - (Z - 30)*0.0025; }
else if (70 > Z) { res = 0.15 - (Z - 50)*0.0025; }
else { res = 0.1; }
return res;
}
G4double G4DeexPrecoUtility::AlphaCValue(const G4int Z)
{
G4double res;
if (30 >= Z) { res = 0.10; }
else if (50 >= Z) { res = 0.10 - (Z - 30)*0.001; }
else if (70 >= Z) { res = 0.08 + (Z - 50)*0.001; }
else { res = 0.06; }
return res;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -4,6 +4,11 @@ See `CONTRIBUTING.rst` for details of **required** info/format for each entry,
which **must** added in reverse chronological order (newest at the top). It must **not**
be used as a substitute for writing good git commit messages!
## 2025-03-31 Vladimir Ivanchenko (hadr-emd-V11-03-01)
- G4EMDissociation : next attempt to fix Coverity warnings
## 2025-03-20 Vladimir Ivanchenko (hadr-emd-V11-03-00)
- G4EMDissociation : fixed Coverity warnings
## 2022-04-04 Vladimir Ivanchenko (hadr-emd-V11-00-01)
- G4EMDissociation : make consistent with G4Fragment modifications
@@ -164,6 +164,7 @@ G4HadFinalState *G4EMDissociation::ApplyYourself
G4double E = theTrack.GetKineticEnergy()/AP;
G4double MP = theTrack.GetTotalEnergy() - E*AP;
G4double b = pP.beta();
if (b <= DBL_MIN) { return &theParticleChange; }
G4double AT = theTarget.GetA_asInt();
G4double ZT = theTarget.GetZ_asInt();
G4double MT = G4NucleiProperties::GetNuclearMass(AT,ZT);
@@ -188,8 +189,8 @@ G4HadFinalState *G4EMDissociation::ApplyYourself
// Initialise the variables which will be used with the phase-space decay and
// to boost the secondaries from the interaction.
G4ParticleDefinition *typeNucleon = NULL;
G4ParticleDefinition *typeDaughter = NULL;
G4ParticleDefinition *typeNucleon = nullptr;
G4ParticleDefinition *typeDaughter = nullptr;
G4double Eg = 0.0;
G4double mass = 0.0;
G4ThreeVector boost = G4ThreeVector(0.0, 0.0, 0.0);
@@ -212,8 +213,7 @@ G4HadFinalState *G4EMDissociation::ApplyYourself
// or the target.
G4int secID = -1; // Creator model ID for the secondaries
if (G4UniformRand() <
totCrossSectionP / (totCrossSectionP + totCrossSectionT)) {
if (G4UniformRand() * (totCrossSectionP + totCrossSectionT) < totCrossSectionP) {
// It was the projectile which underwent EM dissociation. Define the Lorentz
// boost to be applied to the secondaries, and sample whether a proton or a
@@ -345,7 +345,7 @@ G4HadFinalState *G4EMDissociation::ApplyYourself
pp = std::sqrt(pp);
G4double costheta = 2.*G4UniformRand()-1.0;
G4double sintheta = std::sqrt((1.0 - costheta)*(1.0 + costheta));
G4double phi = 2.0*pi*G4UniformRand()*rad;
G4double phi = 2.0*pi*G4UniformRand();
G4ThreeVector direction(sintheta*std::cos(phi),sintheta*std::sin(phi),costheta);
G4DynamicParticle *dynamicNucleon =
new G4DynamicParticle(typeNucleon, direction*pp);
@@ -6,6 +6,14 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2025-05-16 Ben Morgan (hadr-inclxx-V11-03-01)
- Replace the URL root.cern.ch with canonical root.cern
- Fixes [GitHub PR 87](https://github.com/Geant4/geant4/pull/87)
- Pure documentation, no functional change
## 2025-02-13 Gabriele Cosmo (hadr-inclxx-V11-03-00)
- Fixed one more reported Coverity defect for use of std::move() in G4INCLCascade.
## 2024-09-02 Gabriele Cosmo (hadr-inclxx-V11-02-01)
- Fixed reported Coverity defects for use of std::move().
@@ -444,7 +444,7 @@ namespace G4INCL {
sum = read_file(dataPathppbark, probabilities, particle_types);
rdm = ((1.-rdm)/kaonicFSprob)*sum; //2670 normalize by the sum of probabilities in the file
//now get the line number in the file where the FS particles are stored:
G4int n = findStringNumber(rdm, probabilities)-1;
G4int n = findStringNumber(rdm, std::move(probabilities))-1;
if ( n < 0 ) return theEventInfo;
for (G4int j = 0; j < static_cast<G4int>(particle_types[n].size()); j++) {
if (particle_types[n][j] == "pi0") {
@@ -245,7 +245,7 @@ namespace G4INCL {
* historical GENBOD routine [CERN report 68-15 (1968)]. The ROOT
* implementation is documented at the following URL:
*
* http://root.cern.ch/root/html/TGenPhaseSpace.html#TGenPhaseSpace
* http://root.cern/root/html/TGenPhaseSpace.html#TGenPhaseSpace
*/
void phaseSpaceDecayLegacy(Cluster * const c, ClusterDecayType theDecayMode, ParticleList *decayProducts) {
const G4int theA = c->getA();
@@ -6,6 +6,21 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2025-05-14 Bret Beck, Caleb Matoon, Godfree Gert, Douglas M Wright (hadr-lend-V11-03-02)
- Fixes aimed for high impact issues identified by Coverity.
## 2025-02-04 Bret Beck, Caleb Matoon, Godfree Gert, Douglas M Wright (hadr-lend-V11-03-01)
- Major update of GIDIplus interface with refactored c++ code including:
o uses official GNDS formatted data
o added feature for high-fidelity gamma cascades following reactions such as neutron capture and inelastic scattering
## 2024-12-10 Douglas M Wright (hadr-lend-V11-03-00)
- Collect all inelastic models (neutron and gamma induced) into G4HadronPhysicsLEND
o update and simplify Shielding and G4EmExtraPhysics accordingly
o fixed two bugs:
- G4EmExtraPhysics failed to load photonuclear from LEND if G4GammaGeneralProcess existed
- G4LENDCombinedModel photofission check energy function was not connected to the base class which results in a crash
## 2024-08-21 Gabriele Cosmo (hadr-lend-V11-02-05)
- Fixed reported Coverity defects for:
o pointless expression condition in ptwXY_div_ptwXY() operator;
@@ -0,0 +1,4 @@
LEND directory with G4GIDI and GIDI+ assembled on 2025-03-25 13:27:37
G4GIDI git hash = 62db2f9b95bcd850c8821e70db50c4c94874cc4d
G4GIDI git describe = G4GIDI.1.1.0-13-g62db2f9
GIDI+ git describe = GIDI_plus.3.32.0-21-g25ae8f5
@@ -24,63 +24,153 @@
// ********************************************************************
//
#ifndef G4GIDI_h_included
#define G4GIDI_h_included 1
#include <string>
#include <list>
#include <vector>
//using namespace std;
#include <list>
#include "G4Types.hh"
#include "G4GIDI_Misc.hh"
#include "G4GIDI_map.hh"
#include "G4GIDI_target.hh"
#include "G4GIDI_mass.hh"
#include <G4Types.hh>
#include <MCGIDI.hpp>
#ifndef G4GIDI_hh_included
#define G4GIDI_hh_included 1
#define channelID std::string
extern PoPI::Database G4GIDI_pops;
class G4GIDI_Product {
public:
int A, Z, m;
double kineticEnergy, px, py, pz;
double birthTimeSec;
};
class G4GIDI_target {
private:
MCGIDI::Protare *m_MCGIDI_protare;
std::string m_target;
std::string m_fileName;
int m_targetZ;
int m_targetA;
int m_targetM;
double m_targetMass;
MCGIDI::DomainHash m_domainHash;
MCGIDI::URR_protareInfos m_URR_protareInfos;
std::vector<int> m_elasticIndices;
std::vector<int> m_captureIndices;
std::vector<int> m_fissionIndices;
std::vector<int> m_othersIndices;
MCGIDI::Probabilities::ProbabilityBase2d const *m_elasticAngular;
public:
G4GIDI_target( PoPI::Database const &a_pops, MCGIDI::DomainHash const &a_domainHash, GIDI::Protare const &a_GIDI_protare,
MCGIDI::Protare *a_MCGIDI_protare );
~G4GIDI_target( );
std::string const *getName( ) const { return( &m_target ); }
std::string const *getFilename( ) const { return( &m_fileName ); }
int getZ( ) const { return( m_targetZ ); }
int getA( ) const { return( m_targetA ); }
int getM( ) const { return( m_targetM ); }
double getMass( ) const { return( m_targetMass ); }
// int getTemperatures( double *a_temperatures ) const ;
// int readTemperature( int index );
// std::string getEqualProbableBinSampleMethod( );
// int setEqualProbableBinSampleMethod( std::string const &a_method );
std::vector<int> const &elasticIndices( ) { return( m_elasticIndices ); }
std::vector<int> const &captureIndices( ) { return( m_captureIndices ); }
std::vector<int> const &fissionIndices( ) { return( m_fissionIndices ); }
std::vector<int> const &othersIndices( ) { return( m_othersIndices ); }
int getNumberOfChannels( ) const ;
int getNumberOfProductionChannels( ) const ;
channelID getChannelsID( int channelIndex ) const ;
std::vector<channelID> *getChannelIDs( ) const ;
std::vector<channelID> *getProductionChannelIDs( ) const ;
// std::vector<double> *getEnergyGridAtTIndex( int index );
double getTotalCrossSectionAtE( double a_energy, double a_temperature ) const ;
double getElasticCrossSectionAtE( double a_energy, double a_temperature ) const ;
double getCaptureCrossSectionAtE( double a_energy, double a_temperature ) const ;
double getFissionCrossSectionAtE( double a_energy, double a_temperature ) const ;
double getOthersCrossSectionAtE( double a_energy, double a_temperature ) const ;
double sumChannelCrossSectionAtE( std::vector<int> const &a_indices, double a_energy, double a_temperature ) const ;
double sumChannelCrossSectionAtE( int a_nIndices, int const *a_indices, double a_energy, double a_temperature ) const ;
int sampleChannelCrossSectionAtE( std::vector<int> const &a_indices, double a_energy, double a_temperature,
double (*a_rng)( void * ), void *a_rngState ) const ;
int sampleChannelCrossSectionAtE( int a_nIndices, int const *a_indices, double a_energy, double a_temperature,
double (*a_rng)( void * ), void *a_rngState ) const ;
double getElasticFinalState( double a_energy, double a_temperature, double (*a_rng)( void * ), void *a_rngState ) const ;
std::vector<G4GIDI_Product> *getCaptureFinalState( double a_energy, double a_temperature, double (*a_rng)( void * ), void *a_rngState ) const ;
std::vector<G4GIDI_Product> *getFissionFinalState( double a_energy, double a_temperature, double (*a_rng)( void * ), void *a_rngState ) const ;
std::vector<G4GIDI_Product> *getOthersFinalState( double a_energy, double a_temperature, double (*a_rng)( void * ), void *a_rngState ) const ;
std::vector<G4GIDI_Product> *getFinalState( std::vector<int> const &a_indices, double a_energy, double a_temperature,
double (*a_rng)( void * ), void *a_rngState ) const ;
std::vector<G4GIDI_Product> *getFinalState( int a_nIndices, int const *a_indices, double a_energy, double a_temperature,
double (*a_rng)( void * ), void *a_rngState ) const ;
// double getReactionsThreshold( int a_index ) const ;
// void getReactionsDomain( int a_index, double *a_EMin, double *a_EMax ) const ;
};
class G4GIDI {
private:
G4int projectileID;
std::string projectile;
std::list<G4GIDI_map *> dataDirectories;
std::vector<G4GIDI_target *> targets;
G4int init( G4int ip );
G4int m_projectileIP;
std::string m_projectile;
std::vector<GIDI::Map::Map *> m_maps;
std::vector<G4GIDI_target *> m_protares;
public:
G4GIDI( G4int ip, const std::string &dataDirectory );
G4GIDI( G4int ip, std::list<std::string> &dataDirectory );
G4GIDI( G4int a_ip, std::string const &a_dataDirectory );
G4GIDI( G4int a_ip, std::list<std::string> const &a_dataDirectory );
~G4GIDI( );
G4int numberOfDataDirectories( void );
G4int addDataDirectory( const std::string &dataDirectory );
G4int removeDataDirectory( const std::string &dataDirectory );
std::string getDataDirectoryAtIndex( G4int index );
std::vector<std::string> *getDataDirectories( void );
G4int projectileIP( ) const { return( m_projectileIP ); }
G4bool isThisDataAvailable( const std::string &lib_name, G4int iZ, G4int iA, G4int iM = 0 );
G4bool isThisDataAvailable( const std::string &lib_name, const std::string &targetName );
G4int numberOfDataDirectories( ) const { return( static_cast<G4int>( m_maps.size( ) ) ); }
G4int addDataDirectory( std::string const &a_dataDirectory );
G4int removeDataDirectory( std::string const &a_dataDirectory );
std::string const getDataDirectoryAtIndex( G4int a_index ) const ;
std::vector<std::string> *getDataDirectories( ) const ;
char *dataFilename( const std::string &lib_name, G4int iZ, G4int iA, G4int iM = 0 );
char *dataFilename( const std::string &lib_name, const std::string &targetName );
bool isThisDataAvailable( std::string const &a_lib_name, G4int a_Z, G4int a_A, G4int a_M = 0 ) const ;
bool isThisDataAvailable( std::string const &a_lib_name, std::string const &a_targetName ) const ;
std::vector<std::string> *getNamesOfAvailableLibraries( G4int iZ, G4int iA, G4int iM = 0 );
std::vector<std::string> *getNamesOfAvailableLibraries( const std::string &targetName );
std::string dataFilename( std::string const &lib_name, G4int a_Z, G4int a_A, G4int a_M = 0 ) const ;
std::string dataFilename( std::string const &lib_name, std::string const &a_targetName ) const ;
std::vector<std::string> *getNamesOfAvailableTargets( void );
std::vector<std::string> *getNamesOfAvailableLibraries( G4int a_Z, G4int a_A, G4int a_M = 0 ) const ;
std::vector<std::string> *getNamesOfAvailableLibraries( std::string const &a_targetName ) const ;
G4GIDI_target *readTarget( const std::string &lib_name, G4int iZ, G4int iA, G4int iM = 0, G4bool bind = true );
G4GIDI_target *readTarget( const std::string &lib_name, const std::string &targetName, G4bool bind = true );
std::vector<std::string> *getNamesOfAvailableTargets( ) const ;
G4GIDI_target *getAlreadyReadTarget( G4int iZ, G4int iA, G4int iM = 0 );
G4GIDI_target *getAlreadyReadTarget( const std::string &targetName );
G4GIDI_target *readTarget( std::string const &lib_name, G4int a_Z, G4int a_A, G4int a_M = 0, bool a_bind = true );
G4GIDI_target *readTarget( std::string const &lib_name, std::string const &a_targetName, bool a_bind = true );
G4int freeTarget( G4int iZ, G4int iA, G4int iM = 0 );
G4int freeTarget( const std::string &targetSymbol );
G4int freeTarget( G4GIDI_target *target );
G4GIDI_target *getAlreadyReadTarget( G4int a_Z, G4int a_A, G4int a_M = 0 );
G4GIDI_target *getAlreadyReadTarget( std::string const &a_targetName );
std::vector<std::string> *getListOfReadTargetsNames( void );
G4int freeTarget( G4int a_Z, G4int a_A, G4int a_M = 0 );
G4int freeTarget( std::string const &a_targetSymbol );
G4int freeTarget( G4GIDI_target *a_target );
std::vector<std::string> *getListOfReadTargetsNames( );
};
#endif // End of G4GIDI_h_included
std::string G4GIDI_version( );
int G4GIDI_versionMajor( );
int G4GIDI_versionMinor( );
int G4GIDI_versionPatchLevel( );
std::string G4GIDI_GitHash( );
void G4GIDI_initialize( std::string const &a_dataPath );
std::string G4GIDI_Misc_Z_toSymbol( int a_Z );
std::string G4GIDI_Misc_Z_A_m_ToName( int a_Z, int a_A, int a_M );
#endif // End of G4GIDI_hh_included
@@ -1,115 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
/*
# <<BEGIN-copyright>>
# <<END-copyright>>
*/
#ifndef G4GIDI_target_h_included
#define G4GIDI_target_h_included 1
#include <vector>
#include <string>
//using namespace std;
#include <statusMessageReporting.h>
#include <MCGIDI.h>
typedef struct crossSectionData_s crossSectionData;
typedef struct G4GIDI_Product_s G4GIDI_Product;
struct crossSectionData_s {
int start, end;
std::vector<double> crossSection;
};
#define channelID std::string
struct G4GIDI_Product_s {
int A, Z, m;
double kineticEnergy, px, py, pz;
double birthTimeSec;
};
class G4GIDI_target {
public:
void init( const char *fileName );
std::string equalProbableBinSampleMethod;
int nElasticIndices, nCaptureIndices, nFissionIndices, nOthersIndices;
int *elasticIndices, *captureIndices, *fissionIndices, *othersIndices;
public:
GIDI::statusMessageReporting smr;
int projectilesPOPID;
std::string name;
std::string sourceFilename;
double mass;
GIDI::MCGIDI_target *target;
G4GIDI_target( const char *fileName );
G4GIDI_target( std::string const &fileName );
~G4GIDI_target( );
std::string *getName( void );
std::string *getFilename( void );
int getZ( void );
int getA( void );
int getM( void );
double getMass( void );
int getTemperatures( double *temperatures );
int readTemperature( int index );
std::string getEqualProbableBinSampleMethod( void );
int setEqualProbableBinSampleMethod( std::string method );
int getNumberOfChannels( void );
int getNumberOfProductionChannels( void );
channelID getChannelsID( int channelIndex );
std::vector<channelID> *getChannelIDs( void );
std::vector<channelID> *getProductionChannelIDs( void );
std::vector<double> *getEnergyGridAtTIndex( int index );
double getTotalCrossSectionAtE( double e_in, double temperature );
double getElasticCrossSectionAtE( double e_in, double temperature );
double getCaptureCrossSectionAtE( double e_in, double temperature );
double getFissionCrossSectionAtE( double e_in, double temperature );
double getOthersCrossSectionAtE( double e_in, double temperature );
double sumChannelCrossSectionAtE( int nIndices, int *indices, double e_in, double temperature );
int sampleChannelCrossSectionAtE( int nIndices, int *indices, double e_in, double temperature, double (*rng)( void * ), void *rngState );
double getElasticFinalState( double e_in, double temperature, double (*rng)( void * ), void *rngState );
std::vector<G4GIDI_Product> *getCaptureFinalState( double e_in, double temperature, double (*rng)( void * ), void *rngState );
std::vector<G4GIDI_Product> *getFissionFinalState( double e_in, double temperature, double (*rng)( void * ), void *rngState );
std::vector<G4GIDI_Product> *getOthersFinalState( double e_in, double temperature, double (*rng)( void * ), void *rngState );
std::vector<G4GIDI_Product> *getFinalState( int nIndices, int *indices, double e_in, double temperature, double (*rng)( void * ), void *rngState );
double getReactionsThreshold( int index );
double getReactionsDomain( int index, double *EMin, double *EMax );
};
#endif // End of G4GIDI_target_h_included
@@ -35,8 +35,9 @@
// Derived calculational constants
// GIDI is developped at Lawrence Livermore National Laboratory
// Class Description - End
// 170912 First implementation done by T. Koi (SLAC/EPP)
//
// 2012-09-17 T. Koi (SLAC/EPP): First implementation
// 2024-07-17 D.M.Wright (LLNL): Added GetFatalEnergyCheckLevels()
#include "G4LENDModel.hh"
@@ -59,7 +60,10 @@ class G4LENDCombinedModel : public G4LENDModel
G4bool HasData( const G4DynamicParticle* , G4int iZ , G4int iA , G4int iM,
const G4Isotope* , const G4Element* , const G4Material* );
G4LENDModel* channel_selected; // used in GetFatalEnergyCheckLevels()
virtual const std::pair<G4double, G4double> GetFatalEnergyCheckLevels() const;
private:
G4LENDCombinedCrossSection* crossSection;
G4LENDElastic* elastic;
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,174 @@
/*
# <<BEGIN-copyright>>
# Copyright 2019, Lawrence Livermore National Security, LLC.
# This file is part of the gidiplus package (https://github.com/LLNL/gidiplus).
# gidiplus is licensed under the MIT license (see https://opensource.org/licenses/MIT).
# SPDX-License-Identifier: MIT
# <<END-copyright>>
*/
#ifndef GIDI_data_hpp_included
#define GIDI_data_hpp_included 1
#include <stdio.h>
#include <string>
#include <vector>
namespace GIDI {
/*
============================================================
=========================== Data1d =========================
============================================================
*/
class Data1d { // BRB: currently not used.
private:
std::vector<double> m_xs;
std::vector<double> m_ys;
public:
Data1d( std::size_t a_number, double const *const a_xs );
Data1d( std::size_t a_number, double const *const a_xs, double const *const a_ys );
Data1d( std::vector<double> const &a_xs );
Data1d( std::vector<double> const &a_xs, std::vector<double> const &a_ys );
Data1d( Data1d const &a_1dData );
~Data1d( );
std::size_t size( ) const { return( m_xs.size( ) ); }
Data1d operator+( double a_value ) const ;
Data1d &operator+=( double a_value );
Data1d operator+( Data1d const &a_rhs ) const ;
Data1d &operator+=( Data1d const &a_rhs );
Data1d operator-( double a_value ) const ;
Data1d &operator-=( double a_value );
Data1d operator-( Data1d const &a_rhs ) const ;
Data1d &operator-=( Data1d const &a_rhs );
Data1d operator*( double a_value ) const ;
Data1d &operator*=( double a_value );
Data1d operator/( double a_value ) const ;
Data1d &operator/=( double a_value );
void print( std::string const &a_prefix ) const ;
};
/*
============================================================
========================== Vector ==========================
============================================================
*/
class Vector {
private:
std::vector<double> m_vector; /**< The list of elements, each is a double instance. */
void writeWithBoundaries2( FILE *a_file, char const *a_format, std::vector<double> const &a_boundaries, double a_epsilon ) const ;
public:
Vector( std::size_t a_number = 0 );
Vector( std::vector<double> const &a_values );
Vector( std::size_t a_number, double const *a_values );
Vector( Vector const &a_vector );
~Vector( );
Vector &operator=( Vector const &a_rhs );
std::size_t size( ) const { return( m_vector.size( ) ); } /**< Returns a number of elements of *this*. */
void resize( std::size_t a_number, double a_value = 0.0 ) { m_vector.resize( a_number, a_value ); } /**< Resizes *this* to *a_number* elements. For details, see std::vector.resize. */
std::vector<double> &data( ) { return( m_vector ); }
double &operator[]( std::size_t a_index ) { return( m_vector[a_index] ); } /**< Returns a reference to the (*a_index*-1)th element. */
double operator[]( std::size_t a_index ) const { return( m_vector[a_index] ); } /**< Returns a reference to the (*a_index*-1)th element. */
Vector operator+( double a_value ) const ;
Vector &operator+=( double a_value );
Vector operator+( Vector const &a_rhs ) const ;
Vector &operator+=( Vector const &a_rhs );
Vector operator-( double a_value ) const ;
Vector &operator-=( double a_value );
Vector operator-( Vector const &a_rhs ) const ;
Vector &operator-=( Vector const &a_rhs );
Vector operator*( double a_value ) const ;
Vector &operator*=( double a_value );
Vector operator/( double a_value ) const ;
Vector &operator/=( double a_value );
void reverse( );
void setToValueInFlatRange( std::size_t a_start, std::size_t a_end, double a_value );
double sum( );
void print( std::string const &a_prefix ) const ;
void write( FILE *a_file, std::string const &a_prefix ) const ;
void writeWithBoundaries( FILE *a_file, char const *a_format, std::vector<double> const &a_boundaries, double a_epsilon ) const ;
};
/*
============================================================
========================== Matrix ==========================
============================================================
*/
class Matrix {
private:
std::vector<Vector> m_matrix; /**< The list of rows, each is a Vector instance. */
public:
Matrix( std::size_t a_rows, std::size_t a_columns );
Matrix( Matrix const &a_gidi_matrix );
~Matrix( );
Matrix &operator=( Matrix const &a_rhs );
std::size_t size( ) const { return( m_matrix.size( ) ); } /**< Returns the number of rows or *this*. */
Vector &operator[]( std::size_t a_index ) { return( m_matrix[a_index] ); } /**< Returns a reference to the (*a_index*-1)th row. */
Vector const &operator[]( std::size_t a_index ) const { return( m_matrix[a_index] ); } /**< Returns a reference to the (*a_index*-1)th row. */
/** Sets the cell at row **a_row** and column **a_column** to **a_value**. */
void operator()( std::size_t a_row /**< The cell's row. */,
std::size_t a_column /**< The cell's row. */,
double a_value /**< The value to put in the cell. */ )
{ m_matrix[a_row][a_column] = a_value; }
std::vector<Vector> const &matrix( ) const { return( m_matrix ); }
Matrix operator+( double a_value ) const ;
Matrix &operator+=( double a_value );
Matrix operator+( Matrix const &a_rhs ) const ;
Matrix &operator+=( Matrix const &a_rhs );
Matrix operator-( double a_value ) const ;
Matrix &operator-=( double a_value );
Matrix operator-( Matrix const &a_rhs ) const ;
Matrix &operator-=( Matrix const &a_rhs );
Matrix operator*( double a_value ) const ;
Matrix &operator*=( double a_value );
Matrix operator/( double a_value ) const ;
Matrix &operator/=( double a_value );
std::size_t numberOfColumns( ) const ;
/** Sets the cell at row **a_row** and column **a_column** to **a_value**. */
void set( std::size_t a_row /**< The cell's row. */,
std::size_t a_column /**< The cell's row. */,
double a_value /**< The value to put in the cell. */ )
{ m_matrix[a_row][a_column] = a_value; }
/** Sets the row at **a_row** to **a_vector**. */
void set( std::size_t a_row /**< The row to set. */,
Vector const &a_vector /**< The Vector to set at row **a_row**. */ )
{ m_matrix[a_row] = a_vector; }
void push_back( Vector const &a_vector );
Matrix transpose( );
void reverse( );
void print( std::string const &a_prefixForRow ) const ;
};
}
#endif // End of GIDI_data_hpp_included
@@ -1,243 +0,0 @@
/*
# <<BEGIN-copyright>>
# <<END-copyright>>
*/
#define GIDI_USE_BDFLS 0
#ifndef GIDI_settings_hpp_included
#define GIDI_settings_hpp_included 1
#include <string>
#include <vector>
#include <map>
#include <ptwX.h>
#include <ptwXY.h>
#include <statusMessageReporting.h>
/* Disable Effective C++ warnings in GIDI header files. */
#if defined( __INTEL_COMPILER )
#pragma warning( push )
#if __INTEL_COMPILER > 1399
#pragma warning( disable:2021 )
#elif __INTEL_COMPILER > 1199
#pragma warning( disable:2304 )
#endif
#endif
#define GIDI_settings_projectileEnergyMode_continuousEnergy 1
#define GIDI_settings_projectileEnergyMode_grouped ( 1 << 1 )
#define GIDI_settings_projectileEnergyMode_fixedGrid ( 1 << 2 )
class GIDI_settings_group {
private:
std::string mLabel;
std::vector<double> mBoundaries;
public:
GIDI_settings_group( std::string const &label = "empty", int size = 0 );
GIDI_settings_group( std::string const &label, int length, double const *values );
GIDI_settings_group( std::string const &label, std::vector<double> const &boundaries );
GIDI_settings_group( GIDI_settings_group const &group );
GIDI_settings_group& operator=( const GIDI_settings_group &group );
~GIDI_settings_group( );
inline double operator[]( int const index ) const { return( mBoundaries[index] ); }
inline int size( void ) const { return( (int) mBoundaries.size( ) ); }
inline int getNumberOfGroups( void ) const { return( (int) ( mBoundaries.size( ) - 1 ) ); }
inline double const *pointer( void ) const { return( &(mBoundaries[0]) ); }
void setFromCDoubleArray( int length, double *values );
inline std::string getLabel( ) const { return( mLabel ); }
int getGroupIndexFromEnergy( double energy, bool encloseOutOfRange ) const;
inline bool isLabel( std::string &label ) const { return( label == mLabel ); }
void print( bool outline = false, int valuesPerLine = 10 ) const;
private:
void initialize( std::string const &label, int size, int length, double const *values );
};
#if GIDI_USE_BDFLS
#include <cbdfls.h>
class GIDI_settings_groups_from_bdfls {
private:
std::vector<GIDI_settings_group> mGroups;
public:
GIDI_settings_groups_from_bdfls( std::string const &fileName );
GIDI_settings_groups_from_bdfls( char const *fileName );
GIDI_settings_groups_from_bdfls( cbdfls_file const *bdfls );
~GIDI_settings_groups_from_bdfls( );
GIDI_settings_group getViaGID( int gid ) const;
std::vector<std::string> getLabels( void ) const;
std::vector<int> getGIDs( void ) const;
void print( bool outline = true, int valuesPerLine = 10 ) const;
private:
void initialize( char const *fileName );
void initialize2( cbdfls_file const *bdfls );
};
#endif
/**
This class stores the flux for one Legendre order (see class GIDI_settings_flux).
*/
class GIDI_settings_flux_order {
private:
int mOrder; /**< The Legendre order of the flux. */
std::vector<double> mEnergies; /**< List of flux energies. */
std::vector<double> mFluxes; /**< List of flux values - one for each element of mEnergies. */
public:
GIDI_settings_flux_order( int order /**< The Legendre order for this flux data. */ );
GIDI_settings_flux_order( int order /**< The Legendre order for this flux data. */,
int length /**< The number or values in energies and fluxes. */,
double const *energies /**< List of energies where flux is given. */,
double const *fluxes /**< List of flux value for each energies value. */ );
GIDI_settings_flux_order( int order /**< The Legendre order for this flux data. */,
std::vector<double> const &energies /**< List of energies where flux is given. */,
std::vector<double> const &fluxes /**< List of flux value for each energies value. */ );
GIDI_settings_flux_order( GIDI_settings_flux_order const &fluxOrder /**< Legendre flux order to copy. */ );
GIDI_settings_flux_order& operator=( const GIDI_settings_flux_order &fluxOrder );
~GIDI_settings_flux_order( );
inline int getOrder( void ) const { return( mOrder ); }
inline int size( void ) const { return( (int) mEnergies.size( ) ); }
inline double const *getEnergies( void ) const { return( &(mEnergies[0]) ); }
inline double const *getFluxes( void ) const { return( &(mFluxes[0]) ); }
void print( int valuesPerLine = 10 ) const;
private:
void initialize( int order, int length, double const *energies, double const *fluxes );
};
class GIDI_settings_flux {
private:
std::string mLabel; /**< Label for the flux. */
double mTemperature;
std::vector<GIDI_settings_flux_order> mFluxOrders; /**< List of fluxes for each Legendre order, l, sorted by Legendre order starting with l = 0. */
public:
GIDI_settings_flux( std::string const &label, double temperature_MeV );
GIDI_settings_flux( char const *label, double temperature_MeV );
GIDI_settings_flux( GIDI_settings_flux const &flux );
GIDI_settings_flux& operator=( const GIDI_settings_flux &flux );
~GIDI_settings_flux( );
GIDI_settings_flux_order const *operator[]( int order ) const;
inline int getMaxOrder( void ) const { return( (int) mFluxOrders.size( ) - 1 ); }
inline int size( void ) const { return( (int) mFluxOrders.size( ) ); }
inline std::string getLabel( ) const { return( mLabel ); }
inline bool isLabel( std::string const &label ) const { return( label == mLabel ); }
inline bool isLabel( char const *label ) const { return( label == mLabel ); }
inline double getTemperature( ) const { return( mTemperature ); }
void addFluxOrder( GIDI_settings_flux_order const &fluxOrder );
void print( bool outline = true, int valuesPerLine = 10 ) const;
};
#if GIDI_USE_BDFLS
class GIDI_settings_fluxes_from_bdfls {
private:
std::vector<GIDI_settings_flux> mFluxes;
public:
GIDI_settings_fluxes_from_bdfls( std::string const &fileName, double temperature_MeV );
GIDI_settings_fluxes_from_bdfls( char const *fileName, double temperature_MeV );
GIDI_settings_fluxes_from_bdfls( cbdfls_file const *bdfls, double temperature_MeV );
~GIDI_settings_fluxes_from_bdfls( );
GIDI_settings_flux getViaFID( int fid );
std::vector<std::string> getLabels( void );
std::vector<int> getFIDs( void );
void print( bool outline = true, int valuesPerLine = 10 );
private:
void initialize( char const *fileName, double temperature_MeV );
void initialize2( cbdfls_file const *bdfls, double temperature_MeV );
};
#endif
class GIDI_settings_processedFlux {
private:
GIDI_settings_flux mFlux;
std::vector<GIDI::ptwXYPoints *> mFluxXY; /* Same as mFlux but stored as ptwXYPoints for each l-order. */
std::vector<GIDI::ptwXPoints *> mGroupedFlux; /* mFlux grouped using mGroupX, and stored as ptwXPoints for each l-order. */
public:
GIDI_settings_processedFlux( GIDI_settings_flux const &flux, GIDI::ptwXPoints *groupX );
GIDI_settings_processedFlux( GIDI_settings_processedFlux const &flux );
GIDI_settings_processedFlux& operator=( const GIDI_settings_processedFlux &flux );
~GIDI_settings_processedFlux( );
inline double getTemperature( ) const { return( mFlux.getTemperature( ) ); }
GIDI::ptwXPoints *groupFunction( GIDI::statusMessageReporting *smr, GIDI::ptwXPoints *groupX, GIDI::ptwXYPoints *ptwXY1, int order ) const;
};
class GIDI_settings_particle {
private:
int mPoPId;
bool mTransporting;
int mEnergyMode;
GIDI_settings_group mGroup;
GIDI::ptwXPoints *mGroupX; /* Same as mGroup but stored as ptwXPoints. */
std::vector<GIDI_settings_processedFlux> mProcessedFluxes;
public:
GIDI_settings_particle( int PoPId, bool transporting, int energyMode );
GIDI_settings_particle( GIDI_settings_particle const &particle );
int initialize( int PoPId, bool transporting, int energyMode );
~GIDI_settings_particle( );
int addFlux( GIDI::statusMessageReporting *smr, GIDI_settings_flux const &flux );
GIDI_settings_processedFlux const *nearestFluxToTemperature( double temperature ) const;
inline int getGroupIndexFromEnergy( double e_in, bool encloseOutOfRange ) const { return( mGroup.getGroupIndexFromEnergy( e_in, encloseOutOfRange ) ); };
inline int getNumberOfGroups( void ) const { return( mGroup.getNumberOfGroups( ) ); };
inline int getPoPId( void ) const { return( mPoPId ); }
inline int getEnergyMode( void ) const { return( mEnergyMode ); }
inline bool getTransporting( void ) const { return( mTransporting ); }
inline GIDI_settings_group getGroup( void ) const { return( mGroup ); }
GIDI_settings_flux const *getFlux( double temperature ) const;
GIDI::ptwXPoints *groupFunction( GIDI::statusMessageReporting *smr, GIDI::ptwXYPoints *ptwXY1, double temperature, int order ) const;
void setGroup( GIDI_settings_group const &group );
inline bool isEnergyMode_continuous( void ) const { return( this->mEnergyMode & GIDI_settings_projectileEnergyMode_continuousEnergy ); }
inline bool isEnergyMode_grouped( void ) const { return( this->mEnergyMode & GIDI_settings_projectileEnergyMode_grouped ); }
inline bool isEnergyMode_fixedGrid( void ) const { return( this->mEnergyMode & GIDI_settings_projectileEnergyMode_fixedGrid ); }
private:
GIDI_settings_flux const *getProcessedFlux( double temperature ) const;
};
class GIDI_settings {
private:
std::map<int, GIDI_settings_particle> mParticles;
public:
GIDI_settings( );
~GIDI_settings( );
int addParticle( GIDI_settings_particle const &particle );
GIDI_settings_particle const *getParticle( int PoPId ) const;
int eraseParticle( int PoPId );
void releaseMemory( ) { mParticles.clear( ); }
};
#if defined( __INTEL_COMPILER )
#pragma warning( pop )
#endif
#endif // End of GIDI_settings_hpp_included
@@ -0,0 +1,369 @@
/*
# <<BEGIN-copyright>>
# Copyright 2019, Lawrence Livermore National Security, LLC.
# This file is part of the gidiplus package (https://github.com/LLNL/gidiplus).
# gidiplus is licensed under the MIT license (see https://opensource.org/licenses/MIT).
# SPDX-License-Identifier: MIT
# <<END-copyright>>
*/
#ifndef GUPI_hpp_included
#define GUPI_hpp_included 1
#include <list>
#include <map>
#include <LUPI_dataBuffer.hpp>
#include <LUPI.hpp>
#include <HAPI.hpp>
namespace GUPI {
class Entry;
class Suite;
typedef Entry *(*GUPI_parseSuite)( Suite *a_parent, HAPI::Node const &a_node );
#define GUPI_documentationChars "documentation"
#define GUPI_titleChars "title"
#define GUPI_abstractChars "abstract"
#define GUPI_bodyChars "body"
#define GUPI_endfCompatibleChars "endfCompatible"
#define GUPI_doiChars "doi"
#define GUPI_publicationDateChars "publicationDate"
#define GUPI_versionChars "version"
/*
============================================================
======================== WriteInfo =========================
============================================================
*/
class WriteInfo {
public:
std::list<std::string> m_lines;
std::string m_incrementalIndent;
int m_valuesPerLine;
std::string m_sep;
WriteInfo( std::string const &a_incrementalIndent = " ", int a_valuesPerLine = 100, std::string const &a_sep = " " );
std::string incrementalIndent( std::string const &indent ) { return( indent + m_incrementalIndent ); }
void push_back( std::string const &a_line ) { m_lines.push_back( a_line ); }
void addNodeStarter( std::string const &indent, std::string const &a_moniker, std::string const &a_attributes = "" ) {
m_lines.push_back( indent + "<" + a_moniker + a_attributes + ">" ); }
void addNodeStarterEnder( std::string const &indent, std::string const &a_moniker, std::string const &a_attributes = "" ) {
m_lines.push_back( indent + "<" + a_moniker + a_attributes + "/>" ); }
void addNodeEnder( std::string const &a_moniker ) { m_lines.back( ) += "</" + a_moniker + ">"; }
std::string addAttribute( std::string const &a_name, std::string const &a_value ) const { return( " " + a_name + "=\"" + a_value + "\"" ); }
std::string nodeStarter( std::string const &indent, std::string const &a_moniker, std::string const &a_attributes = "" )
{ return( indent + "<" + a_moniker + a_attributes + ">" ); }
std::string nodeEnder( std::string const &a_moniker ) { return( "</" + a_moniker + ">" ); }
void print( );
void clear( ) { m_lines.clear( ); } /**< Clears the contents of *m_lines*. */
};
/*
============================================================
========================= Ancestry =========================
============================================================
*/
class Ancestry {
public:
/* *********************************************************************************************************//**
* Constructs and returns the key name/value for the *this* node.
*
* @return The constructed key name/value.
***********************************************************************************************************/
static std::string buildXLinkItemKey( std::string const &a_name, std::string const &a_key ) {
if( a_key.size( ) == 0 ) return( "" );
return( "[@" + a_name + "='" + a_key + "']" );
}
private:
std::string m_moniker; /**< The node's name (i.e., moniker). */
Ancestry *m_ancestor; /**< The parent node of *this*. */
std::string m_attribute; /**< The name of the attribute in the node that uniquely identifies the node when the parent node containing other child nodes with the same moniker. */
Ancestry *findInAncestry2( std::size_t a_index, std::vector<std::string> const &a_segments );
Ancestry const *findInAncestry2( std::size_t a_index, std::vector<std::string> const &a_segments ) const ;
public:
Ancestry( std::string const &a_moniker, std::string const &a_attribute = "" );
virtual ~Ancestry( );
Ancestry &operator=( Ancestry const &a_ancestry );
std::string const &moniker( ) const { return( m_moniker ); } /**< Returns the value of the *m_moniker* member. */
void setMoniker( std::string const &a_moniker ) { m_moniker = a_moniker; } /**< Set the value of the *m_moniker* member to *a_moniker*. */
Ancestry *ancestor( ) { return( m_ancestor ); } /**< Returns the value of the *m_ancestor* member. */
Ancestry const *ancestor( ) const { return( m_ancestor ); } /**< Returns the value of the *m_ancestor* member. */
void setAncestor( Ancestry *a_ancestor ) { m_ancestor = a_ancestor; } /**< Sets the *m_ancestor* member to *a_ancestor*. */
std::string attribute( ) const { return( m_attribute ); } /**< Returns the value of the *m_attribute* member. */
Ancestry *root( );
Ancestry const *root( ) const ;
bool isChild( Ancestry *a_instance ) { return( this == a_instance->m_ancestor ); } /**< Returns true if *a_instance* is a child of *this*. */
bool isParent( Ancestry *a_parent ) { return( this->m_ancestor == a_parent ); } /**< Returns true if *a_instance* is the parent of *this*. */
bool isRoot( ) const { return( this->m_ancestor == nullptr ); } /**< Returns true if *this* is the root ancestor. */
Ancestry *findInAncestry( std::string const &a_href );
Ancestry const *findInAncestry( std::string const &a_href ) const ;
/* *********************************************************************************************************//**
* Used to tranverse **GNDS** nodes. This method returns a pointer to a derived class' *a_item* member or nullptr if none exists.
*
* @param a_item [in] The name of the class member whose pointer is to be return.
* @return The pointer to the class member or nullptr if class does not have a member named a_item.
***********************************************************************************************************/
virtual Ancestry *findInAncestry3( std::string const &a_item ) = 0;
virtual Ancestry const *findInAncestry3( std::string const &a_item ) const = 0;
virtual LUPI_HOST void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
virtual std::string xlinkItemKey( ) const { return( "" ); } /**< Returns the value of *this*'s key. */
std::string toXLink( ) const ;
virtual void toXMLList( WriteInfo &a_writeInfo, std::string const &a_indent = "" ) const ;
void printXML( ) const ;
};
/*
============================================================
========================== Entry ===========================
============================================================
*/
class Entry : public Ancestry {
private:
std::string m_keyName; /**< The name of the key used by the parent suite to reference *this* entry. */
std::string m_keyValue; /**< The key used by the parent suite to reference *this* entry. */
public:
Entry( std::string const &a_moniker, std::string const &a_keyName, std::string const &a_keyValue );
Entry( HAPI::Node const &a_node, std::string const &a_keyName );
~Entry( );
std::string const &keyName( ) const { return( m_keyName ); } /**< Returns a const reference to the *m_keyName* member. */
std::string const &keyValue( ) const { return( m_keyValue ); } /**< Returns a const reference to the *m_keyValue* member. */
Ancestry *findInAncestry3( LUPI_maybeUnused std::string const &a_item ) { return( nullptr ); }
Ancestry const *findInAncestry3( LUPI_maybeUnused std::string const &a_item ) const { return( nullptr ); }
LUPI_HOST void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
std::string xlinkItemKey( ) const {
if( m_keyValue == "" ) return( "" );
return( buildXLinkItemKey( m_keyName, m_keyValue ) );
}
};
/*
============================================================
========================== Text ============================
============================================================
*/
class Text : public Ancestry {
public:
enum class Encoding {
utf8,
ascii
};
enum class Markup {
none,
xml,
html,
latex
};
private:
std::string m_body;
Encoding m_encoding;
Markup m_markup;
std::string m_label;
public:
Text( HAPI::Node const &a_node );
~Text( );
std::string const &body( ) const { return m_body; }
Encoding encoding( ) const { return m_encoding; }
Markup markup( ) const { return m_markup; }
std::string const &label( ) const { return m_label; }
Ancestry *findInAncestry3( LUPI_maybeUnused std::string const &a_item ) { return( nullptr ); }
Ancestry const *findInAncestry3( LUPI_maybeUnused std::string const &a_item ) const { return( nullptr ); }
};
/*
============================================================
===================== Documentation ========================
============================================================
*/
class Documentation : public Ancestry {
private:
std::string m_doi; /**< The name of the key used by the parent suite to reference *this* entry. */
std::string m_publicationDate; /**< The key used by the parent suite to reference *this* entry. */
std::string m_version;
Text m_title;
Text m_abstract;
Text m_body;
public:
// Documentation(std::string const &a_moniker, Text const &a_doi, std::string const &a_publicationDate, Text const &a_version);
Documentation(HAPI::Node const &a_node);
~Documentation( );
std::string const &doi( ) const { return m_doi; }
std::string const &publicationDate( ) const { return m_publicationDate; }
std::string const &version( ) const { return m_version; }
Text const &title( ) const { return m_title; }
Text const &abstract( ) const { return m_abstract; }
Text const &body( ) const { return m_body; }
Ancestry *findInAncestry3( LUPI_maybeUnused std::string const &a_item ) { return( nullptr ); }
Ancestry const *findInAncestry3( LUPI_maybeUnused std::string const &a_item ) const { return( nullptr ); }
};
/*
============================================================
=========================== Suite ==========================
============================================================
*/
class Suite : public Ancestry {
public:
typedef std::vector<Entry *> Entries; /**< The typedef the the *m_entries* member. */
private:
std::string m_keyName; /**< The name of the key used to look up items in the suite. */
mutable Entries m_entries; /**< The list of nodes stored within *this*. */
std::map<std::string,int> m_map; /**< A map of *this* node labels to their index in *m_entries*. */
Suite( Suite const *a_suite ); // FIXME, should we make public or private copy constructor? Making private for now.
public:
Suite( std::string const &a_keyName );
Suite( std::string const &a_moniker, std::string const &a_keyName );
Suite( HAPI::Node const &a_node, std::string const &a_keyName, GUPI_parseSuite a_parseSuite );
~Suite( );
std::string const &keyName( ) const { return( m_keyName ); } /**< Returns a const reference to the *m_keyName* member. */
std::size_t size( ) const { return( m_entries.size( ) ); } /**< Returns the number of node contained by *this*. */
int operator[]( std::string const &a_label ) const ;
typedef Entries::iterator iterator;
typedef Entries::const_iterator const_iterator;
iterator begin( ) { return m_entries.begin( ); } /**< The C++ begin iterator for *this*. */
const_iterator begin( ) const { return m_entries.begin( ); } /**< The C++ const begin iterator for *this*. */
iterator end( ) { return m_entries.end( ); } /**< The C++ end iterator for *this*. */
const_iterator end( ) const { return m_entries.end( ); } /**< The C++ const end iterator for *this*. */
template<typename T> T *get( std::size_t a_Index );
template<typename T> T const *get( std::size_t a_Index ) const ;
template<typename T> T *get( std::string const &a_label );
template<typename T> T const *get( std::string const &a_label ) const ;
void parse( HAPI::Node const &a_node, GUPI_parseSuite a_parseSuite );
void add( Entry *a_entry );
iterator find( std::string const &a_label );
const_iterator find( std::string const &a_label ) const ;
bool has( std::string const &a_label ) const { return( find( a_label ) != m_entries.end( ) ); }
Ancestry *findInAncestry3( std::string const &a_item );
Ancestry const *findInAncestry3( std::string const &a_item ) const ;
std::vector<iterator> findAllOfMoniker( std::string const &a_moniker ) ;
std::vector<const_iterator> findAllOfMoniker( std::string const &a_moniker ) const ;
void toXMLList( WriteInfo &a_writeInfo, std::string const &a_indent = "" ) const ;
void printEntryLabels( std::string const &a_header ) const ;
};
/* *********************************************************************************************************//**
* Returns the node at index *a_index*.
*
* @param a_index [in] The index of the node to return.
*
* @return The node at index *a_index*.
***********************************************************************************************************/
template<typename T> T *Suite::get( std::size_t a_index ) {
Entry *entry = m_entries[a_index];
T *object = dynamic_cast<T *>( entry );
if( object == nullptr ) throw LUPI::Exception( "GIDI::Suite::get( std::size_t ): invalid cast" );
return( object );
}
/* *********************************************************************************************************//**
* Returns the node at index *a_index*.
*
* @param a_index [in] The index of the node to return.
*
* @return The node at index *a_index*.
***********************************************************************************************************/
template<typename T> T const *Suite::get( std::size_t a_index ) const {
Entry *entry = m_entries[a_index];
T *object = dynamic_cast<T *>( entry );
if( object == nullptr ) throw LUPI::Exception( "GIDI::Suite::get( std::size_t ): invalid cast" );
return( object );
}
/* *********************************************************************************************************//**
* Returns the node with label *a_label*.
*
* @param a_label [in] The label of the node to return.
*
* @return The node with label *a_label*.
***********************************************************************************************************/
template<typename T> T *Suite::get( std::string const &a_label ) {
int index = (*this)[a_label];
Entry *entry = m_entries[index];
T *object = dynamic_cast<T *>( entry );
if( object == nullptr ) throw LUPI::Exception( "GIDI::Suite::get( std::string const & ): invalid cast" );
return( object );
}
/* *********************************************************************************************************//**
* Returns the node with label *a_label*.
*
* @param a_label [in] The label of the node to return.
*
* @return The node with label *a_label*.
***********************************************************************************************************/
template<typename T> T const *Suite::get( std::string const &a_label ) const {
int index = (*this)[a_label];
Entry *entry = m_entries[index];
T *object = dynamic_cast<T *>( entry );
if( object == nullptr ) throw LUPI::Exception( "GIDI::Suite::get( std::string const & ): invalid cast" );
return( object );
}
} // End of namespace GUPI.
#endif // GUPI_hpp_included
@@ -0,0 +1,420 @@
/*
# <<BEGIN-copyright>>
# Copyright 2019, Lawrence Livermore National Security, LLC.
# This file is part of the gidiplus package (https://github.com/LLNL/gidiplus).
# gidiplus is licensed under the MIT license (see https://opensource.org/licenses/MIT).
# SPDX-License-Identifier: MIT
# <<END-copyright>>
*/
#ifndef HAPI_hpp_included
#define HAPI_hpp_included 1
#include <string>
#include <stdlib.h>
#include <vector>
#include <stdexcept>
#include <nf_buffer.h>
#include <nf_utilities.h>
#define HAPI_USE_PUGIXML 1
#ifdef HAPI_USE_PUGIXML
#include <pugixml.hpp>
#endif
#ifdef HAPI_USE_HDF5
#include <hdf5.h>
#endif
#include <LUPI.hpp>
namespace HAPI {
enum class NodeInteralType { pugiXML, HDF5 };
// container classes for reading in from various data sources:
/*
============================================================
========================= Attribute ========================
============================================================
*/
class Node_internal;
class Attribute {
private:
Node_internal *m_node;
std::string m_name;
//std::string m_value;
public:
inline Attribute() : m_node(nullptr), m_name() {}
inline Attribute(Node_internal *a_node, std::string const a_name) :
m_node(a_node),
m_name(a_name)
{
}
~Attribute() = default;
//std::string const &name() const { return( m_name ); }
inline std::string const value() const;
inline int as_int() const;
inline long as_long() const;
inline double as_double() const;
};
/*
============================================================
=========================== Text ===========================
============================================================
*/
class Text {
private:
std::string m_text;
public:
Text();
Text(std::string const a_text);
~Text();
std::string const &get() const { return( m_text ); }
};
/*
============================================================
================== Data_internal (base class) ==============
============================================================
*/
class Data_internal {
public:
Data_internal() { };
virtual ~Data_internal() = 0;
//std::string const getDataType();
//virtual template <typename T> T read() = 0;
virtual void getDoubles(nf_Buffer<double> &buffer) = 0;
virtual void getInts(nf_Buffer<int> &buffer) = 0;
virtual int length() const = 0;
};
/*
============================================================
=================== Node_internal (base class) =============
============================================================
*/
class Node_internal {
private:
NodeInteralType m_type;
public:
Node_internal( NodeInteralType a_type );
Node_internal( Node_internal const &a_node );
virtual ~Node_internal() = 0;
NodeInteralType type( ) const { return( m_type ); }
virtual std::string attribute(const char* name) = 0;
virtual int attribute_as_int(const char* name) = 0;
virtual long attribute_as_long(const char* name) = 0;
virtual double attribute_as_double(const char* name) = 0;
virtual Node_internal *child(const char* name) = 0;
virtual Node_internal *first_child() = 0;
virtual Node_internal *next_sibling() = 0;
virtual void to_next_sibling() = 0;
virtual Node_internal *copy() = 0;
virtual std::string name() const = 0;
virtual bool empty() const = 0;
virtual Text text() const = 0;
virtual Data_internal *data() const = 0;
};
inline std::string const Attribute::value() const { return( m_node->attribute( m_name.c_str()) ); }
inline int Attribute::as_int() const { return( m_node->attribute_as_int(m_name.c_str()) ); }
inline long Attribute::as_long() const { return( m_node->attribute_as_long(m_name.c_str()) ); }
inline double Attribute::as_double() const { return( m_node->attribute_as_double(m_name.c_str()) ); }
/*
============================================================
=========================== Data ===========================
============================================================
*/
class Data {
private:
Data_internal *m_data;
public:
Data();
Data( Data_internal *a_data );
~Data();
void getDoubles(nf_Buffer<double> &buffer);
void getInts(nf_Buffer<int> &buffer);
int length() const;
};
/*
============================================================
============================ Node ==========================
============================================================
*/
class Node {
private:
Node_internal *m_node;
public:
Node();
Node( Node_internal *a_node );
Node( Node const &a_node );
~Node();
inline Attribute attribute(const char* a_name) const{
return Attribute(m_node, a_name);
}
inline std::string attribute_as_string(const char* a_name) const{
if(m_node == nullptr){
return "";
}
return m_node->attribute(a_name);
}
inline int attribute_as_int(const char* a_name) const{
if(m_node == nullptr){
return 0;
}
return m_node->attribute_as_int(a_name);
}
inline long attribute_as_long(const char* a_name) const{
if(m_node == nullptr){
return 0;
}
return m_node->attribute_as_long(a_name);
}
inline double attribute_as_double(const char* a_name) const{
if(m_node == nullptr){
return 0.0;
}
return m_node->attribute_as_double(a_name);
}
Node child(const char* name) const;
Node first_child() const;
Node next_sibling() const;
void to_next_sibling() const;
Node &operator=(const Node &other);
std::string name() const;
bool empty() const;
Text text() const;
Data data() const;
};
/*
============================================================
======================= File (base class) ==================
============================================================
*/
class File {
public:
File() { };
virtual ~File() = 0;
virtual Node child(const char* name) = 0;
virtual Node first_child() = 0;
virtual std::string name() const = 0;
};
/*
============================================================
=============== Data Manager (for hybrid files) ============
============================================================
*/
class DataManager {
public:
DataManager() {};
virtual ~DataManager() {};
static DataManager* m_instance;
public:
virtual void getDoubles(nf_Buffer<double> &result, size_t startIndex, size_t endIndex) = 0;
virtual void getInts(nf_Buffer<int> &result, size_t startIndex, size_t endIndex) = 0;
};
#ifdef HAPI_USE_PUGIXML
/*
============================================================
===================== XML using Pugi =======================
============================================================
*/
class PugiXMLNode : public Node_internal {
private:
pugi::xml_node m_node;
public:
PugiXMLNode();
PugiXMLNode(pugi::xml_node a_node);
PugiXMLNode(const PugiXMLNode &other);
virtual ~PugiXMLNode();
std::string attribute(const char* name);
int attribute_as_int(const char* name);
long attribute_as_long(const char* name);
double attribute_as_double(const char* name);
Node_internal *child(char const *name);
Node_internal *first_child();
Node_internal *next_sibling();
void to_next_sibling();
Node_internal *copy();
Node_internal &operator=(const PugiXMLNode &other);
std::string name() const;
bool empty() const;
Text text() const;
Data_internal *data() const;
};
class PugiXMLData : public Data_internal {
private:
pugi::xml_node m_node;
int m_length;
public:
PugiXMLData();
PugiXMLData(pugi::xml_node a_node);
virtual ~PugiXMLData();
void getDoubles(nf_Buffer<double> &buffer);
void getInts(nf_Buffer<int> &buffer);
int length() const;
};
class PugiXMLFile : public File {
private:
std::string m_name;
pugi::xml_document m_doc;
public:
PugiXMLFile();
PugiXMLFile(char const *filename, std::string const &a_callingFunctionName);
virtual ~PugiXMLFile();
Node child(char const *name);
Node first_child();
std::string name() const;
};
#endif
#ifdef HAPI_USE_HDF5
/*
============================================================
=========================== HDF ============================
============================================================
*/
typedef struct {
std::string name;
std::string xmlName; // HDF sometimes mangles names, need original name here
size_t index;
hid_t node_id;
} childInfo;
class HDFNode : public Node_internal {
private:
hid_t m_node_id;
hid_t m_parent_id;
size_t m_index;
std::vector<childInfo> m_siblings;
std::vector<childInfo> m_children;
public:
HDFNode();
HDFNode(hid_t a_node_id, hid_t a_parent_id, size_t a_index, std::vector<childInfo> a_siblings);
explicit HDFNode(hid_t a_file_id);
HDFNode(const HDFNode &other);
virtual ~HDFNode();
//Attribute attribute(char const *name);
std::string attribute(const char* name);
int attribute_as_int(const char* name);
long attribute_as_long(const char* name);
double attribute_as_double(const char* name);
Node_internal *child(char const *name);
Node_internal *first_child();
Node_internal *next_sibling();
void to_next_sibling();
Node_internal *copy();
Node_internal &operator=(const HDFNode &other);
std::string name() const;
bool empty() const;
Text text() const;
Data_internal *data() const;
};
class HDFData : public Data_internal {
private:
hid_t m_node_id;
hid_t m_dataspace_id;
int m_length;
public:
HDFData();
explicit HDFData(hid_t node_id);
virtual ~HDFData();
void getDoubles(nf_Buffer<double> &buffer);
void getInts(nf_Buffer<int> &buffer);
int length() const;
};
class HDFFile : public File {
private:
std::string m_name;
hid_t m_doc;
HDFNode *m_doc_as_node;
public:
HDFFile();
explicit HDFFile(char const *filename);
virtual ~HDFFile();
Node child(char const *name);
Node first_child();
std::string name() const;
};
class HDFDataManager : public DataManager{
private:
std::string m_filename;
bool m_iDataPresent;
bool m_dDataPresent;
hid_t m_file_id;
hid_t m_dataset_ints, m_dataset_doubles;
hid_t m_dataspace_ints, m_dataspace_doubles;
hsize_t m_stride[1], m_block[1];
size_t m_num_double_reads;
size_t m_num_double_elem;
size_t m_num_int_reads;
size_t m_num_int_elem;
public:
HDFDataManager(std::string const &filename);
virtual ~HDFDataManager();
virtual void getDoubles(nf_Buffer<double> &result, size_t startIndex, size_t endIndex);
virtual void getInts(nf_Buffer<int> &result, size_t startIndex, size_t endIndex);
};
#endif
} // end of namespace 'HAPI'
#endif // End of HAPI_hpp_included
@@ -0,0 +1,446 @@
/*
# <<BEGIN-copyright>>
# Copyright 2019, Lawrence Livermore National Security, LLC.
# This file is part of the gidiplus package (https://github.com/LLNL/gidiplus).
# gidiplus is licensed under the MIT license (see https://opensource.org/licenses/MIT).
# SPDX-License-Identifier: MIT
# <<END-copyright>>
*/
#ifndef LUPI_hpp_included
#define LUPI_hpp_included 1
#include <sys/stat.h>
#include <string>
#include <vector>
#include <list>
#include <map>
#include <stdexcept>
#include <iostream>
#ifndef _WIN32
#include <time.h>
#include <sys/time.h>
#endif
#include <LUPI_defines.hpp>
#include <statusMessageReporting.h>
#define LUPI_XML_verionEncoding "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
#ifndef LUPI_PATH_MAX
#define LUPI_PATH_MAX ( 4 * 4096 )
#endif
#if defined (GIDIP_HAVE_COMPILER_FLOATING_POINT_EXCEPTIONS)
void LUPI_FPE_enable( char const *a_file, int a_line );
void LUPI_FPE_disable_and_clear( char const *a_file, int a_line );
void LUPI_FPE_test( char const *a_file, int a_line );
#endif
namespace LUPI {
#ifdef _WIN32
#define LUPI_FILE_SEPARATOR "\\"
#else
#define LUPI_FILE_SEPARATOR "/"
#endif
#define GNDS_formatVersion_1_10Chars "1.10"
#define GNDS_formatVersion_2_0Chars "2.0"
#define GNDS_formatVersion_2_0_LLNL_4Chars "2.0.LLNL_4"
void deprecatedFunction( std::string const &a_functionName, std::string const &a_replacementName, std::string const &a_asOf );
/*
============================================================
====================== FormatVersion =======================
============================================================
*/
class FormatVersion {
private:
std::string m_format; /**< The GNDS format version. */
int m_major; /**< The GNDS format major value as an integer. */
int m_minor; /**< The GNDS format minor value as an integer. */
std::string m_patch; /**< The GNDS format patch string. This will be an empty string except for unofficial formats. */
public:
FormatVersion( );
FormatVersion( std::string const &a_formatVersion );
FormatVersion( FormatVersion const &a_formatVersion );
FormatVersion &operator=( FormatVersion const &a_rhs );
std::string const &format( ) const { return( m_format ); }
int major( ) const { return( m_major ); }
int minor( ) const { return( m_minor ); }
std::string const &patch( ) const { return( m_patch ); }
bool setFormat( std::string const &a_formatVersion );
bool supported( ) const ;
};
/*
============================================================
========================= Exception ========================
============================================================
*/
class Exception : public std::runtime_error {
public :
explicit Exception( std::string const &a_message );
};
/*
============================================================
================== StatusMessageReporting ==================
============================================================
*/
class StatusMessageReporting {
public:
enum class Status { ok, info, warning, error };
private:
statusMessageReporting m_smr;
public:
StatusMessageReporting( );
~StatusMessageReporting( );
statusMessageReporting *smr( ) { return( &m_smr ); }
bool isOk( ) { return( smr_isOk( &m_smr ) ); }
bool isInfo( ) { return( smr_isInfo( &m_smr ) ); }
bool isWarning( ) { return( smr_isWarning( &m_smr ) ); }
bool isError( ) { return( smr_isError( &m_smr ) ); }
void clear( ) { smr_release( &m_smr ); }
std::string constructMessage( std::string a_prefix, int a_reports = 1, bool a_clear = false );
std::string constructFullMessage( std::string a_prefix, int a_reports = 1, bool a_clear = false );
};
/*
============================================================
====================== ArgumentParser ======================
============================================================
*/
enum class ArgumentType { True, False, Count, Store, Append, Positional };
class ArgumentBase;
class ArgumentParser {
private:
std::string m_codeName; /**< The name of the code that is using **ArgumentParser**. */
std::string m_descriptor; /**< The descriptor that is printed when help (i.e., '-h') is entered. */
std::vector<ArgumentBase *> m_arguments; /**< The list of arguments (positional and optional) supported. */
void add2( ArgumentBase *a_argumentBase );
public:
ArgumentParser( std::string const &a_codeName, std::string const &a_descriptor = "" );
~ArgumentParser( );
std::string const &codeName( ) const { return( m_codeName ); }
std::string const &descriptor( ) const { return( m_descriptor ); }
template<typename T> T *add( std::string const &a_name, std::string const &a_descriptor, int a_minimumNeeded = 1, int a_maximumNeeded = 1 );
ArgumentBase *add( ArgumentType a_argumentType, std::string const &a_name, std::string const &a_descriptor,
int a_minimumNeeded = -2, int a_maximumNeeded = -2 );
void addAlias( std::string const &a_name, std::string const &a_alias );
void addAlias( ArgumentBase const * const a_argumentBase, std::string const &a_alias );
bool hasName( std::string const &a_name ) const ;
bool isOptionalArgument( std::string const &a_name ) const ;
void parse( int a_argc, char **a_argv, bool a_printArguments = true );
template<typename T> T *get( std::size_t a_name );
void help( ) const ;
void usage( ) const ;
virtual void printStatus( std::string a_indent ) const ;
};
/* *********************************************************************************************************//**
* Creates a new argument, adds the argument to *this* and returns a pointer the the newly created argument.
*
* @param a_name [in] The name of the argument.
* @param a_descriptor [in] The argument's description, displayed when the help option is enetered.
* @param a_minimumNeeded [in] The minimum number of required time *this* argument must be entered.
* @param a_maximumNeeded [in] The maximum number of required time *this* argument must be entered.
*
* @return A pointer to the created argument.
***********************************************************************************************************/
template<typename T> T *ArgumentParser::add( std::string const &a_name, std::string const &a_descriptor, int a_minimumNeeded, int a_maximumNeeded ) {
T *argument = new T( a_name, a_descriptor, a_minimumNeeded, a_maximumNeeded );
add2( argument );
return( argument );
}
/*
============================================================
======================= ArgumentBase =======================
============================================================
*/
class ArgumentBase {
private:
ArgumentType m_argumentType; /**< The enum for arguent type of *this*. */
std::vector<std::string> m_names; /**< The allowed names for *this*. */
std::string m_descriptor; /**< The desciption printed help. */
int m_minimumNeeded; /**< Minimum number of times *this* argument is required on the command line. */
int m_maximumNeeded; /**< Maximum number of times *this* argument is required on the command line. */
int m_counts; /**< The number of time this argument was entered on the command line. */
std::vector<std::string> m_values; /**< list of values entered for this argument. Only used for types Store, Append and Positional. */
void addAlias( std::string const &a_name ); /**< Adds the alias *a_name* to *this*. */
virtual std::string printStatus2( ) const ; /**< For internal use. Called by method **printStatus**. */
virtual void printStatus3( std::string const &a_indent ) const ;
friend void ArgumentParser::addAlias( std::string const &a_name, std::string const &a_alias );
public:
ArgumentBase( ArgumentType a_argumentType, std::string const &a_name, std::string const &a_descriptor, int a_minimumNeeded, int a_maximumNeeded );
virtual ~ArgumentBase( ) = 0 ;
ArgumentType argumentType( ) const { return( m_argumentType ); }
std::string const &name( ) const { return( m_names[0] ); }
std::vector<std::string> const &names( ) { return( m_names ); }
bool hasName( std::string const &a_name ) const ;
std::string const &descriptor( ) const { return( m_descriptor ); }
int minimumNeeded( ) const { return( m_minimumNeeded ); }
int maximumNeeded( ) const { return( m_maximumNeeded ); }
int counts( ) const { return( m_counts ); }
virtual std::string const &value( std::size_t a_index = 0 ) const ;
std::vector<std::string> const &values( ) const { return( m_values ); }
virtual bool isOptionalArgument( ) const { return( true ); }
virtual bool requiresAValue( ) const { return( false ); }
virtual int parse( ArgumentParser const &a_argumentParser, int a_index, int a_argc, char **a_argv );
std::string usage( bool a_requiredOption ) const ;
void printStatus( std::string a_indent ) const ;
};
/*
============================================================
======================= OptionBoolean ======================
============================================================
*/
class OptionBoolean : public ArgumentBase {
private:
bool m_default;
public:
OptionBoolean( ArgumentType a_argumentType, std::string const &a_name, std::string const &a_descriptor, bool a_default );
virtual ~OptionBoolean( ) = 0 ;
bool _default( ) const { return( m_default ); }
std::string printStatus2( ) const ;
};
/*
============================================================
======================== OptionTrue ========================
============================================================
*/
class OptionTrue : public OptionBoolean {
public:
OptionTrue( std::string const &a_name, std::string const &a_descriptor = "", int a_minimumNeeded = 0, int a_maximumNeeded = -1 );
~OptionTrue( ) { }
};
/*
============================================================
======================= OptionFalse ========================
============================================================
*/
class OptionFalse : public OptionBoolean {
public:
OptionFalse( std::string const &a_name, std::string const &a_descriptor = "", int a_minimumNeeded = 0, int a_maximumNeeded = -1 );
~OptionFalse( ) { }
};
/*
============================================================
====================== OptionCounter =======================
============================================================
*/
class OptionCounter : public ArgumentBase {
public:
OptionCounter( std::string const &a_name, std::string const &a_descriptor = "", int a_minimumNeeded = 0, int a_maximumNeeded = -1 );
~OptionCounter( ) { }
std::string printStatus2( ) const ;
};
/*
============================================================
======================= OptionStore ========================
============================================================
*/
class OptionStore : public ArgumentBase {
public:
OptionStore( std::string const &a_name, std::string const &a_descriptor = "", int a_minimumNeeded = 0, int a_maximumNeeded = -1 );
~OptionStore( ) { }
std::string const &value( std::size_t a_index = 0 ) const ;
bool requiresAValue( ) const { return( true ); }
void printStatus3( std::string const &a_indent ) const ;
};
/*
============================================================
======================= OptionAppend =======================
============================================================
*/
class OptionAppend : public ArgumentBase {
public:
OptionAppend( std::string const &a_name, std::string const &a_descriptor = "", int a_minimumNeeded = 0, int a_maximumNeeded = -1 );
~OptionAppend( ) { }
bool requiresAValue( ) const { return( true ); }
void printStatus3( std::string const &a_indent ) const ;
};
/*
============================================================
======================== Positional ========================
============================================================
*/
class Positional : public ArgumentBase {
public:
Positional( std::string const &a_name, std::string const &a_descriptor = "", int a_minimumNeeded = 1, int a_maximumNeeded = 1 );
~Positional( ) { }
bool isOptionalArgument( ) const { return( false ); }
bool requiresAValue( ) const { return( true ); }
void printStatus3( std::string const &a_indent ) const ;
};
/*
============================================================
======================== DeltaTime =========================
============================================================
*/
#ifndef _WIN32
#define LUPI_DeltaTime_toStringFormatIncremental "incremental: CPU %8.3fs, wall %8.3fs"
#define LUPI_DeltaTime_toStringFormatTotal "total: CPU %8.3fs, wall %8.3fs"
class DeltaTime {
private:
double m_CPU_time;
double m_wallTime;
double m_CPU_timeIncremental;
double m_wallTimeIncremental;
public:
DeltaTime( );
DeltaTime( double a_CPU_time, double a_wallTime, double a_CPU_timeIncremental, double a_wallTimeIncremental );
DeltaTime( DeltaTime const &deltaTime );
~DeltaTime( ) { }
double CPU_time( ) const { return( m_CPU_time ); }
double wallTime( ) const { return( m_wallTime ); }
double CPU_timeIncremental( ) const { return( m_CPU_timeIncremental ); }
double wallTimeIncremental( ) const { return( m_wallTimeIncremental ); }
std::string toString( std::string a_formatIncremental = LUPI_DeltaTime_toStringFormatIncremental,
std::string a_format = LUPI_DeltaTime_toStringFormatTotal, std::string a_sep = "; " );
};
/*
============================================================
========================== Timer ===========================
============================================================
*/
class Timer {
private:
clock_t m_CPU_time;
struct timeval m_wallTime;
clock_t m_CPU_timeIncremental;
struct timeval m_wallTimeIncremental;
public:
Timer( );
~Timer( ) { }
DeltaTime deltaTime( );
DeltaTime deltaTimeAndReset( );
void reset( );
};
#endif // End of not _WIN32 defined.
namespace FileInfo { // Should be using std::filesystem stuff but this requires C++ 17.
std::string realPath( std::string const &a_path );
std::string _basename( std::string const &a_path );
std::string basenameWithoutExtension( std::string const &a_path );
std::string _dirname( std::string const &a_path );
bool exists( std::string const &a_path );
bool isDirectory( std::string const &a_path );
bool createDirectories( std::string const &a_path );
/*
============================================================
========================= FileStat =========================
============================================================
*/
class FileStat {
private:
std::string m_path; /**< The path that is stat-ed. */
struct stat m_stat; /**< The stat for the path. */
public:
FileStat( std::string const &a_path );
std::string const &path( ) const { return( m_path ); } /**< Returns a reference to the **m_path** member. */
struct stat const &statRef( ) const { return( m_stat ); } /**< Returns a reference to the **m_stat** member. */
bool exists( );
bool isDirectory( ) const { return( ( m_stat.st_mode & S_IFMT ) == S_IFDIR ); } /**< Returns *true* if the path is a directory and *false* otherwise. */
bool isRegularFile( ) const { return( ( m_stat.st_mode & S_IFMT ) == S_IFREG ); } /**< Returns *true* if the path is a regular file and *false* otherwise. */
};
} // End of namespace FileInfo.
// Miscellaneous functions
namespace Misc {
std::string stripString( std::string const &a_string, bool a_left = true, bool a_right = true );
std::vector<std::string> splitString( std::string const &a_string, char a_delimiter, bool a_strip = false );
std::vector<std::string> splitString( std::string const &a_string, std::string const &a_delimiter, bool a_strip = false );
std::vector<std::string> splitXLinkString( std::string const &a_string );
bool stringToInt( std::string const &a_string, int &a_value );
std::string argumentsToString( char const *a_format, ... );
std::string doubleToString3( char const *a_format, double a_value, bool a_reduceBits = false );
std::string doubleToShortestString( double a_value, int a_significantDigits = 15, int a_favorEFormBy = 0 );
void printCommand( std::string const &a_indent, int a_argc, char **a_argv );
} // End of namespace Misc.
} // End of namespace LUPI.
#endif // LUPI_hpp_included
@@ -0,0 +1,462 @@
/*
# <<BEGIN-copyright>>
# Copyright 2019, Lawrence Livermore National Security, LLC.
# This file is part of the gidiplus package (https://github.com/LLNL/gidiplus).
# gidiplus is licensed under the MIT license (see https://opensource.org/licenses/MIT).
# SPDX-License-Identifier: MIT
# <<END-copyright>>
*/
#ifndef LUPI_data_buffer_hpp_included
#define LUPI_data_buffer_hpp_included 1
#include <cstdint>
#include <LUPI_defines.hpp>
#include <LUPI_declareMacro.hpp>
namespace LUPI {
/*
============================================================
========================= DataBuffer =======================
============================================================
*/
class DataBuffer {
public:
std::size_t m_intIndex;
std::size_t m_floatIndex;
std::size_t m_doubleIndex;
std::size_t m_charIndex;
std::size_t m_longIndex;
int *m_intData;
float *m_floatData;
double *m_doubleData;
char *m_charData;
std::uint64_t *m_longData;
// For unpacking into pre-allocated memory
char *m_placementStart;
char *m_placement;
std::size_t m_maxPlacementSize;
// If m_sharedPlacementStart is not a nullPtr, place int and double vector information here
// m_sharedMaxPlacementSize is how much shared memory will be used.
char *m_sharedPlacementStart;
char *m_sharedPlacement;
std::size_t m_sharedMaxPlacementSize;
enum class Mode { Count, Pack, Unpack, Reset, Memory };
LUPI_HOST_DEVICE DataBuffer( void ) :
m_intIndex( 0 ),
m_floatIndex( 0 ),
m_doubleIndex( 0 ),
m_charIndex( 0 ),
m_longIndex( 0 ),
m_intData( nullptr ),
m_floatData( nullptr ),
m_doubleData( nullptr ),
m_charData( nullptr ),
m_longData( nullptr ),
m_placementStart( nullptr ),
m_placement( nullptr ),
m_maxPlacementSize( 0 ),
m_sharedPlacementStart( nullptr ),
m_sharedPlacement( nullptr ),
m_sharedMaxPlacementSize( 0 ) {
}
LUPI_HOST_DEVICE DataBuffer( DataBuffer const &rhs ) :
m_intIndex( 0 ),
m_floatIndex( 0 ),
m_doubleIndex( 0 ),
m_charIndex( 0 ),
m_longIndex( 0 ),
m_intData( nullptr ),
m_floatData( nullptr ),
m_doubleData( nullptr ),
m_charData( nullptr ),
m_longData( nullptr ),
m_placementStart( nullptr ),
m_placement( nullptr ),
m_maxPlacementSize( 0 ),
m_sharedPlacementStart( nullptr ),
m_sharedPlacement( nullptr ),
m_sharedMaxPlacementSize( 0 ) {
if( rhs.m_placementStart == nullptr ) m_placementStart = rhs.m_placementStart; // Only to stop compiler warning of unused variable as cannot get [[maybe_unused]] to work.
}
LUPI_HOST_DEVICE ~DataBuffer( ) {
delete [] m_intData;
delete [] m_floatData;
delete [] m_doubleData;
delete [] m_charData;
delete [] m_longData;
}
LUPI_HOST_DEVICE void zeroIndexes( void ) {
m_intIndex = m_floatIndex = m_doubleIndex = m_charIndex = m_longIndex = 0;
}
LUPI_HOST_DEVICE void copyIndexes( DataBuffer const &a_input ) {
m_intIndex = a_input.m_intIndex;
m_floatIndex = a_input.m_floatIndex;
m_doubleIndex = a_input.m_doubleIndex;
m_charIndex = a_input.m_charIndex;
m_longIndex = a_input.m_longIndex;
}
LUPI_HOST_DEVICE void simpleCopy( DataBuffer const &a_input ) {
m_intIndex = a_input.m_intIndex;
m_floatIndex = a_input.m_floatIndex;
m_doubleIndex = a_input.m_doubleIndex;
m_charIndex = a_input.m_charIndex;
m_longIndex = a_input.m_longIndex;
m_intData = a_input.m_intData;
m_floatData = a_input.m_floatData;
m_doubleData = a_input.m_doubleData;
m_charData = a_input.m_charData;
m_longData = a_input.m_longData;
m_placementStart = a_input.m_placementStart;
m_placement = a_input.m_placement;
m_maxPlacementSize = a_input.m_maxPlacementSize;
m_sharedPlacementStart = a_input.m_sharedPlacementStart;
m_sharedPlacement = a_input.m_sharedPlacement;
m_sharedMaxPlacementSize = a_input.m_sharedMaxPlacementSize;
}
// Useful for temporary buffers that we don't want destroying the data in the destructor
LUPI_HOST_DEVICE void nullOutPointers( void ) {
m_intData = nullptr;
m_floatData = nullptr;
m_doubleData = nullptr;
m_charData = nullptr;
m_longData = nullptr;
}
LUPI_HOST_DEVICE void allocateBuffers( void ) {
m_intData = new int[m_intIndex];
m_floatData = new float[m_floatIndex];
m_doubleData = new double[m_doubleIndex];
m_charData = new char[m_charIndex];
m_longData = new std::uint64_t[m_longIndex];
}
LUPI_HOST_DEVICE void freeMemory( void ) {
delete [] m_intData;
delete [] m_floatData;
delete [] m_doubleData;
delete [] m_charData;
delete [] m_longData;
zeroIndexes( );
nullOutPointers( );
}
LUPI_HOST_DEVICE bool compareIndexes( LUPI_maybeUnused char const *a_file, LUPI_maybeUnused int a_line, DataBuffer const &a_input ) {
return( ( a_input.m_intIndex == m_intIndex ) && ( a_input.m_floatIndex == m_floatIndex ) &&
( a_input.m_doubleIndex == m_doubleIndex ) &&
( a_input.m_charIndex == m_charIndex ) && ( a_input.m_longIndex == m_longIndex ) );
}
LUPI_HOST_DEVICE void incrementPlacement(std::size_t a_delta) {
std::size_t sub = a_delta % 8;
if (sub != 0) a_delta += (8-sub);
m_placement += a_delta;
}
LUPI_HOST_DEVICE void incrementSharedPlacement(std::size_t a_delta) {
std::size_t sub = a_delta % 8;
if (sub != 0) a_delta += (8-sub);
m_sharedPlacement += a_delta;
}
// Returns true if data buffer has not gone over any memory limits
LUPI_HOST_DEVICE bool validate() {
if (m_placementStart == 0 && m_sharedPlacementStart == 0) return true;
if (m_placement > m_maxPlacementSize + m_placementStart) return false;
if (m_sharedPlacement > m_sharedMaxPlacementSize + m_sharedPlacementStart) return false;
return true;
}
#if defined(__CUDACC__) || defined (__HIP__)
#ifdef __CUDACC__
#define LUPI_GPU_MALLOC cudaMalloc
#define LUPI_GPU_MEMCPY cudaMemcpy
#define LUPI_GPU_HTOD cudaMemcpyHostToDevice
#else
#define LUPI_GPU_MALLOC hipMalloc
#define LUPI_GPU_MEMCPY hipMemcpy
#define LUPI_GPU_HTOD hipMemcpyHostToDevice
#endif
// Copy this host object to the device and return its pointer
LUPI_HOST DataBuffer *copyToDevice(std::size_t a_cpuSize, char *&a_protarePtr) {
DataBuffer *devicePtr = nullptr;
DataBuffer buf_tmp;
buf_tmp.copyIndexes(*this);
buf_tmp.m_maxPlacementSize = a_cpuSize;
gpuErrorCheck( LUPI_GPU_MALLOC( (void **) &buf_tmp.m_intData, sizeof(int) * m_intIndex) );
gpuErrorCheck( LUPI_GPU_MEMCPY( buf_tmp.m_intData, m_intData, sizeof(int) * m_intIndex, LUPI_GPU_HTOD ) );
gpuErrorCheck( LUPI_GPU_MALLOC( (void **) &buf_tmp.m_floatData, sizeof(float) * m_floatIndex ) );
gpuErrorCheck( LUPI_GPU_MEMCPY( buf_tmp.m_floatData, m_floatData, sizeof(float) * m_floatIndex, LUPI_GPU_HTOD ) );
gpuErrorCheck( LUPI_GPU_MALLOC( (void **) &buf_tmp.m_doubleData, sizeof(double) * m_doubleIndex ) );
gpuErrorCheck( LUPI_GPU_MEMCPY( buf_tmp.m_doubleData, m_doubleData, sizeof(double) * m_doubleIndex, LUPI_GPU_HTOD ) );
gpuErrorCheck( LUPI_GPU_MALLOC( (void **) &buf_tmp.m_charData, sizeof(char) * m_charIndex ) );
gpuErrorCheck( LUPI_GPU_MEMCPY( buf_tmp.m_charData, m_charData, sizeof(char) * m_charIndex, LUPI_GPU_HTOD ) );
gpuErrorCheck( LUPI_GPU_MALLOC( (void **) &buf_tmp.m_longData, sizeof(std::uint64_t) * m_longIndex ) );
gpuErrorCheck( LUPI_GPU_MEMCPY( buf_tmp.m_longData, m_longData, sizeof(std::uint64_t) * m_longIndex, LUPI_GPU_HTOD ) );
gpuErrorCheck( LUPI_GPU_MALLOC( (void **) &buf_tmp.m_placementStart, buf_tmp.m_maxPlacementSize ) );
// Set to 0 for easier byte comparisons. This may be removed after testing is done
//gpuErrorCheck( cudaMemset( (void *) buf_tmp.m_placementStart, 0, buf_tmp.m_maxPlacementSize ) );
buf_tmp.m_placement = buf_tmp.m_placementStart;
a_protarePtr = buf_tmp.m_placementStart;
gpuErrorCheck( LUPI_GPU_MALLOC( (void **) &devicePtr, sizeof(DataBuffer) ) );
gpuErrorCheck( LUPI_GPU_MEMCPY( devicePtr, &buf_tmp, sizeof(DataBuffer), LUPI_GPU_HTOD ) );
// Don't need destructor trying to free the device memory.
buf_tmp.nullOutPointers( );
return devicePtr;
}
#undef LUPI_GPU_MALLOC
#undef LUPI_GPU_MEMCPY
#undef LUPI_GPU_HTOD
#endif
private:
DataBuffer &operator=( DataBuffer const &tmp ); // disable assignment operator
};
} // End of namespace LUPI.
#define DATA_MEMBER_SIMPLE(member, buffer, index, mode) \
{if ( mode == LUPI::DataBuffer::Mode::Count ) {(index)++; } \
else if ( mode == LUPI::DataBuffer::Mode::Pack ) {(buffer)[ (index)++ ] = (member); } \
else if ( mode == LUPI::DataBuffer::Mode::Unpack ) {member = (buffer)[ (index)++ ]; } \
else if ( mode == LUPI::DataBuffer::Mode::Reset ) {(index)++; member = 0; }}
#define DATA_MEMBER_CAST(member, buf, mode, someType) \
{if ( mode == LUPI::DataBuffer::Mode::Count ) {((buf).m_intIndex)++; } \
else if ( mode == LUPI::DataBuffer::Mode::Pack ) {(buf).m_intData[ ((buf).m_intIndex)++ ] = (int)(member); } \
else if ( mode == LUPI::DataBuffer::Mode::Unpack ) {member = (someType) (buf).m_intData[ ((buf).m_intIndex)++ ]; } \
else if ( mode == LUPI::DataBuffer::Mode::Reset ) {((buf).m_intIndex)++; member = (someType) 0; }}
#define DATA_MEMBER_CHAR( member, buf, mode) DATA_MEMBER_SIMPLE(member, (buf).m_charData, (buf).m_charIndex, mode)
#define DATA_MEMBER_INT( member, buf, mode) DATA_MEMBER_SIMPLE(member, (buf).m_intData, (buf).m_intIndex, mode)
#define DATA_MEMBER_FLOAT(member, buf, mode) DATA_MEMBER_SIMPLE(member, (buf).m_floatData, (buf).m_floatIndex, mode)
#define DATA_MEMBER_DOUBLE(member, buf, mode) DATA_MEMBER_SIMPLE(member, (buf).m_doubleData, (buf).m_doubleIndex, mode)
#define DATA_MEMBER_STRING(member, buf, mode) \
{if ( mode == LUPI::DataBuffer::Mode::Count ) {((buf).m_charIndex) += member.size(); ((buf).m_intIndex)++; } \
else if ( mode == LUPI::DataBuffer::Mode::Pack ) {std::size_t array_size = member.size(); \
(buf).m_intData[((buf).m_intIndex)++] = array_size; \
for (std::size_t size_index = 0; size_index < array_size; size_index++)\
{(buf).m_charData[ ((buf).m_charIndex)++ ] = (member[size_index]); }} \
else if ( mode == LUPI::DataBuffer::Mode::Unpack ) {std::size_t array_size = (buf).m_intData[((buf).m_intIndex)++]; \
member.resize(array_size, &(buf).m_placement); \
for (std::size_t size_index = 0; size_index < array_size; size_index++) \
{member[size_index] = (buf).m_charData[ ((buf).m_charIndex)++ ]; }} \
else if ( mode == LUPI::DataBuffer::Mode::Reset ) {std::size_t array_size = member.size(); \
for (std::size_t size_index = 0; size_index < array_size; size_index++) \
{((buf).m_charIndex)++; member[size_index] = '\0'; }} \
else if ( mode == LUPI::DataBuffer::Mode::Memory ) { (buf).incrementPlacement(sizeof(char) * (member.size()+1)); } }
#define DATA_MEMBER_STD_STRING(member, buf, mode) { \
if ( mode == LUPI::DataBuffer::Mode::Count ) \
{((buf).m_charIndex) += member.size(); ((buf).m_intIndex)++; } \
else if ( mode == LUPI::DataBuffer::Mode::Pack ) {std::size_t array_size = member.size(); \
(buf).m_intData[((buf).m_intIndex)++] = array_size; \
for (std::size_t size_index = 0; size_index < array_size; size_index++)\
{(buf).m_charData[((buf).m_charIndex)++] = (member[size_index]); }} \
else if ( mode == LUPI::DataBuffer::Mode::Unpack ) {std::size_t array_size = (buf).m_intData[((buf).m_intIndex)++]; \
member.resize(array_size); \
for (std::size_t size_index = 0; size_index < array_size; size_index++) \
{member[size_index] = (buf).m_charData[ ((buf).m_charIndex)++ ]; }} }
#if LUPI_WARP_SIZE > 1 && defined(LUPI_ON_GPU)
#define DATA_MEMBER_VECTOR_FLOAT(member, buf, mode) \
{ \
std::size_t vector_size = member.size(); \
DATA_MEMBER_INT(vector_size, (buf), mode); \
if ( mode == LUPI::DataBuffer::Mode::Unpack ) member.resize(vector_size, &(buf).m_placement); \
std::size_t bufferIndex = (buf).m_floatIndex; \
for ( std::size_t member_index = 0; member_index < vector_size; member_index += LUPI_WARP_SIZE, bufferIndex += LUPI_WARP_SIZE ) \
{ \
std::size_t thrMemberId = member_index + LUPI_THREADID; \
if (thrMemberId >= vector_size) continue; \
member[thrMemberId] = (buf).m_floatData[bufferIndex + LUPI_THREADID]; \
} \
(buf).m_floatIndex += vector_size; \
}
#define DATA_MEMBER_VECTOR_DOUBLE(member, buf, mode) \
{ \
std::size_t vector_size = member.size(); \
DATA_MEMBER_INT(vector_size, (buf), mode); \
if ( mode == LUPI::DataBuffer::Mode::Unpack ) member.resize(vector_size, &(buf).m_placement); \
std::size_t bufferIndex = (buf).m_doubleIndex; \
for ( std::size_t member_index = 0; member_index < vector_size; member_index += LUPI_WARP_SIZE, bufferIndex += LUPI_WARP_SIZE ) \
{ \
std::size_t thrMemberId = member_index + LUPI_THREADID; \
if (thrMemberId >= vector_size) continue; \
member[thrMemberId] = (buf).m_doubleData[bufferIndex + LUPI_THREADID]; \
} \
(buf).m_doubleIndex += vector_size; \
}
#else
#define DATA_MEMBER_VECTOR_FLOAT(member, buf, mode) \
{ \
std::size_t vector_size = member.size(); \
DATA_MEMBER_INT(vector_size, (buf), mode); \
if ( mode == LUPI::DataBuffer::Mode::Unpack ) { \
if ((buf).m_sharedPlacement == nullptr) { \
member.resize(vector_size, &(buf).m_placement); \
} else { \
member.resize(vector_size, &(buf).m_sharedPlacement); \
} \
}\
if ( mode == LUPI::DataBuffer::Mode::Memory ) { \
(buf).incrementSharedPlacement(sizeof(float) * member.capacity()); \
} \
for ( std::size_t member_index = 0; member_index < vector_size; member_index++ ) \
{ \
DATA_MEMBER_FLOAT(member[member_index], (buf), mode); \
} \
}
#define DATA_MEMBER_VECTOR_DOUBLE(member, buf, mode) \
{ \
std::size_t vector_size = member.size(); \
DATA_MEMBER_INT(vector_size, (buf), mode); \
if ( mode == LUPI::DataBuffer::Mode::Unpack ) { \
if ((buf).m_sharedPlacement == nullptr) { \
member.resize(vector_size, &(buf).m_placement); \
} else { \
member.resize(vector_size, &(buf).m_sharedPlacement); \
} \
}\
if ( mode == LUPI::DataBuffer::Mode::Memory ) { \
(buf).incrementSharedPlacement(sizeof(double) * member.capacity()); \
} \
for ( std::size_t member_index = 0; member_index < vector_size; member_index++ ) \
{ \
DATA_MEMBER_DOUBLE(member[member_index], (buf), mode); \
} \
}
#endif
#if LUPI_WARP_SIZE > 1 && defined(LUPI_ON_GPU)
#define DATA_MEMBER_VECTOR_INT(member, buf, mode) \
{ \
std::size_t vector_size = member.size(); \
DATA_MEMBER_INT(vector_size, (buf), mode); \
if ( mode == LUPI::DataBuffer::Mode::Unpack ) member.resize(vector_size, &(buf).m_placement); \
std::size_t bufferIndex = (buf).m_intIndex; \
for ( std::size_t member_index = 0; member_index < vector_size; member_index += LUPI_WARP_SIZE, bufferIndex += LUPI_WARP_SIZE ) \
{ \
std::size_t thrMemberId = member_index + LUPI_THREADID; \
if (thrMemberId >= vector_size) continue; \
member[thrMemberId] = (buf).m_intData[bufferIndex + LUPI_THREADID]; \
} \
(buf).m_intIndex += vector_size; \
}
#else
#define DATA_MEMBER_VECTOR_INT(member, buf, mode) \
{ \
std::size_t vector_size = member.size(); \
DATA_MEMBER_INT(vector_size, (buf), mode); \
if ( mode == LUPI::DataBuffer::Mode::Unpack ) { \
if ((buf).m_sharedPlacement == nullptr) { \
member.resize(vector_size, &(buf).m_placement); \
} else { \
member.resize(vector_size, &(buf).m_sharedPlacement); \
} \
}\
if ( mode == LUPI::DataBuffer::Mode::Memory ) { \
(buf).incrementSharedPlacement(sizeof(int) * member.capacity()); \
} \
for ( std::size_t member_index = 0; member_index < vector_size; member_index++ ) \
{ \
DATA_MEMBER_INT(member[member_index], (buf), mode); \
} \
}
#endif
#if LUPI_WARP_SIZE > 1 && defined(LUPI_ON_GPU)
#define DATA_MEMBER_VECTOR_BOOL(member, buf, mode) \
{ \
std::size_t vector_size = member.size(); \
DATA_MEMBER_INT(vector_size, (buf), mode); \
if ( mode == LUPI::DataBuffer::Mode::Unpack ) member.resize(vector_size, &(buf).m_placement); \
std::size_t bufferIndex = (buf).m_intIndex; \
for ( std::size_t member_index = 0; member_index < vector_size; member_index += LUPI_WARP_SIZE, bufferIndex += LUPI_WARP_SIZE ) \
{ \
std::size_t thrMemberId = member_index + LUPI_THREADID; \
if (thrMemberId >= vector_size) continue; \
member[thrMemberId] = (buf).m_intData[bufferIndex + LUPI_THREADID]; \
} \
(buf).m_intIndex += vector_size; \
}
#else
#define DATA_MEMBER_VECTOR_BOOL(member, buf, mode) \
{ \
std::size_t vector_size = member.size(); \
DATA_MEMBER_INT(vector_size, (buf), mode); \
if ( mode == LUPI::DataBuffer::Mode::Unpack ) { \
if ((buf).m_sharedPlacement == nullptr) { \
member.resize(vector_size, &(buf).m_placement); \
} else { \
member.resize(vector_size, &(buf).m_sharedPlacement); \
} \
}\
if ( mode == LUPI::DataBuffer::Mode::Memory ) { \
(buf).incrementSharedPlacement(sizeof(int) * member.capacity()); \
} \
for ( std::size_t member_index = 0; member_index < vector_size; member_index++ ) \
{ \
DATA_MEMBER_CAST(member[member_index], (buf), mode, bool); \
} \
}
#endif
#if LUPI_WARP_SIZE > 1 && defined(LUPI_ON_GPU)
#define DATA_MEMBER_CHAR_ARRAY( member, buf, mode ) { \
std::size_t array_size = sizeof( member ); \
std::size_t bufferIndex = (buf).m_charIndex; \
for ( std::size_t member_index = 0; member_index < array_size; member_index += LUPI_WARP_SIZE, bufferIndex += LUPI_WARP_SIZE ) { \
std::size_t thrMemberId = member_index + LUPI_THREADID; \
if( thrMemberId >= array_size ) continue; \
member[thrMemberId] = (buf).m_charData[bufferIndex + LUPI_THREADID]; \
} \
(buf).m_charIndex += array_size; \
}
#else
#define DATA_MEMBER_CHAR_ARRAY( member, buf, mode ) { \
std::size_t array_size = sizeof( member ); \
for ( std::size_t member_index = 0; member_index < array_size; member_index++ ) DATA_MEMBER_CHAR( member[member_index], (buf), mode ); \
}
#endif
#endif // End of LUPI_data_buffer_hpp_included
@@ -0,0 +1,90 @@
/*
# <<BEGIN-copyright>>
# Copyright 2019, Lawrence Livermore National Security, LLC.
# This file is part of the gidiplus package (https://github.com/LLNL/gidiplus).
# gidiplus is licensed under the MIT license (see https://opensource.org/licenses/MIT).
# SPDX-License-Identifier: MIT
# <<END-copyright>>
*/
#ifndef LUPI_declare_macro_hpp_included
#define LUPI_declare_macro_hpp_included
#include <LUPI_defines.hpp>
// Default, if LUPI_HIP_INLINE is not defined, is to use an attribute function
// to inform HIP not to inline the function.
// This is quite useful for the publicly installed header files for code robustness
// However, when compiling the source, one should be able to disable
// this within the library itself for faster code. To do so
// the define -DLUPI_HIP_INLINE can be added to the compiler flags, and
// the define will evaluate to nothing, so the compiler is welcome to do
// its optimizations.
#ifdef LUPI_HIP_INLINE
#define LUPI_HIP_INLINE_ATTRIBUTE
#else
#define LUPI_HIP_INLINE_ATTRIBUTE __attribute__ ((noinline))
#endif
#define gpuErrorCheck(ans) { gpuAssert((ans), __FILE__, __LINE__); }
#if defined(__HIP_DEVICE_COMPILE__) || defined(__CUDA_ARCH__)
#define LUPI_ON_GPU 1
#endif
#ifdef __CUDACC__
#include <cstdio>
#define LUPI_HOST __host__
#define LUPI_DEVICE __device__
#define LUPI_HOST_DEVICE __host__ __device__
#define LUPI_THROW(arg) printf("%s", arg)
#define LUPI_WARP_SIZE 32
#define LUPI_THREADID threadIdx.x
inline void gpuAssert(cudaError_t code, const char *file, int line, bool abort=true)
{
if (code != cudaSuccess)
{
fprintf(stderr,"GPUASSERT: %s File: %s line: %d\n", cudaGetErrorString(code), file, line);
if (abort) exit(code);
}
}
#elif HAVE_OPENMP_TARGET
#define LUPI_HOST
#define LUPI_DEVICE
#define LUPI_HOST_DEVICE
#define LUPI_THROW(arg) printf("%s", arg)
#define LUPI_WARP_SIZE 1
#define LUPI_THREADID
inline void gpuAssert(int code, const char *file, int line, bool abort=true) {}
#elif defined(__HIP__)
#include <hip/hip_version.h>
#include <hip/hip_runtime.h>
#include <hip/hip_runtime_api.h>
#include <hip/hip_common.h>
#define LUPI_HOST __host__
#define LUPI_DEVICE __device__
#define LUPI_HOST_DEVICE LUPI_HIP_INLINE_ATTRIBUTE __host__ __device__
#define LUPI_THROW(arg)
#define LUPI_WARP_SIZE 1
#define LUPI_THREADID hipThreadIdx_x
inline void gpuAssert(hipError_t code, const char *file, int line, bool do_abort=true)
{
if (code == hipSuccess) { return; }
printf("GPUassert code %d: %s %s %d\n", code, hipGetErrorString(code), file, line);
if (do_abort) { abort(); }
}
#else
#define LUPI_HOST
#define LUPI_DEVICE
#define LUPI_HOST_DEVICE
#define LUPI_THROW(arg) throw arg
#define LUPI_WARP_SIZE 1
#define LUPI_THREADID
inline void gpuAssert(LUPI_maybeUnused int code, LUPI_maybeUnused const char *file, LUPI_maybeUnused int line, LUPI_maybeUnused bool abort=true) {}
#endif
#endif // End of LUPI_declare_macro_hpp_included
@@ -0,0 +1,19 @@
/*
# <<BEGIN-copyright>>
# Copyright 2019, Lawrence Livermore National Security, LLC.
# This file is part of the gidiplus package (https://github.com/LLNL/gidiplus).
# gidiplus is licensed under the MIT license (see https://opensource.org/licenses/MIT).
# SPDX-License-Identifier: MIT
# <<END-copyright>>
*/
#ifndef LUPI_defines_hpp_included
#define LUPI_defines_hpp_included 1
#if __cplusplus > 201402L
#define LUPI_maybeUnused [[maybe_unused]]
#else
#define LUPI_maybeUnused
#endif
#endif // LUPI_defines_hpp_included
@@ -1,780 +0,0 @@
/*
# <<BEGIN-copyright>>
# <<END-copyright>>
*/
#ifndef MCGIDI_h_included
#define MCGIDI_h_included
#define MCGIDI_VERSION_MAJOR 1
#define MCGIDI_VERSION_MINOR 0
#define MCGIDI_VERSION_PATCHLEVEL 0
#include <GIDI_settings.hh>
#include <map>
#include <vector>
#include <statusMessageReporting.h>
#include <ptwXY.h>
#include <xDataTOM.h>
#include "MCGIDI_mass.h"
#include "MCGIDI_map.h"
/* Disable Effective C++ warnings in GIDI code. */
#if __INTEL_COMPILER > 1399
#pragma warning( disable:2021 )
#pragma warning( disable:593 )
#pragma warning( disable:111 )
#elif __INTEL_COMPILER > 1199
#pragma warning( disable:2304 )
#endif
#if defined __cplusplus
extern "C" {
namespace GIDI {
#endif
typedef struct MCGIDI_GammaBranching_s MCGIDI_GammaBranching;
typedef struct MCGIDI_POP_s MCGIDI_POP;
typedef struct MCGIDI_POPs_s MCGIDI_POPs;
typedef struct MCGIDI_particle_s MCGIDI_particle;
typedef struct MCGIDI_target_s MCGIDI_target;
typedef struct MCGIDI_target_heated_info_s MCGIDI_target_heated_info;
typedef struct MCGIDI_target_heated_sorted_s MCGIDI_target_heated_sorted;
typedef struct MCGIDI_target_heated_s MCGIDI_target_heated;
typedef struct MCGIDI_reaction_s MCGIDI_reaction;
typedef struct MCGIDI_outputChannel_s MCGIDI_outputChannel;
typedef struct MCGIDI_product_s MCGIDI_product;
typedef struct MCGIDI_distribution_s MCGIDI_distribution;
typedef struct MCGIDI_KalbachMann_s MCGIDI_KalbachMann;
typedef struct MCGIDI_KalbachMann_ras_s MCGIDI_KalbachMann_ras;
typedef struct MCGIDI_pdfOfX_s MCGIDI_pdfOfX;
typedef struct MCGIDI_pdfsOfXGivenW_s MCGIDI_pdfsOfXGivenW;
typedef struct MCGIDI_pdfsOfXGivenW_sampled_s MCGIDI_pdfsOfXGivenW_sampled;
typedef struct MCGIDI_angular_s MCGIDI_angular;
typedef struct MCGIDI_energyWeightedFunctional_s MCGIDI_energyWeightedFunctional;
typedef struct MCGIDI_energyWeightedFunctionals_s MCGIDI_energyWeightedFunctionals;
typedef struct MCGIDI_energyNBodyPhaseSpace_s MCGIDI_energyNBodyPhaseSpace;
typedef struct MCGIDI_energy_s MCGIDI_energy;
typedef struct MCGIDI_energyAngular_s MCGIDI_energyAngular;
typedef struct MCGIDI_angularEnergy_s MCGIDI_angularEnergy;
typedef struct MCGIDI_decaySamplingInfo_s MCGIDI_decaySamplingInfo;
typedef struct MCGIDI_productsInfo_s MCGIDI_productsInfo;
typedef struct MCGIDI_productInfo_s MCGIDI_productInfo;
typedef struct MCGIDI_sampledProductsData_s MCGIDI_sampledProductsData;
typedef struct MCGIDI_sampledProductsDatas_s MCGIDI_sampledProductsDatas;
#if defined __cplusplus
}
}
#endif
enum MCGIDI_quantityLookupMode {
MCGIDI_quantityLookupMode_pointwise /**< Pointwise data are used to determine a quantity's value an energy E. */,
MCGIDI_quantityLookupMode_grouped /**< Grouped data are used to determine a quantity's value an energy E. */
};
class MCGIDI_quantitiesLookupModes {
private:
int mProjectilesPOPID;
double mProjectileEnergy;
int mGroupIndex;
double mProjectileEnergyForGroupIndex;
double mTemperature;
enum MCGIDI_quantityLookupMode mCrossSectionMode;
enum MCGIDI_quantityLookupMode mMultiplicityMode;
public:
MCGIDI_quantitiesLookupModes( int projectilesPOPID );
~MCGIDI_quantitiesLookupModes( );
inline double getProjectileEnergy( void ) const { return( mProjectileEnergy ); }
void setProjectileEnergy( double e_in ) { mProjectileEnergy = e_in; }
inline int getGroupIndex( void ) const { return( mGroupIndex ); }
int setGroupIndex( GIDI_settings const &settings, bool encloseOutOfRange );
inline double getTemperature( void ) const { return( mTemperature ); }
void setTemperature( double temperature ) { mTemperature = temperature; }
enum MCGIDI_quantityLookupMode getMode( std::string const &quantity ) const;
enum MCGIDI_quantityLookupMode getCrossSectionMode( void ) const { return( mCrossSectionMode ); };
std::vector<std::string> getListOfLookupQuanities( ) const;
void setMode( std::string const &quantity, enum MCGIDI_quantityLookupMode mode );
void setCrossSectionMode( enum MCGIDI_quantityLookupMode mode ) { mCrossSectionMode = mode; };
void setModeAll( enum MCGIDI_quantityLookupMode mode );
};
typedef struct MCGIDI_samplingMultiplicityBias_s MCGIDI_samplingMultiplicityBias;
struct MCGIDI_samplingMultiplicityBias_s {
int PoPID;
double multiplicityFactor;
};
class MCGIDI_samplingMethods {
public:
MCGIDI_samplingMethods( );
~MCGIDI_samplingMethods( );
};
class MCGIDI_samplingSettings {
private: // This is user input.
enum GIDI::xDataTOM_frame mWantFrame;
bool mWantVelocities;
double (*mRng)( void * );
void *mRngState;
std::vector<struct MCGIDI_samplingMultiplicityBias_s> mSamplingMultiplicityBiases;
public: // Temporary variables used in MCGIDI sampling routines.
enum GIDI::xDataTOM_frame mGotFrame;
GIDI::MCGIDI_POP *mPoP;
double mMu;
double mEp;
public:
MCGIDI_samplingSettings( enum GIDI::xDataTOM_frame frame, bool wantVelocities, double (*rng)( void * ), void *rngState );
~MCGIDI_samplingSettings( );
inline double getProductMultiplicityBias( int PoPID ) const {
for( int i1 = 0; i1 < (int) mSamplingMultiplicityBiases.size( ); ++i1 ) {
if( PoPID == mSamplingMultiplicityBiases[i1].PoPID ) return( mSamplingMultiplicityBiases[i1].multiplicityFactor );
}
return( 1. ); }
int setProductMultiplicityBias( GIDI::statusMessageReporting *smr, int PoPID, double fractor );
};
#if defined __cplusplus
extern "C" {
namespace GIDI {
#endif
enum MCGIDI_transportability { /**< This enum is used to give the transportability status for a particle in a reaction or target. */
MCGIDI_transportability_unknown, /**< Particle is not a product of this reaction or target. */
MCGIDI_transportability_none, /**< Particle is a product but has not distribution data. */
MCGIDI_transportability_partial, /**< Particle is a product and has some distribution data. */
MCGIDI_transportability_full }; /**< Particle is a product and all needed distribution data. */
#if defined __cplusplus
}
}
#endif
typedef std::map<int, enum GIDI::MCGIDI_transportability> transportabilitiesMap;
#if defined __cplusplus
extern "C" {
namespace GIDI {
#endif
#define MCGIDI_crossSectionType_grouped 1
#define MCGIDI_crossSectionType_pointwise 2
#define MCGIDI_nullReaction -10001
#define MCGIDI_speedOfLight_cm_sec 2.99792458e10
#define MCGIDI_AMU2MeV 931.494028
enum MCGIDI_reactionType {
MCGIDI_reactionType_unknown_e, /* This should never happen. */
MCGIDI_reactionType_null_e, /* Only occurs when sampling with from grouped cross sections and the projectile is below threshold. */
MCGIDI_reactionType_elastic_e, /* A nuclear elastic reaction. */
MCGIDI_reactionType_scattering_e, /* A nuclear reaction where the projectile and target are products as well as gammas,
excluding reactions that are MCGIDI_reactionType_elastic_e and
MCGIDI_reactionType_nuclearLevelTransition_e. */
MCGIDI_reactionType_nuclearIsomerTransmutation_e, /* A nuclear that changes N or Z and is not one of the others.*/
MCGIDI_reactionType_nuclearLevelTransition_e, /* Reaction in which the residual is the same isotope as the target but in a
different nuclear level. Mainly for meta-stables. */
MCGIDI_reactionType_capture_e, /* A nuclear capture reaction. */
MCGIDI_reactionType_fission_e, /* A nuclear fission reaction. */
MCGIDI_reactionType_sumOfRemainingOutputChannels_e, /* ENDF MT 5 reactions. */
MCGIDI_reactionType_atomic_e
};
enum MCGIDI_channelGenre { MCGIDI_channelGenre_undefined_e, MCGIDI_channelGenre_twoBody_e, MCGIDI_channelGenre_uncorrelated_e,
MCGIDI_channelGenre_sumOfRemaining_e, MCGIDI_channelGenre_twoBodyDecay_e, MCGIDI_channelGenre_uncorrelatedDecay_e };
enum MCGIDI_productMultiplicityType { MCGIDI_productMultiplicityType_invalid_e, MCGIDI_productMultiplicityType_unknown_e, MCGIDI_productMultiplicityType_integer_e,
MCGIDI_productMultiplicityType_energyDependent_e, MCGIDI_productMultiplicityType_gammaBranching_e, MCGIDI_productMultiplicityType_mixed_e };
enum MCGIDI_distributionType { MCGIDI_distributionType_none_e, MCGIDI_distributionType_unknown_e, MCGIDI_distributionType_angular_e,
MCGIDI_distributionType_KalbachMann_e, MCGIDI_distributionType_uncorrelated_e, MCGIDI_distributionType_energyAngular_e,
MCGIDI_distributionType_angularEnergy_e };
enum MCGIDI_angularType { MCGIDI_angularType_isotropic, MCGIDI_angularType_recoil, MCGIDI_angularType_linear };
enum MCGIDI_energyType { MCGIDI_energyType_unknown, MCGIDI_energyType_primaryGamma, MCGIDI_energyType_discreteGamma,
MCGIDI_energyType_linear, MCGIDI_energyType_generalEvaporation, MCGIDI_energyType_simpleMaxwellianFission, MCGIDI_energyType_evaporation,
MCGIDI_energyType_Watt, MCGIDI_energyType_MadlandNix, MCGIDI_energyType_NBodyPhaseSpace, MCGIDI_energyType_weightedFunctional };
extern const char *MCGIDI_productGenre_unknown, *MCGIDI_productGenre_twoBody_angular, *MCGIDI_productGenre_twoBody_formFactor,
*MCGIDI_productGenre_NBody_angular_energy, *MCGIDI_productGenre_NBody_pairProduction;
#define MCGIDI_particleLevel_continuum -1
#define MCGIDI_particleLevel_sum -2
struct MCGIDI_GammaBranching_s {
MCGIDI_POP *finalLevel;
double probability;
};
struct MCGIDI_POP_s {
MCGIDI_POP *next;
MCGIDI_POP *parent;
char *name;
int globalPoPsIndex; /* Index of particle in the PoPs library if particle can be return to packages using */
int Z, A, level, m; /* this library. Otherwise, -1. */
double mass_MeV;
double level_MeV;
int numberOfGammaBranchs;
MCGIDI_GammaBranching *gammas;
};
struct MCGIDI_POPs_s {
int numberOfPOPs, size, increment;
MCGIDI_POP *first, *last, **sorted;
};
struct MCGIDI_particle_s {
MCGIDI_particle *prior;
MCGIDI_particle *next;
int ordinal;
int Z, A, m;
double mass_MeV;
char *name;
};
struct MCGIDI_decaySamplingInfo_s {
enum xDataTOM_frame frame; /* The frame the product data are in. */
int isVelocity; /* See struct MCGIDI_sampledProductsData_s for meaning. This is user input. */
double (*rng)( void * ); /* User supplied rng. */
void *rngState; /* User supplied rng state. */
MCGIDI_POP *pop; /* pop for the sampled product. */
double mu; /* mu = cos( theta ) for the sampled product. Frame is given by frame member. */
double Ep; /* Energy of the product. Frame is given by frame member. */
};
struct MCGIDI_productInfo_s {
int globalPoPsIndex;
enum MCGIDI_productMultiplicityType productMultiplicityType;
int multiplicity;
int transportable;
};
struct MCGIDI_productsInfo_s {
int numberOfProducts;
int numberOfAllocatedProducts;
MCGIDI_productInfo *productInfo;
};
struct MCGIDI_sampledProductsData_s {
int isVelocity; /* If true, px_vx, py_vy and pz_vz are velocities otherwise momenta. */
MCGIDI_POP *pop;
double kineticEnergy;
double px_vx;
double py_vy;
double pz_vz;
int delayedNeutronIndex;
double delayedNeutronRate;
double birthTimeSec; /* Some products, like delayed fission neutrons, are to appear (be born) later. */
};
struct MCGIDI_sampledProductsDatas_s {
int numberOfProducts;
int numberAllocated;
int incrementSize;
MCGIDI_sampledProductsData *products;
};
struct MCGIDI_pdfOfX_s {
int numberOfXs;
double *Xs;
double *pdf;
double *cdf;
};
struct MCGIDI_pdfsOfXGivenW_s {
int numberOfWs;
ptwXY_interpolation interpolationWY, interpolationXY;
double *Ws;
MCGIDI_pdfOfX *dist;
};
struct MCGIDI_pdfsOfXGivenW_sampled_s {
statusMessageReporting *smr;
ptwXY_interpolation interpolationWY, interpolationXY;
int iW, iX1, iX2;
double x, w, frac;
};
struct MCGIDI_angular_s {
enum xDataTOM_frame frame;
enum MCGIDI_angularType type;
MCGIDI_angular *recoilProduct;
MCGIDI_pdfsOfXGivenW dists;
double projectileMass_MeV, targetMass_MeV, productMass_MeV, residualMass_MeV;
};
struct MCGIDI_energyWeightedFunctional_s {
ptwXYPoints *weight;
MCGIDI_energy *energy;
};
struct MCGIDI_energyWeightedFunctionals_s {
int numberOfWeights;
MCGIDI_energyWeightedFunctional weightedFunctional[4]; /* ??????????? Hardwired for no good reason. Will handle up to a (z,4n) reaction. */
};
struct MCGIDI_energyNBodyPhaseSpace_s {
int numberOfProducts;
double mass, massFactor, e_inCOMFactor, Q_MeV;
};
struct MCGIDI_energy_s {
enum xDataTOM_frame frame;
enum MCGIDI_energyType type;
double gammaEnergy_MeV;
double primaryGammaMassFactor;
double e_inCOMFactor;
MCGIDI_pdfsOfXGivenW dists;
double U;
ptwXYPoints *theta, *Watt_a, *Watt_b;
ptwXY_interpolation gInterpolation;
MCGIDI_pdfOfX g;
MCGIDI_energyWeightedFunctionals weightedFunctionals;
MCGIDI_energyNBodyPhaseSpace NBodyPhaseSpace;
};
struct MCGIDI_energyAngular_s {
enum xDataTOM_frame frame;
MCGIDI_pdfsOfXGivenW pdfOfEpGivenE;
MCGIDI_pdfsOfXGivenW *pdfOfMuGivenEAndEp; /* The number of MCGIDI_pdfsOfXGivenW allocated is given by pdfOfEpGivenE.numberOfWs. */
};
struct MCGIDI_angularEnergy_s {
enum xDataTOM_frame frame;
MCGIDI_pdfsOfXGivenW pdfOfMuGivenE;
MCGIDI_pdfsOfXGivenW *pdfOfEpGivenEAndMu; /* The number of MCGIDI_pdfsOfXGivenW allocated is given by pdfOfMuGivenE.numberOfWs. */
};
struct MCGIDI_KalbachMann_ras_s {
double *rs;
double *as;
};
struct MCGIDI_KalbachMann_s {
enum xDataTOM_frame frame;
double energyToMeVFactor, massFactor, Sa, Sb, Ma, mb; /* Needed if a(E,E') is caluclated from the formula. */
MCGIDI_pdfsOfXGivenW dists; /* Sa currently not used. */
MCGIDI_KalbachMann_ras *ras;
};
struct MCGIDI_distribution_s {
MCGIDI_product *product;
enum MCGIDI_distributionType type;
MCGIDI_angular *angular; /* All distribution forms must have a frame member. */
MCGIDI_energy *energy;
MCGIDI_energyAngular *energyAngular;
MCGIDI_angularEnergy *angularEnergy;
MCGIDI_KalbachMann *KalbachMann;
};
struct MCGIDI_outputChannel_s {
enum MCGIDI_channelGenre genre;
MCGIDI_reaction *reaction; /* This is only used for output channels. */
MCGIDI_product *parent; /* This is only used for decay channels. */
int QIsFloat;
double Q;
int numberOfProducts;
MCGIDI_product *products;
};
struct MCGIDI_product_s {
MCGIDI_POP *pop;
char *label;
MCGIDI_outputChannel *outputChannel;
int multiplicity; /* If 0, the multiplicity is either 'energyDependent' or 'partialProduction'. */
int delayedNeutronIndex;
double delayedNeutronRate;
ptwXYPoints *multiplicityVsEnergy;
ptwXYPoints *norms;
int numberOfPiecewiseMultiplicities;
ptwXYPoints **piecewiseMultiplicities;
MCGIDI_distribution distribution;
MCGIDI_outputChannel decayChannel;
};
struct MCGIDI_reaction_s {
MCGIDI_target_heated *target;
int ENDF_MT, ENDL_C, ENDL_S;
enum MCGIDI_reactionType reactionType;
char const *outputChannelStr;
xDataTOM_attributionList attributes; /* Do not free, owned by attributes. */
int domainValuesPresent; /* True if cross section data defined so EMin and EMax are value. */
int thresholdGroupIndex; /* For grouped data, the group index where threshold starts. */
double thresholdGroupDomain; /* This is groupEnergy[thresholdGroupIndex+1] - EMin. */
double thresholdGroupedDeltaCrossSection; /* The adjusted group cross section in group thresholdGroupIndex. */
double EMin, EMax, finalQ; /* BRB, EMin is used as threshold. However, some reactions, especially charged particle */
ptwXYPoints *crossSection; /* have effective thresholds much higher than EMin, may need to handle these differently??????? */
ptwXPoints *crossSectionGrouped;
MCGIDI_outputChannel outputChannel;
MCGIDI_productsInfo productsInfo; /* See MCGIDI_reaction_ParseDetermineReactionProducts for description. */
transportabilitiesMap *transportabilities;
};
struct MCGIDI_target_heated_s {
int ordinal;
char *path; /* Partial path of input file. */
char *absPath; /* Full absolute path of input file. */
MCGIDI_POPs pops;
MCGIDI_POP *projectilePOP;
MCGIDI_POP *targetPOP;
xDataTOM_attributionList attributes;
char *contents;
double temperature_MeV;
double EMin, EMax;
ptwXYPoints *crossSection;
ptwXPoints *crossSectionGrouped;
ptwXPoints *crossSectionGroupedForSampling;
int numberOfReactions;
MCGIDI_reaction *reactions;
transportabilitiesMap *transportabilities;
};
struct MCGIDI_target_heated_info_s {
int ordinal;
double temperature;
char *path; /* Full path of input file. */
char *contents;
MCGIDI_target_heated *heatedTarget;
};
struct MCGIDI_target_s {
char *path; /* Full path of input file. */
char *absPath; /* Full absolute path of input file. */
MCGIDI_POP *projectilePOP;
MCGIDI_POP *targetPOP;
xDataTOM_attributionList attributes;
int nHeatedTargets, nReadHeatedTargets;
MCGIDI_target_heated *baseHeatedTarget; /* The lowest temperature whose contents is "all" data, (e.g, not just "crossSection"). */
MCGIDI_target_heated_info *heatedTargets; /* List of heated targets in order by temperature. */
MCGIDI_target_heated_info **readHeatedTargets; /* List of "read in" heated targets in order by temperature. */
};
char const *MCGIDI_version( void );
int MCGIDI_versionMajor( void );
int MCGIDI_versionMinor( void );
int MCGIDI_versionPatchLevel( void );
/*
* Routines in MCGIDI_target.c
*/
MCGIDI_target *MCGIDI_target_new( statusMessageReporting *smr );
int MCGIDI_target_initialize( statusMessageReporting *smr, MCGIDI_target *target );
MCGIDI_target *MCGIDI_target_newRead( statusMessageReporting *smr, const char *fileName );
int MCGIDI_target_readFromMapViaPoPIDs( statusMessageReporting *smr, MCGIDI_target *target, MCGIDI_map *map, const char *evaluation,
int projectile_PoPID, int target_PoPID );
int MCGIDI_target_readFromMap( statusMessageReporting *smr, MCGIDI_target *target, MCGIDI_map *map, const char *evaluation, const char *projectileName,
const char *targetName );
MCGIDI_target *MCGIDI_target_newReadFromMapViaPoPIDs( statusMessageReporting *smr, MCGIDI_map *map, const char *evaluation,
int projectile_PoPID, int target_PoPID );
MCGIDI_target *MCGIDI_target_newReadFromMap( statusMessageReporting *smr, MCGIDI_map *map, const char *evaluation, const char *projectileName,
const char *targetName );
MCGIDI_target *MCGIDI_target_free( statusMessageReporting *smr, MCGIDI_target *target );
int MCGIDI_target_release( statusMessageReporting *smr, MCGIDI_target *target );
int MCGIDI_target_read( statusMessageReporting *smr, MCGIDI_target *target, const char *fileName );
char const *MCGIDI_target_getAttributesValue( statusMessageReporting *smr, MCGIDI_target *target, char const *name );
int MCGIDI_target_getTemperatures( statusMessageReporting *smr, MCGIDI_target *target, double *temperatures );
int MCGIDI_target_readHeatedTarget( statusMessageReporting *smr, MCGIDI_target *target, int index );
MCGIDI_target_heated *MCGIDI_target_getHeatedTargetAtIndex_ReadIfNeeded( statusMessageReporting *smr, MCGIDI_target *target, int index );
MCGIDI_target_heated *MCGIDI_target_getHeatedTargetAtTIndex( statusMessageReporting *smr, MCGIDI_target *target, int index );
int MCGIDI_target_numberOfReactions( statusMessageReporting *smr, MCGIDI_target *target );
enum MCGIDI_reactionType MCGIDI_target_getReactionTypeAtIndex( statusMessageReporting *smr, MCGIDI_target *target, int index );
MCGIDI_reaction *MCGIDI_target_getReactionAtIndex( MCGIDI_target *target, int index );
MCGIDI_reaction *MCGIDI_target_getReactionAtIndex_smr( statusMessageReporting *smr, MCGIDI_target *target, int index );
int MCGIDI_target_numberOfProductionReactions( statusMessageReporting *smr, MCGIDI_target *target );
transportabilitiesMap const *MCGIDI_target_getUniqueProducts( statusMessageReporting *smr, MCGIDI_target *target );
int MCGIDI_target_recast( statusMessageReporting *smr, MCGIDI_target *target, GIDI_settings &settings );
int MCGIDI_target_getDomain( statusMessageReporting *smr, MCGIDI_target *target, double *EMin, double *EMax );
double MCGIDI_target_getTotalCrossSectionAtTAndE( statusMessageReporting *smr, MCGIDI_target *target, MCGIDI_quantitiesLookupModes &modes,
bool sampling );
double MCGIDI_target_getIndexReactionCrossSectionAtE( statusMessageReporting *smr, MCGIDI_target *target, int index, MCGIDI_quantitiesLookupModes &modes,
bool sampling );
int MCGIDI_target_sampleReaction( statusMessageReporting *smr, MCGIDI_target *target, MCGIDI_quantitiesLookupModes &modes, double totalXSec,
double (*userrng)( void * ), void *rngState );
int MCGIDI_target_sampleNullReactionProductsAtE( statusMessageReporting *smr, MCGIDI_target *target,
MCGIDI_quantitiesLookupModes &modes, MCGIDI_decaySamplingInfo *decaySamplingInfo, MCGIDI_sampledProductsDatas *productDatas );
int MCGIDI_target_sampleIndexReactionProductsAtE( statusMessageReporting *smr, MCGIDI_target *target, int index,
MCGIDI_quantitiesLookupModes &modes, MCGIDI_decaySamplingInfo *decaySamplingInfo, MCGIDI_sampledProductsDatas *productData );
double MCGIDI_target_getIndexReactionFinalQ( statusMessageReporting *smr, MCGIDI_target *target, int index, MCGIDI_quantitiesLookupModes &modes );
/*
* Routines in MCGIDI_target_heated.c
*/
MCGIDI_target_heated *MCGIDI_target_heated_new( statusMessageReporting *smr );
int MCGIDI_target_heated_initialize( statusMessageReporting *smr, MCGIDI_target_heated *target );
MCGIDI_target_heated *MCGIDI_target_heated_newRead( statusMessageReporting *smr, const char *fileName );
MCGIDI_target_heated *MCGIDI_target_heated_free( statusMessageReporting *smr, MCGIDI_target_heated *target );
int MCGIDI_target_heated_release( statusMessageReporting *smr, MCGIDI_target_heated *target );
int MCGIDI_target_heated_read( statusMessageReporting *smr, MCGIDI_target_heated *target, const char *fileName );
int MCGIDI_target_heated_numberOfReactions( statusMessageReporting *smr, MCGIDI_target_heated *target );
int MCGIDI_target_heated_numberOfProductionReactions( statusMessageReporting *smr, MCGIDI_target_heated *target );
MCGIDI_reaction *MCGIDI_target_heated_getReactionAtIndex( MCGIDI_target_heated *target, int index );
MCGIDI_reaction *MCGIDI_target_heated_getReactionAtIndex_smr( statusMessageReporting *smr, MCGIDI_target_heated *target, int index );
#if 0
MCGIDI_reaction *MCGIDI_target_heated_getProductionReactionAtIndex( MCGIDI_target_heated *target, int index );
#endif
MCGIDI_POP *MCGIDI_target_heated_getPOPForProjectile( statusMessageReporting *smr, MCGIDI_target_heated *target );
MCGIDI_POP *MCGIDI_target_heated_getPOPForTarget( statusMessageReporting *smr, MCGIDI_target_heated *target );
double MCGIDI_target_heated_getProjectileMass_MeV( statusMessageReporting *smr, MCGIDI_target_heated *target );
double MCGIDI_target_heated_getTargetMass_MeV( statusMessageReporting *smr, MCGIDI_target_heated *target );
int MCGIDI_target_heated_getEnergyGrid( statusMessageReporting *smr, MCGIDI_target_heated *target, double **energyGrid );
double MCGIDI_target_heated_getTotalCrossSectionAtE( statusMessageReporting *smr, MCGIDI_target_heated *target, MCGIDI_quantitiesLookupModes &modes,
bool sampling );
double MCGIDI_target_heated_getIndexReactionCrossSectionAtE( statusMessageReporting *smr, MCGIDI_target_heated *target, int index,
MCGIDI_quantitiesLookupModes &modes, bool sampling );
int MCGIDI_target_heated_sampleIndexReactionProductsAtE( statusMessageReporting *smr, MCGIDI_target_heated *target, int index,
MCGIDI_quantitiesLookupModes &modes, MCGIDI_decaySamplingInfo *decaySamplingInfo, MCGIDI_sampledProductsDatas *productData );
double MCGIDI_target_heated_getReactionsThreshold( statusMessageReporting *smr, MCGIDI_target_heated *target, int index );
int MCGIDI_target_heated_getReactionsDomain( statusMessageReporting *smr, MCGIDI_target_heated *target, int index, double *EMin, double *EMax );
double MCGIDI_target_heated_getIndexReactionFinalQ( statusMessageReporting *smr, MCGIDI_target_heated *target, int index,
MCGIDI_quantitiesLookupModes &modes );
transportabilitiesMap const *MCGIDI_target_heated_getUniqueProducts( statusMessageReporting *smr, MCGIDI_target_heated *target );
int MCGIDI_target_heated_recast( statusMessageReporting *smr, MCGIDI_target_heated *target, GIDI_settings &settings );
/*
* Routines in MCGIDI_reaction.c
*/
MCGIDI_reaction *MCGIDI_reaction_new( statusMessageReporting *smr );
int MCGIDI_reaction_initialize( statusMessageReporting *smr, MCGIDI_reaction *reaction );
MCGIDI_reaction *MCGIDI_reaction_free( statusMessageReporting *smr, MCGIDI_reaction *reaction );
int MCGIDI_reaction_release( statusMessageReporting *smr, MCGIDI_reaction *reaction );
int MCGIDI_reaction_parseFromTOM( statusMessageReporting *smr, xDataTOM_element *element, MCGIDI_target_heated *target,
MCGIDI_POPs *pops, MCGIDI_reaction *reaction );
enum MCGIDI_reactionType MCGIDI_reaction_getReactionType( statusMessageReporting *smr, MCGIDI_reaction *reaction );
MCGIDI_target_heated *MCGIDI_reaction_getTargetHeated( statusMessageReporting *smr, MCGIDI_reaction *reaction );
double MCGIDI_reaction_getProjectileMass_MeV( statusMessageReporting *smr, MCGIDI_reaction *reaction );
double MCGIDI_reaction_getTargetMass_MeV( statusMessageReporting *smr, MCGIDI_reaction *reaction );
int MCGIDI_reaction_getDomain( statusMessageReporting *smr, MCGIDI_reaction *reaction, double *EMin, double *EMax );
int MCGIDI_reaction_fixDomains( statusMessageReporting *smr, MCGIDI_reaction *reaction, double EMin, double EMax, nfu_status *status );
double MCGIDI_reaction_getCrossSectionAtE( statusMessageReporting *smr, MCGIDI_reaction *reaction, MCGIDI_quantitiesLookupModes &modes, bool sampling );
double MCGIDI_reaction_getFinalQ( statusMessageReporting *smr, MCGIDI_reaction *reaction, MCGIDI_quantitiesLookupModes &modes );
int MCGIDI_reaction_getENDF_MTNumber( MCGIDI_reaction *reaction );
int MCGIDI_reaction_getENDL_CSNumbers( MCGIDI_reaction *reaction, int *S );
int MCGIDI_reaction_recast( statusMessageReporting *smr, MCGIDI_reaction *reaction, GIDI_settings &settings,
GIDI_settings_particle const *projectileSettings, double temperature_MeV, ptwXPoints *totalGroupedCrossSection );
MCGIDI_productsInfo *MCGIDI_reaction_getProductsInfo( MCGIDI_reaction *reaction );
int MCGIDI_productsInfo_getNumberOfUniqueProducts( MCGIDI_productsInfo *productsInfo );
int MCGIDI_productsInfo_getPoPsIndexAtIndex( MCGIDI_productsInfo *productsInfo, int index );
enum MCGIDI_productMultiplicityType MCGIDI_productsInfo_getMultiplicityTypeAtIndex( MCGIDI_productsInfo *productsInfo, int index );
int MCGIDI_productsInfo_getIntegerMultiplicityAtIndex( MCGIDI_productsInfo *productsInfo, int index );
int MCGIDI_productsInfo_getTransportableAtIndex( MCGIDI_productsInfo *productsInfo, int index );
/*
* Routines in MCGIDI_pop.c
*/
MCGIDI_POPs *MCGIDI_POPs_new( statusMessageReporting *smr, int size );
int MCGIDI_POPs_initial( statusMessageReporting *smr, MCGIDI_POPs *pops, int size );
void *MCGIDI_POPs_free( MCGIDI_POPs *pops );
int MCGIDI_POPs_release( MCGIDI_POPs *pops );
MCGIDI_POP *MCGIDI_POPs_addParticleIfNeeded( statusMessageReporting *smr, MCGIDI_POPs *pops, char const *name, double mass_MeV,
double level_MeV, MCGIDI_POP *parent, int globalParticle );
int MCGIDI_POPs_findParticleIndex( MCGIDI_POPs *pops, char const *name );
MCGIDI_POP *MCGIDI_POPs_findParticle( MCGIDI_POPs *pops, char const *name );
void MCGIDI_POPs_writeSortedList( MCGIDI_POPs *pops, FILE *f );
void MCGIDI_POPs_printSortedList( MCGIDI_POPs *pops );
MCGIDI_POP *MCGIDI_POP_new( statusMessageReporting *smr, char const *name, double mass_MeV, double level_MeV, MCGIDI_POP *parent );
MCGIDI_POP *MCGIDI_POP_free( MCGIDI_POP *pop );
MCGIDI_POP *MCGIDI_POP_release( MCGIDI_POP *pop );
double MCGIDI_POP_getMass_MeV( MCGIDI_POP *pop );
/*
* Routines in MCGIDI_particle.c
*/
MCGIDI_particle *MCGIDI_particle_new( statusMessageReporting *smr );
int MCGIDI_particle_initialize( statusMessageReporting *smr, MCGIDI_particle *particle );
MCGIDI_particle *MCGIDI_particle_free( statusMessageReporting *smr, MCGIDI_particle *particle );
int MCGIDI_particle_release( statusMessageReporting *smr, MCGIDI_particle *particle );
int MCGIDI_particle_freeInternalList( statusMessageReporting *smr );
MCGIDI_particle *MCGIDI_particle_getInternalID( statusMessageReporting *smr, const char * const name, MCGIDI_POPs *pops );
int MCGIDI_particle_printInternalSortedList( statusMessageReporting *smr );
/*
* Routines in MCGIDI_outputChannel.c
*/
MCGIDI_outputChannel *MCGIDI_outputChannel_new( statusMessageReporting *smr );
int MCGIDI_outputChannel_initialize( statusMessageReporting *smr, MCGIDI_outputChannel *outputChannel );
MCGIDI_outputChannel *MCGIDI_outputChannel_free( statusMessageReporting *smr, MCGIDI_outputChannel *outputChannel );
int MCGIDI_outputChannel_release( statusMessageReporting *smr, MCGIDI_outputChannel *outputChannel );
int MCGIDI_outputChannel_parseFromTOM( statusMessageReporting *smr, xDataTOM_element *element, MCGIDI_POPs *pops, MCGIDI_outputChannel *outputChannel,
MCGIDI_reaction *reaction, MCGIDI_product *parent );
int MCGIDI_outputChannel_numberOfProducts( MCGIDI_outputChannel *outputChannel );
MCGIDI_product *MCGIDI_outputChannel_getProductAtIndex( statusMessageReporting *smr, MCGIDI_outputChannel *outputChannel, int i );
int MCGIDI_outputChannel_getDomain( statusMessageReporting *smr, MCGIDI_outputChannel *outputChannel, double *EMin, double *EMax );
MCGIDI_target_heated *MCGIDI_outputChannel_getTargetHeated( statusMessageReporting *smr, MCGIDI_outputChannel *outputChannel );
double MCGIDI_outputChannel_getProjectileMass_MeV( statusMessageReporting *smr, MCGIDI_outputChannel *outputChannel );
double MCGIDI_outputChannel_getTargetMass_MeV( statusMessageReporting *smr, MCGIDI_outputChannel *outputChannel );
double MCGIDI_outputChannel_getQ_MeV( statusMessageReporting *smr, MCGIDI_outputChannel *outputChannel, double e_in );
double MCGIDI_outputChannel_getFinalQ( statusMessageReporting *smr, MCGIDI_outputChannel *outputChannel, double e_in );
int MCGIDI_outputChannel_sampleProductsAtE( statusMessageReporting *smr, MCGIDI_outputChannel *outputChannel, MCGIDI_quantitiesLookupModes &modes,
MCGIDI_decaySamplingInfo *decaySamplingInfo, MCGIDI_sampledProductsDatas *productDatas, double *masses );
/*
* Routines in MCGIDI_product.c
*/
MCGIDI_product *MCGIDI_product_new( statusMessageReporting *smr );
int MCGIDI_product_initialize( statusMessageReporting *smr, MCGIDI_product *product );
MCGIDI_product *MCGIDI_product_free( statusMessageReporting *smr, MCGIDI_product *product );
int MCGIDI_product_release( statusMessageReporting *smr, MCGIDI_product *product );
int MCGIDI_product_parseFromTOM( statusMessageReporting *smr, xDataTOM_element *element, MCGIDI_outputChannel *outputChannel,
MCGIDI_POPs *pops, MCGIDI_product *product, int *delayedNeutronIndex );
int MCGIDI_product_getDomain( statusMessageReporting *smr, MCGIDI_product *product, double *EMin, double *EMax );
int MCGIDI_product_setTwoBodyMasses( statusMessageReporting *smr, MCGIDI_product *product, double projectileMass_MeV, double targetMass_MeV,
double productMass_MeV, double residualMass_MeV );
double MCGIDI_product_getMass_MeV( statusMessageReporting *smr, MCGIDI_product *product );
MCGIDI_target_heated *MCGIDI_product_getTargetHeated( statusMessageReporting *smr, MCGIDI_product *product );
double MCGIDI_product_getProjectileMass_MeV( statusMessageReporting *smr, MCGIDI_product *product );
double MCGIDI_product_getTargetMass_MeV( statusMessageReporting *smr, MCGIDI_product *product );
int MCGIDI_product_sampleMultiplicity( statusMessageReporting *smr, MCGIDI_product *product, double e_in, double r );
int MCGIDI_product_sampleMu( statusMessageReporting *smr, MCGIDI_product *product, MCGIDI_quantitiesLookupModes &modes,
MCGIDI_decaySamplingInfo *decaySamplingInfo );
int MCGIDI_sampledProducts_initialize( statusMessageReporting *smr, MCGIDI_sampledProductsDatas *sampledProductsDatas, int incrementSize );
int MCGIDI_sampledProducts_release( statusMessageReporting *smr, MCGIDI_sampledProductsDatas *sampledProductsDatas );
int MCGIDI_sampledProducts_remalloc( statusMessageReporting *smr, MCGIDI_sampledProductsDatas *sampledProductsDatas );
int MCGIDI_sampledProducts_addProduct( statusMessageReporting *smr, MCGIDI_sampledProductsDatas *sampledProductsDatas,
MCGIDI_sampledProductsData *sampledProductsData );
int MCGIDI_sampledProducts_number( MCGIDI_sampledProductsDatas *sampledProductsDatas );
MCGIDI_sampledProductsData *MCGIDI_sampledProducts_getProductAtIndex( MCGIDI_sampledProductsDatas *sampledProductsDatas, int index );
/*
* Routines in MCGIDI_distribution.c
*/
MCGIDI_distribution *MCGIDI_distribution_new( statusMessageReporting *smr );
int MCGIDI_distribution_initialize( statusMessageReporting *smr, MCGIDI_distribution *distribution );
MCGIDI_distribution *MCGIDI_distribution_free( statusMessageReporting *smr, MCGIDI_distribution *distribution );
int MCGIDI_distribution_release( statusMessageReporting *smr, MCGIDI_distribution *distribution );
int MCGIDI_distribution_parseFromTOM( statusMessageReporting *smr, xDataTOM_element *element, MCGIDI_product *product, MCGIDI_POPs *pops, ptwXYPoints *norms );
/*
* Routines in MCGIDI_angular.c
*/
MCGIDI_angular *MCGIDI_angular_new( statusMessageReporting *smr );
int MCGIDI_angular_initialize( statusMessageReporting *smr, MCGIDI_angular *angular );
MCGIDI_angular *MCGIDI_angular_free( statusMessageReporting *smr, MCGIDI_angular *angular );
int MCGIDI_angular_release( statusMessageReporting *smr, MCGIDI_angular *angular );
int MCGIDI_angular_setTwoBodyMasses( statusMessageReporting *smr, MCGIDI_angular *angular, double projectileMass_MeV, double targetMass_MeV,
double productMass_MeV, double residualMass_MeV );
int MCGIDI_angular_parseFromTOM( statusMessageReporting *smr, xDataTOM_element *element, MCGIDI_distribution *distribution, ptwXYPoints *norms );
int MCGIDI_angular_sampleMu( statusMessageReporting *smr, MCGIDI_angular *angular, MCGIDI_quantitiesLookupModes &modes,
MCGIDI_decaySamplingInfo *decaySamplingInfo );
/*
* Routines in MCGIDI_energy.c
*/
MCGIDI_energy *MCGIDI_energy_new( statusMessageReporting *smr );
int MCGIDI_energy_initialize( statusMessageReporting *smr, MCGIDI_energy *energy );
MCGIDI_energy *MCGIDI_energy_free( statusMessageReporting *smr, MCGIDI_energy *energy );
int MCGIDI_energy_release( statusMessageReporting *smr, MCGIDI_energy *energy );
int MCGIDI_energy_parseFromTOM( statusMessageReporting *smr, xDataTOM_element *element, MCGIDI_distribution *distribution, ptwXYPoints *norms,
enum MCGIDI_energyType energyType, double gammaEnergy_MeV );
int MCGIDI_energy_sampleEnergy( statusMessageReporting *smr, MCGIDI_energy *energy, MCGIDI_quantitiesLookupModes &modes,
MCGIDI_decaySamplingInfo *decaySamplingInfo );
/*
* Routines in MCGIDI_energyAngular.c
*/
int MCGIDI_energyAngular_parseFromTOM( statusMessageReporting *smr, xDataTOM_element *element, MCGIDI_distribution *distribution );
MCGIDI_energyAngular *MCGIDI_energyAngular_new( statusMessageReporting *smr );
int MCGIDI_energyAngular_initialize( statusMessageReporting *smr, MCGIDI_energyAngular *energyAngular );
MCGIDI_energyAngular *MCGIDI_energyAngular_free( statusMessageReporting *smr, MCGIDI_energyAngular *energyAngular );
int MCGIDI_energyAngular_release( statusMessageReporting *smr, MCGIDI_energyAngular *energyAngular );
int MCGIDI_energyAngular_sampleDistribution( statusMessageReporting *smr, MCGIDI_distribution *distribution, MCGIDI_quantitiesLookupModes &modes,
MCGIDI_decaySamplingInfo *decaySamplingInfo );
/*
* Routines in MCGIDI_angularEnergy.c
*/
MCGIDI_angularEnergy *MCGIDI_angularEnergy_new( statusMessageReporting *smr );
int MCGIDI_angularEnergy_initialize( statusMessageReporting *smr, MCGIDI_angularEnergy *energyAngular );
MCGIDI_angularEnergy *MCGIDI_angularEnergy_free( statusMessageReporting *smr, MCGIDI_angularEnergy *energyAngular );
int MCGIDI_angularEnergy_release( statusMessageReporting *smr, MCGIDI_angularEnergy *energyAngular );
int MCGIDI_angularEnergy_parseFromTOM( statusMessageReporting *smr, xDataTOM_element *element, MCGIDI_distribution *distribution );
int MCGIDI_angularEnergy_sampleDistribution( statusMessageReporting *smr, MCGIDI_angularEnergy *angularEnergy, MCGIDI_quantitiesLookupModes &modes,
MCGIDI_decaySamplingInfo *decaySamplingInfo );
/*
* Routines in MCGIDI_KalbachMann.c
*/
MCGIDI_KalbachMann *MCGIDI_KalbachMann_new( statusMessageReporting *smr, ptwXY_interpolation interpolationWY, ptwXY_interpolation interpolationXY );
int MCGIDI_KalbachMann_initialize( statusMessageReporting *smr, MCGIDI_KalbachMann *KalbachMann, ptwXY_interpolation interpolationWY, ptwXY_interpolation interpolationXY );
MCGIDI_KalbachMann *MCGIDI_KalbachMann_free( statusMessageReporting *smr, MCGIDI_KalbachMann *KalbachMann );
int MCGIDI_KalbachMann_release( statusMessageReporting *smr, MCGIDI_KalbachMann *KalbachMann );
int MCGIDI_KalbachMann_parseFromTOM( statusMessageReporting *smr, xDataTOM_element *element, MCGIDI_distribution *distribution );
int MCGIDI_KalbachMann_sampleEp( statusMessageReporting *smr, MCGIDI_KalbachMann *KalbachMann, MCGIDI_quantitiesLookupModes &modes,
MCGIDI_decaySamplingInfo *decaySamplingInfo );
/*
* Routines in MCGIDI_uncorrelated.c
*/
int MCGIDI_uncorrelated_parseFromTOM( statusMessageReporting *smr, xDataTOM_element *element, MCGIDI_distribution *distribution, ptwXYPoints *norms,
enum MCGIDI_energyType energyType, double gammaEnergy_MeV );
int MCGIDI_uncorrelated_sampleDistribution( statusMessageReporting *smr, MCGIDI_distribution *distribution, MCGIDI_quantitiesLookupModes &modes,
MCGIDI_decaySamplingInfo *decaySamplingInfo );
/*
* Routines in MCGIDI_LLNLAngular_angularEnergy.c
*/
int MCGIDI_LLNLAngular_angularEnergy_parseFromTOM( statusMessageReporting *smr, xDataTOM_element *element, MCGIDI_distribution *distribution );
/*
* Routines in MCGIDI_kinetics.c
*/
int MCGIDI_kinetics_2BodyReaction( statusMessageReporting *smr, MCGIDI_angular *angular, double K, double mu, double phi,
MCGIDI_sampledProductsData *outgoingData );
int MCGIDI_kinetics_COMKineticEnergy2LabEnergyAndMomentum( statusMessageReporting *smr, double beta, double e_kinetic_com, double mu, double phi,
double m3cc, double m4cc, MCGIDI_sampledProductsData *outgoingData );
int MCGIDI_kinetics_COM2Lab( statusMessageReporting *smr, MCGIDI_quantitiesLookupModes &modes, MCGIDI_decaySamplingInfo *decaySamplingInfo, double masses[3] );
/*
* Routines in MCGIDI_sampling.c
*/
int MCGIDI_sampling_pdfsOfXGivenW_initialize( statusMessageReporting *smr, MCGIDI_pdfsOfXGivenW *dists );
int MCGIDI_sampling_pdfsOfXGivenW_release( statusMessageReporting *smr, MCGIDI_pdfsOfXGivenW *dists );
int MCGIDI_sampling_pdfsOfX_release( statusMessageReporting *smr, MCGIDI_pdfOfX *dist );
int MCGIDI_sampling_sampleX_from_pdfsOfXGivenW( MCGIDI_pdfsOfXGivenW *dists, MCGIDI_pdfsOfXGivenW_sampled *sampled, double r );
int MCGIDI_sampling_sampleX_from_pdfOfX( MCGIDI_pdfOfX *dist, MCGIDI_pdfsOfXGivenW_sampled *sampled, double r );
int MCGIDI_sampling_doubleDistribution( statusMessageReporting *smr, MCGIDI_pdfsOfXGivenW *pdfOfWGivenV, MCGIDI_pdfsOfXGivenW *pdfOfXGivenVAndW,
MCGIDI_quantitiesLookupModes &modes, MCGIDI_decaySamplingInfo *decaySamplingInfo );
int MCGIDI_sampling_interpolationValues( statusMessageReporting *smr, ptwXY_interpolation interpolation, double *ws, double y1, double y2, double *y );
double MCGIDI_sampling_ptwXY_getValueAtX( ptwXYPoints *ptwXY, double x1 );
/*
* Routines in MCGIDI_misc.c
*/
int MCGIDI_misc_NumberOfZSymbols( void );
const char *MCGIDI_misc_ZToSymbol( int iZ );
int MCGIDI_misc_symbolToZ( const char *Z );
int MCGIDI_miscNameToZAm( statusMessageReporting *smr, const char *name, int *Z, int *A, int *m, int *level );
xDataTOM_Int MCGIDI_misc_binarySearch( xDataTOM_Int n, double *ds, double d );
int MCGIDI_misc_PQUStringToDouble( statusMessageReporting *smr, char const *str, char const *unit, double conversion, double *value );
int MCGIDI_misc_PQUStringToDoubleInUnitOf( statusMessageReporting *smr, char const *str, char const *toUnit, double *value );
void MCGIDI_misc_updateTransportabilitiesMap( transportabilitiesMap *transportabilities, int PoPID, enum MCGIDI_transportability transportability );
void MCGIDI_misc_updateTransportabilitiesMap2( transportabilitiesMap *transportabilities, int PoPID, int transportable );
#if defined __cplusplus
}
}
#endif
#endif /* End of MCGIDI_h_included. */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,463 @@
/*
# <<BEGIN-copyright>>
# Copyright 2019, Lawrence Livermore National Security, LLC.
# This file is part of the gidiplus package (https://github.com/LLNL/gidiplus).
# gidiplus is licensed under the MIT license (see https://opensource.org/licenses/MIT).
# SPDX-License-Identifier: MIT
# <<END-copyright>>
*/
#ifndef MCGIDI_distributions_hpp_included
#define MCGIDI_distributions_hpp_included 1
#include <LUPI_declareMacro.hpp>
namespace MCGIDI {
namespace Distributions {
enum class Type { none, unspecified, angularTwoBody, KalbachMann, uncorrelated, branching3d, energyAngularMC, angularEnergyMC,
coherentPhotoAtomicScattering, incoherentPhotoAtomicScattering, incoherentPhotoAtomicScatteringElectron, incoherentBoundToFreePhotoAtomicScattering, pairProductionGamma,
coherentElasticTNSL, incoherentElasticTNSL };
/*
============================================================
======================= Distribution =======================
============================================================
*/
class Distribution {
private:
Type m_type; /**< Specifies the Type of the distribution. */
GIDI::Frame m_productFrame; /**< Specifies the frame the product data are given in. */
double m_projectileMass; /**< The mass of the projectile. */
double m_targetMass; /**< The mass of the target. */
double m_productMass; /**< The mass of the first product. */
public:
LUPI_HOST_DEVICE Distribution( );
LUPI_HOST Distribution( Type a_type, GIDI::Distributions::Distribution const &a_distribution, SetupInfo &a_setupInfo );
LUPI_HOST Distribution( Type a_type, GIDI::Frame a_productFrame, SetupInfo &a_setupInfo );
LUPI_HOST_DEVICE MCGIDI_VIRTUAL_FUNCTION ~Distribution( ) MCGIDI_TRUE_VIRTUAL;
LUPI_HOST_DEVICE Type type( ) const { return( m_type ); } /**< Returns the value of the **m_type**. */
LUPI_HOST_DEVICE GIDI::Frame productFrame( ) const { return( m_productFrame ); } /**< Returns the value of the **m_productFrame**. */
LUPI_HOST_DEVICE double projectileMass( ) const { return( m_projectileMass ); } /**< Returns the value of the **m_projectileMass**. */
LUPI_HOST_DEVICE double targetMass( ) const { return( m_targetMass ); } /**< Returns the value of the **m_targetMass**. */
LUPI_HOST_DEVICE double productMass( ) const { return( m_productMass ); } /**< Returns the value of the **m_productMass**. */
LUPI_HOST void setModelDBRC_data( Sampling::Upscatter::ModelDBRC_data *a_modelDBRC_data );
template <typename RNG>
LUPI_HOST_DEVICE MCGIDI_VIRTUAL_FUNCTION void sample( double a_X, Sampling::Input &a_input, RNG && a_rng ) const MCGIDI_TRUE_VIRTUAL;
template <typename RNG>
LUPI_HOST_DEVICE MCGIDI_VIRTUAL_FUNCTION double angleBiasing( Reaction const *a_reaction, double a_temperature, double a_energy_in, double a_mu_lab,
RNG && a_rng, double &a_energy_out ) const MCGIDI_TRUE_VIRTUAL;
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
};
/*
============================================================
====================== AngularTwoBody ======================
============================================================
*/
class AngularTwoBody : public Distribution {
private:
double m_residualMass; /**< The mass of the second product (often the residual). */
double m_Q; /**< FIX ME. */
double m_twoBodyThreshold; /**< This is the T_1 value needed to do two-body kinematics (i.e., in the equation (K_{com,3_4} = m_2 * (K_1 - T_1) / (m_1 + m_2)). */
bool m_Upscatter; /**< Set to true if reaction is elastic which is the only reaction upscatter Model B is applied to. */
Probabilities::ProbabilityBase2d_d1 *m_angular; /**< The 2d angular probability. */
Sampling::Upscatter::ModelDBRC_data *m_modelDBRC_data; /**< The cross section and other data needed for neutron elastic upscatter model DBRC. */
template <typename RNG>
LUPI_HOST_DEVICE bool upscatterModelB( double a_kineticLab, Sampling::Input &a_input, RNG && a_rng ) const ;
public:
LUPI_HOST_DEVICE AngularTwoBody( );
LUPI_HOST AngularTwoBody( GIDI::Distributions::AngularTwoBody const &a_angularTwoBody, SetupInfo &a_setupInfo );
LUPI_HOST_DEVICE ~AngularTwoBody( );
LUPI_HOST_DEVICE double residualMass( ) const { return( m_residualMass ); } /**< Returns the value of the **m_residualMass**. */
LUPI_HOST_DEVICE double Q( ) const { return( m_Q ); } /**< Returns the value of the **m_Q**. */
LUPI_HOST_DEVICE Probabilities::ProbabilityBase2d_d1 *angular( ) const { return( m_angular ); } /**< Returns the value of the **m_angular**. */
template <typename RNG>
LUPI_HOST_DEVICE void sample( double a_X, Sampling::Input &a_input, RNG && a_rng ) const ;
template <typename RNG>
LUPI_HOST_DEVICE double angleBiasing( Reaction const *a_reaction, double a_temperature, double a_energy_in, double a_mu_lab,
RNG && a_rng, double &a_energy_out ) const ;
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
LUPI_HOST_DEVICE bool Upscatter( ) const { return( m_Upscatter ); } /**< Returns the value of the **m_Upscatter**. */
LUPI_HOST void setModelDBRC_data2( Sampling::Upscatter::ModelDBRC_data *a_modelDBRC_data );
};
/*
============================================================
======================= Uncorrelated =======================
============================================================
*/
class Uncorrelated : public Distribution {
private:
Probabilities::ProbabilityBase2d_d1 *m_angular; /**< The angular probability P(mu|E). */
Probabilities::ProbabilityBase2d *m_energy; /**< The energy probability P(E'|E). */
public:
LUPI_HOST_DEVICE Uncorrelated( );
LUPI_HOST Uncorrelated( GIDI::Distributions::Uncorrelated const &a_uncorrelated, SetupInfo &a_setupInfo );
LUPI_HOST_DEVICE ~Uncorrelated( );
LUPI_HOST_DEVICE Probabilities::ProbabilityBase2d_d1 *angular( ) const { return( m_angular ); } /**< Returns the value of the **m_angular**. */
LUPI_HOST_DEVICE Probabilities::ProbabilityBase2d *energy( ) const { return( m_energy ); } /**< Returns the value of the **m_energy**. */
template <typename RNG>
LUPI_HOST_DEVICE void sample( double a_X, Sampling::Input &a_input, RNG && a_rng ) const ;
template <typename RNG>
LUPI_HOST_DEVICE double angleBiasing( Reaction const *a_reaction, double a_temperature, double a_energy_in, double a_mu_lab,
RNG && a_rng, double &a_energy_out ) const ;
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
};
/*
============================================================
======================== Branching3d =======================
============================================================
*/
class Branching3d : public Distribution {
private:
int m_initialStateIndex;
public:
LUPI_HOST_DEVICE Branching3d( );
LUPI_HOST Branching3d( GIDI::Distributions::Branching3d const &a_branching3d, SetupInfo &a_setupInfo );
LUPI_HOST_DEVICE ~Branching3d( );
template <typename RNG>
LUPI_HOST_DEVICE void sample( double a_X, Sampling::Input &a_input, RNG && a_rng ) const ;
template <typename RNG>
LUPI_HOST_DEVICE double angleBiasing( Reaction const *a_reaction, double a_temperature, double a_energy_in, double a_mu_lab,
RNG && a_rng, double &a_energy_out ) const ;
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
};
/*
============================================================
====================== EnergyAngularMC =====================
============================================================
*/
class EnergyAngularMC : public Distribution {
private:
Probabilities::ProbabilityBase2d_d1 *m_energy; /**< The energy probability P(E'|E). */
Probabilities::ProbabilityBase3d *m_angularGivenEnergy; /**< The angular probability given E', P(mu|E,E'). */
public:
LUPI_HOST_DEVICE EnergyAngularMC( );
LUPI_HOST EnergyAngularMC( GIDI::Distributions::EnergyAngularMC const &a_energyAngularMC, SetupInfo &a_setupInfo );
LUPI_HOST_DEVICE ~EnergyAngularMC( );
LUPI_HOST_DEVICE Probabilities::ProbabilityBase2d_d1 *energy( ) const { return( m_energy ); } /**< Returns the value of the **m_energy**. */
LUPI_HOST_DEVICE Probabilities::ProbabilityBase3d *angularGivenEnergy( ) const { return( m_angularGivenEnergy ); } /**< Returns the value of the **m_angularGivenEnergy**. */
template <typename RNG>
LUPI_HOST_DEVICE void sample( double a_X, Sampling::Input &a_input, RNG && a_rng ) const ;
template <typename RNG>
LUPI_HOST_DEVICE double angleBiasing( Reaction const *a_reaction, double a_temperature, double a_energy_in, double a_mu_lab,
RNG && a_rng, double &a_energy_out ) const ;
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
};
/*
============================================================
====================== AngularEnergyMC =====================
============================================================
*/
class AngularEnergyMC : public Distribution {
private:
Probabilities::ProbabilityBase2d_d1 *m_angular; /**< The angular probability P(mu|E). */
Probabilities::ProbabilityBase3d *m_energyGivenAngular; /**< The energy probability P(E'|E,mu). */
public:
LUPI_HOST_DEVICE AngularEnergyMC( );
LUPI_HOST AngularEnergyMC( GIDI::Distributions::AngularEnergyMC const &a_angularEnergyMC, SetupInfo &a_setupInfo );
LUPI_HOST_DEVICE ~AngularEnergyMC( );
LUPI_HOST_DEVICE Probabilities::ProbabilityBase2d_d1 *angular( ) const { return( m_angular ); } /**< Returns the value of the **m_angular**. */
LUPI_HOST_DEVICE Probabilities::ProbabilityBase3d *energyGivenAngular( ) const { return( m_energyGivenAngular ); } /**< Returns the value of the **m_energyGivenAngular**. */
template <typename RNG>
LUPI_HOST_DEVICE void sample( double a_X, Sampling::Input &a_input, RNG && a_rng ) const ;
template <typename RNG>
LUPI_HOST_DEVICE double angleBiasing( Reaction const *a_reaction, double a_temperature, double a_energy_in, double a_mu_lab,
RNG && a_rng, double &a_energy_out ) const ;
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
};
/*
============================================================
======================== KalbachMann =======================
============================================================
*/
class KalbachMann : public Distribution {
private:
double m_energyToMeVFactor; /**< The factor that converts energies to MeV. */
double m_eb_massFactor; /**< FIX ME */
Probabilities::ProbabilityBase2d_d1 *m_f; /**< The energy probability P(E'|E). */
Functions::Function2d *m_r; /**< The Kalbach-Mann r(E,E') function. */
Functions::Function2d *m_a; /**< The Kalbach-Mann a(E,E') function. */
public:
LUPI_HOST_DEVICE KalbachMann( );
LUPI_HOST KalbachMann( GIDI::Distributions::KalbachMann const &a_KalbachMann, SetupInfo &a_setupInfo );
LUPI_HOST_DEVICE ~KalbachMann( );
LUPI_HOST_DEVICE double energyToMeVFactor( ) const { return( m_energyToMeVFactor ); } /**< Returns the value of the **m_energyToMeVFactor**. */
LUPI_HOST_DEVICE double eb_massFactor( ) const { return( m_eb_massFactor ); } /**< Returns the value of the **m_eb_massFactor**. */
LUPI_HOST_DEVICE Probabilities::ProbabilityBase2d_d1 *f( ) const { return( m_f ); } /**< Returns the value of the **m_f**. */
LUPI_HOST_DEVICE Functions::Function2d *r( ) const { return( m_r ); } /**< Returns the value of the **m_r**. */
LUPI_HOST_DEVICE Functions::Function2d *a( ) const { return( m_a ); } /**< Returns the value of the **m_a**. */
template <typename RNG>
LUPI_HOST_DEVICE void sample( double a_X, Sampling::Input &a_input, RNG && a_rng ) const ;
template <typename RNG>
LUPI_HOST_DEVICE double angleBiasing( Reaction const *a_reaction, double a_temperature, double a_energy_in, double a_mu_lab,
RNG && a_rng, double &a_energy_out ) const ;
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
LUPI_HOST_DEVICE double evaluate( double E_in_lab, double E_out, double mu );
};
/*
============================================================
=============== CoherentPhotoAtomicScattering ==============
============================================================
*/
class CoherentPhotoAtomicScattering : public Distribution {
private:
bool m_anomalousDataPresent; /**< FIX ME */
Vector<double> m_energies; /**< FIX ME */
Vector<double> m_formFactor; /**< FIX ME */
Vector<double> m_a; /**< FIX ME */
Vector<double> m_integratedFormFactor; /**< FIX ME */
Vector<double> m_integratedFormFactorSquared; /**< FIX ME */
Vector<double> m_probabilityNorm1_1; /**< FIX ME */
Vector<double> m_probabilityNorm1_3; /**< FIX ME */
Vector<double> m_probabilityNorm1_5; /**< FIX ME */
Vector<double> m_probabilityNorm2_1; /**< FIX ME */
Vector<double> m_probabilityNorm2_3; /**< FIX ME */
Vector<double> m_probabilityNorm2_5; /**< FIX ME */
Functions::Function1d_d1 *m_realAnomalousFactor; /**< The real part of the anomalous scattering factor. */
Functions::Function1d_d1 *m_imaginaryAnomalousFactor; /**< The imaginary part of the anomalous scattering factor. */
LUPI_HOST_DEVICE double Z_a( double a_Z, double a_a ) const ;
public:
LUPI_HOST_DEVICE CoherentPhotoAtomicScattering( );
LUPI_HOST CoherentPhotoAtomicScattering( GIDI::Distributions::CoherentPhotoAtomicScattering const &a_coherentPhotoAtomicScattering, SetupInfo &a_setupInfo );
LUPI_HOST_DEVICE ~CoherentPhotoAtomicScattering( );
LUPI_HOST_DEVICE double evaluate( double a_energyIn, double a_mu ) const ;
LUPI_HOST_DEVICE double evaluateFormFactor( double a_energyIn, double a_mu ) const ;
template <typename RNG>
LUPI_HOST_DEVICE void sample( double a_X, Sampling::Input &a_input, RNG && a_rng ) const ;
template <typename RNG>
LUPI_HOST_DEVICE double angleBiasing( Reaction const *a_reaction, double a_temperature, double a_energy_in, double a_mu_lab,
RNG && a_rng, double &a_energy_out ) const ;
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
};
/*
============================================================
============== IncoherentPhotoAtomicScattering =============
============================================================
*/
class IncoherentPhotoAtomicScattering : public Distribution {
private:
Vector<double> m_energies; /**< FIX ME */
Vector<double> m_scatteringFactor; /**< FIX ME */
Vector<double> m_a; /**< FIX ME */
public:
LUPI_HOST_DEVICE IncoherentPhotoAtomicScattering( );
LUPI_HOST IncoherentPhotoAtomicScattering( GIDI::Distributions::IncoherentPhotoAtomicScattering const &a_incoherentPhotoAtomicScattering, SetupInfo &a_setupInfo );
LUPI_HOST_DEVICE ~IncoherentPhotoAtomicScattering( );
LUPI_HOST_DEVICE double energyRatio( double a_energyIn, double a_mu ) const ;
LUPI_HOST_DEVICE double evaluateKleinNishina( double a_energyIn, double a_mu ) const ;
LUPI_HOST_DEVICE double evaluateScatteringFactor( double a_X ) const ;
template <typename RNG>
LUPI_HOST_DEVICE void sample( double a_X, Sampling::Input &a_input, RNG && a_rng ) const ;
template <typename RNG>
LUPI_HOST_DEVICE double angleBiasing( Reaction const *a_reaction, double a_temperature, double a_energy_in, double a_mu_lab,
RNG && a_rng, double &a_energy_out ) const ;
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
/*
LUPI_HOST_DEVICE double evaluate( double E_in_lab, double mu );
*/
};
/*
=======================================================================
============== IncoherentBoundToFreePhotoAtomicScattering =============
=======================================================================
*/
class IncoherentBoundToFreePhotoAtomicScattering : public Distribution {
private:
//Vector<double> m_energies;
//Vector<double> m_ComptonProfile;
Vector<double> m_occupationNumber;
//Vector<double> m_a;
Vector<double> m_pz;
double m_bindingEnergy;
public:
LUPI_HOST_DEVICE IncoherentBoundToFreePhotoAtomicScattering( );
LUPI_HOST IncoherentBoundToFreePhotoAtomicScattering( GIDI::Distributions::IncoherentBoundToFreePhotoAtomicScattering const &a_incoherentPhotoAtomicScattering, SetupInfo &a_setupInfo );
LUPI_HOST_DEVICE ~IncoherentBoundToFreePhotoAtomicScattering( );
LUPI_HOST_DEVICE double energyRatio( double a_energyIn, double a_mu ) const ;
LUPI_HOST_DEVICE double evaluateKleinNishina( double a_energyIn, double a_mu ) const ;
LUPI_HOST_DEVICE double evaluateOccupationNumber( double a_X, double a_mu ) const;
template <typename RNG>
LUPI_HOST_DEVICE void sample( double a_X, Sampling::Input &a_input, RNG && a_rng ) const ;
template <typename RNG>
LUPI_HOST_DEVICE double angleBiasing( Reaction const *a_reaction, double a_temperature, double a_energy_in, double a_mu_lab,
RNG && a_rng, double &a_energy_out ) const ;
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
};
/*
============================================================
========== IncoherentPhotoAtomicScatteringElectron =========
============================================================
*/
class IncoherentPhotoAtomicScatteringElectron : public Distribution {
public:
LUPI_HOST_DEVICE IncoherentPhotoAtomicScatteringElectron( );
LUPI_HOST IncoherentPhotoAtomicScatteringElectron( SetupInfo &a_setupInfo );
LUPI_HOST_DEVICE ~IncoherentPhotoAtomicScatteringElectron( );
template <typename RNG>
LUPI_HOST_DEVICE void sample( double a_energy, Sampling::Input &a_input, RNG && a_rng ) const ;
template <typename RNG>
LUPI_HOST_DEVICE double angleBiasing( Reaction const *a_reaction, double a_temperature, double a_energy_in, double a_mu_lab,
RNG && a_rng, double &a_energy_out ) const ;
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
};
/*
============================================================
==================== PairProductionGamma ===================
============================================================
*/
class PairProductionGamma : public Distribution {
private:
bool m_firstSampled; /**< When sampling photons for pair production, the photons must be emitted back-to-back. The flag help do this. */
public:
LUPI_HOST_DEVICE PairProductionGamma( );
LUPI_HOST PairProductionGamma( SetupInfo &a_setupInfo, bool a_firstSampled );
LUPI_HOST_DEVICE ~PairProductionGamma( );
template <typename RNG>
LUPI_HOST_DEVICE void sample( double a_X, Sampling::Input &a_input, RNG && a_rng ) const ;
template <typename RNG>
LUPI_HOST_DEVICE double angleBiasing( Reaction const *a_reaction, double a_temperature, double a_energy_in, double a_mu_lab,
RNG && a_rng, double &a_energy_out ) const ;
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
};
/*
============================================================
==================== CoherentElasticTNSL ===================
============================================================
*/
class CoherentElasticTNSL : public Distribution {
private:
Interpolation m_temperatureInterpolation;
Vector<double> m_temperatures;
Vector<double> m_energies;
Vector<double> m_S_table;
public:
LUPI_HOST_DEVICE CoherentElasticTNSL( );
LUPI_HOST CoherentElasticTNSL( GIDI::DoubleDifferentialCrossSection::n_ThermalNeutronScatteringLaw::CoherentElastic const *a_coherentElasticTNSL,
SetupInfo &a_setupInfo );
LUPI_HOST_DEVICE ~CoherentElasticTNSL( ) {}
template <typename RNG>
LUPI_HOST_DEVICE void sample( double a_energy, Sampling::Input &a_input, RNG && a_rng ) const ;
template <typename RNG>
LUPI_HOST_DEVICE double angleBiasing( Reaction const *a_reaction, double a_temperature, double a_energy_in, double a_mu_lab,
RNG && a_rng, double &a_energy_out ) const ;
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
};
/*
============================================================
==================== IncoherentElasticTNSL ===================
============================================================
*/
class IncoherentElasticTNSL : public Distribution {
private:
double m_temperatureToMeV_K;
Functions::Function1d_d1 *m_DebyeWallerIntegral;
public:
LUPI_HOST_DEVICE IncoherentElasticTNSL( );
LUPI_HOST IncoherentElasticTNSL( GIDI::DoubleDifferentialCrossSection::n_ThermalNeutronScatteringLaw::IncoherentElastic const *a_incoherentElasticTNSL,
SetupInfo &a_setupInfo );
LUPI_HOST_DEVICE ~IncoherentElasticTNSL( ) {}
template <typename RNG>
LUPI_HOST_DEVICE void sample( double a_energy, Sampling::Input &a_input, RNG && a_rng ) const ;
template <typename RNG>
LUPI_HOST_DEVICE double angleBiasing( Reaction const *a_reaction, double a_temperature, double a_energy_in, double a_mu_lab,
RNG && a_rng, double &a_energy_out ) const ;
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
Functions::Function1d *DebyeWallerIntegral( ) { return( m_DebyeWallerIntegral ); }
Functions::Function1d const *DebyeWallerIntegral( ) const { return( m_DebyeWallerIntegral ); }
};
/*
============================================================
======================= Unspecified ========================
============================================================
*/
class Unspecified : public Distribution {
public:
LUPI_HOST_DEVICE Unspecified( );
LUPI_HOST Unspecified( GIDI::Distributions::Distribution const &a_distribution, SetupInfo &a_setupInfo );
LUPI_HOST_DEVICE ~Unspecified( );
template <typename RNG>
LUPI_HOST_DEVICE void sample( double a_X, Sampling::Input &a_input, RNG && a_rng ) const ;
template <typename RNG>
LUPI_HOST_DEVICE double angleBiasing( Reaction const *a_reaction, double a_temperature, double a_energy_in, double a_mu_lab,
RNG && a_rng, double &a_energy_out ) const ;
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
};
/*
============================================================
========================== Others ==========================
============================================================
*/
LUPI_HOST Distribution *parseGIDI( GIDI::Suite const &a_distribution, SetupInfo &a_setupInfo, Transporting::MC const &a_settings );
LUPI_HOST_DEVICE Type DistributionType( Distribution const *a_distribution );
}
}
#endif // End of MCGIDI_distributions_hpp_included
@@ -1,27 +0,0 @@
/*
# <<BEGIN-copyright>>
# <<END-copyright>>
*/
#ifndef MCGIDI_fromTOM_h_included
#define MCGIDI_fromTOM_h_included
#include <xDataTOM_importXML_private.h>
#include "MCGIDI.h"
#if defined __cplusplus
extern "C" {
namespace GIDI {
#endif
ptwXYPoints *MCGIDI_fromTOM_XYs_to_ptwXYPoints_linear( statusMessageReporting *smr, xDataTOM_XYs *XYs, enum ptwXY_interpolation_e interpolation );
int MCGIDI_fromTOM_pdfsOfXGivenW( statusMessageReporting *smr, xDataTOM_element *element, MCGIDI_pdfsOfXGivenW *dists, ptwXYPoints *norms,
char const *toUnits[3] );
int MCGIDI_fromTOM_pdfOfX( statusMessageReporting *smr, ptwXYPoints *pdfXY, MCGIDI_pdfOfX *dist, double *norm );
int MCGIDI_fromTOM_interpolation( statusMessageReporting *smr, xDataTOM_element *element, int index, enum ptwXY_interpolation_e *interpolation );
#if defined __cplusplus
}
}
#endif
#endif /* End of MCGIDI_fromTOM_h_included. */
@@ -0,0 +1,825 @@
/*
# <<BEGIN-copyright>>
# Copyright 2019, Lawrence Livermore National Security, LLC.
# This file is part of the gidiplus package (https://github.com/LLNL/gidiplus).
# gidiplus is licensed under the MIT license (see https://opensource.org/licenses/MIT).
# SPDX-License-Identifier: MIT
# <<END-copyright>>
*/
#ifndef MCGIDI_functions_hpp_included
#define MCGIDI_functions_hpp_included 1
#include <nf_utilities.h>
#include <ptwXY.h>
#include <LUPI_dataBuffer.hpp>
namespace MCGIDI {
enum class Interpolation { LINLIN, LINLOG, LOGLIN, LOGLOG, FLAT, OTHER };
enum class Function1dType { none, constant, XYs, polyomial, gridded, regions, branching, TerrellFissionNeutronMultiplicityModel };
enum class Function2dType { none, XYs };
enum class ProbabilityBase1dType { none, xs_pdf_cdf };
enum class ProbabilityBase2dType { none, XYs, regions, isotropic, discreteGamma, primaryGamma, recoil, NBodyPhaseSpace, evaporation,
generalEvaporation, simpleMaxwellianFission, Watt, weightedFunctionals };
enum class ProbabilityBase3dType { none, XYs };
namespace Functions {
/*
============================================================
====================== FunctionBase ========================
============================================================
*/
class FunctionBase {
private:
int m_dimension;
double m_domainMin;
double m_domainMax;
Interpolation m_interpolation;
double m_outerDomainValue;
public:
LUPI_HOST_DEVICE FunctionBase( );
LUPI_HOST FunctionBase( GIDI::Functions::FunctionForm const &a_function );
LUPI_HOST_DEVICE FunctionBase( int a_dimension, double a_domainMin, double a_domainMax, Interpolation a_interpolation, double a_outerDomainValue = 0 );
LUPI_HOST_DEVICE virtual ~FunctionBase( ) = 0;
LUPI_HOST_DEVICE Interpolation interpolation( ) const { return( m_interpolation ); }
LUPI_HOST_DEVICE double domainMin( ) const { return( m_domainMin ); }
LUPI_HOST_DEVICE double domainMax( ) const { return( m_domainMax ); }
LUPI_HOST_DEVICE double outerDomainValue( ) const { return( m_outerDomainValue ); }
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
};
/*
============================================================
======================== Function1d ========================
============================================================
*/
class Function1d : public FunctionBase {
protected:
Function1dType m_type;
public:
LUPI_HOST_DEVICE Function1d( );
LUPI_HOST_DEVICE Function1d( double a_domainMin, double a_domainMax, Interpolation a_interpolation, double a_outerDomainValue = 0 );
LUPI_HOST_DEVICE ~Function1d( );
LUPI_HOST_DEVICE Function1dType type( ) const { return( m_type ); }
LUPI_HOST_DEVICE String typeString( ) const ;
template <typename RNG>
LUPI_HOST_DEVICE MCGIDI_VIRTUAL_FUNCTION int sampleBoundingInteger( double a_x1, RNG && a_rng ) const ;
LUPI_HOST_DEVICE MCGIDI_VIRTUAL_FUNCTION double evaluate( double a_x1 ) const MCGIDI_TRUE_VIRTUAL;
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
};
/*
============================================================
====================== Function1d_d1 =======================
============================================================
*/
class Function1d_d1 : public Function1d {
public:
LUPI_HOST_DEVICE Function1d_d1( ) :
Function1d( ) { }
LUPI_HOST_DEVICE Function1d_d1( double a_domainMin, double a_domainMax, Interpolation a_interpolation, double a_outerDomainValue = 0 ) :
Function1d( a_domainMin, a_domainMax, a_interpolation, a_outerDomainValue ) { }
LUPI_HOST_DEVICE double evaluate( double a_x1 ) const ;
};
/*
============================================================
====================== Function1d_d2 =======================
============================================================
*/
class Function1d_d2 : public Function1d_d1 {
public:
LUPI_HOST_DEVICE Function1d_d2( ) :
Function1d_d1( ) { }
LUPI_HOST_DEVICE Function1d_d2( double a_domainMin, double a_domainMax, Interpolation a_interpolation, double a_outerDomainValue = 0 ) :
Function1d_d1( a_domainMin, a_domainMax, a_interpolation, a_outerDomainValue ) { }
LUPI_HOST_DEVICE double evaluate( double a_x1 ) const ;
};
/*
============================================================
======================== Constant1d ========================
============================================================
*/
class Constant1d : public Function1d_d2 {
private:
double m_value;
public:
LUPI_HOST_DEVICE Constant1d( );
LUPI_HOST_DEVICE Constant1d( double a_domainMin, double a_domainMax, double a_value, double a_outerDomainValue = 0 );
LUPI_HOST Constant1d( GIDI::Functions::Constant1d const &a_constant1d );
LUPI_HOST_DEVICE ~Constant1d( );
LUPI_HOST_DEVICE double evaluate( LUPI_maybeUnused double a_x1 ) const { return( m_value ); }
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
};
/*
============================================================
=========================== XYs1d ==========================
============================================================
*/
class XYs1d : public Function1d_d2 {
private:
Vector<double> m_Xs;
Vector<double> m_Ys;
public:
LUPI_HOST_DEVICE XYs1d( );
LUPI_HOST XYs1d( Interpolation a_interpolation, Vector<double> a_Xs, Vector<double> a_Ys, double a_outerDomainValue = 0 );
LUPI_HOST XYs1d( GIDI::Functions::XYs1d const &a_XYs1d );
LUPI_HOST_DEVICE ~XYs1d( );
LUPI_HOST_DEVICE double evaluate( double a_x1 ) const ;
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
};
/*
============================================================
======================= Polynomial1d =======================
============================================================
*/
class Polynomial1d : public Function1d_d2 {
private:
Vector<double> m_coefficients;
Vector<double> m_coefficientsReversed;
public:
LUPI_HOST_DEVICE Polynomial1d( );
LUPI_HOST Polynomial1d( double a_domainMin, double a_domainMax, Vector<double> const &a_coefficients, double a_outerDomainValue = 0 );
LUPI_HOST Polynomial1d( GIDI::Functions::Polynomial1d const &a_polynomial1d );
LUPI_HOST_DEVICE ~Polynomial1d( );
LUPI_HOST_DEVICE Vector<double> const &coefficients( ) const { return( m_coefficients ); }
LUPI_HOST_DEVICE double evaluate( double a_x1 ) const ;
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
};
/*
============================================================
========================= Gridded1d ========================
============================================================
*/
class Gridded1d : public Function1d_d2 {
private:
Vector<double> m_grid;
Vector<double> m_data;
public:
LUPI_HOST_DEVICE Gridded1d( );
LUPI_HOST Gridded1d( GIDI::Functions::Gridded1d const &a_gridded1d );
LUPI_HOST_DEVICE ~Gridded1d( );
LUPI_HOST_DEVICE double evaluate( double a_x1 ) const ;
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
};
/*
============================================================
========================= Regions1d ========================
============================================================
*/
class Regions1d : public Function1d_d1 {
private:
Vector<double> m_Xs;
Vector<Function1d_d2 *> m_functions1d;
public:
LUPI_HOST_DEVICE Regions1d( );
LUPI_HOST Regions1d( GIDI::Functions::Regions1d const &a_regions1d );
LUPI_HOST_DEVICE ~Regions1d( );
LUPI_HOST_DEVICE void append( Function1d_d2 *a_function1d );
LUPI_HOST_DEVICE double evaluate( double a_x1 ) const ;
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
};
/*
============================================================
======================== Branching1d =======================
============================================================
*/
class Branching1d : public Function1d_d2 {
private:
int m_initialStateIndex;
public:
LUPI_HOST_DEVICE Branching1d( );
LUPI_HOST Branching1d( SetupInfo &a_setupInfo, GIDI::Functions::Branching1d const &a_branching1d );
LUPI_HOST_DEVICE ~Branching1d( );
LUPI_HOST_DEVICE int initialStateIndex( ) const { return( m_initialStateIndex ); }
LUPI_HOST_DEVICE double evaluate( double a_x1 ) const ;
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
};
/*
============================================================
========== TerrellFissionNeutronMultiplicityModel ==========
============================================================
*/
class TerrellFissionNeutronMultiplicityModel : public Function1d {
private:
double m_width;
Function1d_d1 *m_multiplicity;
public:
LUPI_HOST_DEVICE TerrellFissionNeutronMultiplicityModel( );
LUPI_HOST TerrellFissionNeutronMultiplicityModel( double a_width, Function1d_d1 *a_multiplicity );
LUPI_HOST_DEVICE ~TerrellFissionNeutronMultiplicityModel( );
template <typename RNG>
LUPI_HOST_DEVICE int sampleBoundingInteger( double a_energy, RNG && a_rng ) const ;
LUPI_HOST_DEVICE double evaluate( double a_energy ) const ;
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
};
/*
============================================================
======================== Function2d ========================
============================================================
*/
class Function2d : public FunctionBase {
protected:
Function2dType m_type;
public:
LUPI_HOST_DEVICE Function2d( );
LUPI_HOST Function2d( double a_domainMin, double a_domainMax, Interpolation a_interpolation, double a_outerDomainValue = 0 );
LUPI_HOST_DEVICE ~Function2d( );
LUPI_HOST_DEVICE Function2dType type( ) const { return m_type; }
LUPI_HOST_DEVICE String typeString( ) const ;
LUPI_HOST_DEVICE MCGIDI_VIRTUAL_FUNCTION double evaluate( double a_x2, double a_x1 ) const MCGIDI_TRUE_VIRTUAL;
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
};
/*
============================================================
=========================== XYs2d ==========================
============================================================
*/
class XYs2d : public Function2d {
private:
Vector<double> m_Xs;
Vector<Function1d_d1 *> m_functions1d;
public:
LUPI_HOST_DEVICE XYs2d( );
LUPI_HOST XYs2d( GIDI::Functions::XYs2d const &a_XYs2d );
LUPI_HOST_DEVICE ~XYs2d( );
LUPI_HOST_DEVICE double evaluate( double a_x2, double a_x1 ) const ;
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
};
/*
============================================================
========================== others ==========================
============================================================
*/
LUPI_HOST Function1d *parseMultiplicityFunction1d( SetupInfo &a_setupInfo, Transporting::MC const &a_settings, GIDI::Suite const &a_suite );
LUPI_HOST Function1d_d1 *parseFunction1d_d1( Transporting::MC const &a_settings, GIDI::Suite const &a_suite );
LUPI_HOST Function1d_d1 *parseFunction1d_d1( GIDI::Functions::Function1dForm const *form1d );
LUPI_HOST Function1d_d2 *parseFunction1d_d2( GIDI::Functions::Function1dForm const *form1d );
LUPI_HOST Function2d *parseFunction2d( Transporting::MC const &a_settings, GIDI::Suite const &a_suite );
LUPI_HOST Function2d *parseFunction2d( GIDI::Functions::Function2dForm const *form2d );
} // End of namespace Functions.
/*
============================================================
============================================================
================== namespace Probabilities ==================
============================================================
============================================================
*/
namespace Probabilities {
/*
============================================================
===================== ProbabilityBase ======================
============================================================
*/
class ProbabilityBase : public Functions::FunctionBase {
protected:
Vector<double> m_Xs;
public:
LUPI_HOST_DEVICE ProbabilityBase( );
LUPI_HOST ProbabilityBase( GIDI::Functions::FunctionForm const &a_probabilty );
LUPI_HOST ProbabilityBase( GIDI::Functions::FunctionForm const &a_probabilty, Vector<double> const &a_Xs );
LUPI_HOST_DEVICE ~ProbabilityBase( );
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
};
/*
============================================================
===================== ProbabilityBase1d ====================
============================================================
*/
class ProbabilityBase1d : public ProbabilityBase {
protected:
ProbabilityBase1dType m_type;
public:
LUPI_HOST_DEVICE ProbabilityBase1d( );
LUPI_HOST ProbabilityBase1d( GIDI::Functions::FunctionForm const &a_probabilty, Vector<double> const &a_Xs );
LUPI_HOST_DEVICE ~ProbabilityBase1d( );
LUPI_HOST_DEVICE ProbabilityBase1dType type( ) const { return m_type; }
LUPI_HOST_DEVICE String typeString( ) const ;
LUPI_HOST_DEVICE MCGIDI_VIRTUAL_FUNCTION double evaluate( double a_x1 ) const MCGIDI_TRUE_VIRTUAL;
template <typename RNG>
LUPI_HOST_DEVICE MCGIDI_VIRTUAL_FUNCTION double sample( double a_rngValue, RNG && a_rng ) const MCGIDI_TRUE_VIRTUAL;
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
};
/*
============================================================
======================= Xs_pdf_cdf1d =======================
============================================================
*/
class Xs_pdf_cdf1d : public ProbabilityBase1d {
private:
Vector<double> m_pdf;
Vector<double> m_cdf;
public:
LUPI_HOST_DEVICE Xs_pdf_cdf1d( );
LUPI_HOST Xs_pdf_cdf1d( GIDI::Functions::Xs_pdf_cdf1d const &a_xs_pdf_cdf1d );
LUPI_HOST_DEVICE ~Xs_pdf_cdf1d( );
LUPI_HOST_DEVICE double evaluate( double a_x1 ) const ;
template <typename RNG>
LUPI_HOST_DEVICE double sample( double a_rngValue, RNG && a_rng ) const ;
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
};
/*
============================================================
===================== ProbabilityBase2d ====================
============================================================
*/
class ProbabilityBase2d : public ProbabilityBase {
protected:
ProbabilityBase2dType m_type;
public:
LUPI_HOST_DEVICE ProbabilityBase2d( );
LUPI_HOST ProbabilityBase2d( GIDI::Functions::FunctionForm const &a_probabilty );
LUPI_HOST ProbabilityBase2d( GIDI::Functions::FunctionForm const &a_probabilty, Vector<double> const &a_Xs );
LUPI_HOST_DEVICE ~ProbabilityBase2d( );
LUPI_HOST_DEVICE ProbabilityBase2dType type( ) const { return m_type; }
LUPI_HOST_DEVICE String typeString( ) const ;
LUPI_HOST_DEVICE MCGIDI_VIRTUAL_FUNCTION double evaluate( double a_x2, double a_x1 ) const MCGIDI_TRUE_VIRTUAL;
template <typename RNG>
LUPI_HOST_DEVICE MCGIDI_VIRTUAL_FUNCTION double sample( double a_x2, double a_rngValue, RNG && a_rng ) const MCGIDI_TRUE_VIRTUAL;
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
};
/*
============================================================
=================== ProbabilityBase2d_d1 ===================
============================================================
*/
class ProbabilityBase2d_d1 : public ProbabilityBase2d {
public:
LUPI_HOST_DEVICE ProbabilityBase2d_d1( ) :
ProbabilityBase2d( ) { }
LUPI_HOST ProbabilityBase2d_d1( GIDI::Functions::FunctionForm const &a_probabilty ) :
ProbabilityBase2d( a_probabilty ) { }
LUPI_HOST ProbabilityBase2d_d1( GIDI::Functions::FunctionForm const &a_probabilty, Vector<double> const &a_Xs ) :
ProbabilityBase2d( a_probabilty, a_Xs ) { }
LUPI_HOST_DEVICE double evaluate( double a_x2, double a_x1 ) const ;
template <typename RNG>
LUPI_HOST_DEVICE double sample( double a_x2, double a_rngValue, RNG && a_rng ) const ;
template <typename RNG>
LUPI_HOST_DEVICE double sample2dOf3d( double a_x2, double a_rngValue, RNG && a_rng, double *a_x1_1, double *a_x1_2 ) const ;
};
/*
============================================================
=================== ProbabilityBase2d_d2 ===================
============================================================
*/
class ProbabilityBase2d_d2 : public ProbabilityBase2d_d1 {
public:
LUPI_HOST_DEVICE ProbabilityBase2d_d2( ) :
ProbabilityBase2d_d1( ) { }
LUPI_HOST ProbabilityBase2d_d2( GIDI::Functions::FunctionForm const &a_probabilty ) :
ProbabilityBase2d_d1( a_probabilty ) { }
LUPI_HOST ProbabilityBase2d_d2( GIDI::Functions::FunctionForm const &a_probabilty, Vector<double> const &a_Xs ) :
ProbabilityBase2d_d1( a_probabilty, a_Xs ) { }
LUPI_HOST_DEVICE double evaluate( double a_x2, double a_x1 ) const ;
template <typename RNG>
LUPI_HOST_DEVICE double sample( double a_x2, double a_rngValue, RNG && a_rng ) const ;
template <typename RNG>
LUPI_HOST_DEVICE double sample2dOf3d( double a_x2, double a_rngValue, RNG && a_rng, double *a_x1_1, double *a_x1_2 ) const ;
};
/*
============================================================
========================== XYs2d ===========================
============================================================
*/
class XYs2d : public ProbabilityBase2d_d2 {
private:
Vector<ProbabilityBase1d *> m_probabilities;
public:
LUPI_HOST_DEVICE XYs2d( );
LUPI_HOST XYs2d( GIDI::Functions::XYs2d const &a_XYs2d );
LUPI_HOST_DEVICE ~XYs2d( );
LUPI_HOST_DEVICE double evaluate( double a_x2, double a_x1 ) const ;
template <typename RNG>
LUPI_HOST_DEVICE double sample( double a_x2, double a_rngValue, RNG && a_rng ) const ;
template <typename RNG>
LUPI_HOST_DEVICE double sample2dOf3d( double a_x2, double a_rngValue, RNG && a_rng, double *a_x1_1, double *a_x1_2 ) const ;
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
};
/*
============================================================
======================== Regions2d =========================
============================================================
*/
class Regions2d : public ProbabilityBase2d_d1 {
private:
Vector<ProbabilityBase2d_d2 *> m_probabilities;
public:
LUPI_HOST_DEVICE Regions2d( );
LUPI_HOST Regions2d( GIDI::Functions::Regions2d const &a_regions2d );
LUPI_HOST_DEVICE ~Regions2d( );
LUPI_HOST_DEVICE double evaluate( double a_x2, double a_x1 ) const ;
template <typename RNG>
LUPI_HOST_DEVICE double sample( double a_x2, double a_rngValue, RNG && a_rng ) const ;
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
};
/*
============================================================
======================== Isotropic2d =======================
============================================================
*/
class Isotropic2d : public ProbabilityBase2d_d2 {
public:
LUPI_HOST_DEVICE Isotropic2d( );
LUPI_HOST Isotropic2d( GIDI::Functions::Isotropic2d const &a_isotropic2d );
LUPI_HOST_DEVICE ~Isotropic2d( );
LUPI_HOST_DEVICE double evaluate( LUPI_maybeUnused double a_x2, LUPI_maybeUnused double a_x1 ) const { return( 0.5 ); }
template <typename RNG>
LUPI_HOST_DEVICE double sample( LUPI_maybeUnused double a_x2, double a_rngValue, LUPI_maybeUnused RNG && a_rng ) const { return( 1. - 2. * a_rngValue ); }
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode ) {
ProbabilityBase2d::serialize( a_buffer, a_mode ); }
};
/*
============================================================
====================== DiscreteGamma2d =====================
============================================================
*/
class DiscreteGamma2d : public ProbabilityBase2d_d2 {
private:
double m_value;
public:
LUPI_HOST_DEVICE DiscreteGamma2d( );
LUPI_HOST DiscreteGamma2d( GIDI::Functions::DiscreteGamma2d const &a_discreteGamma2d );
LUPI_HOST_DEVICE ~DiscreteGamma2d( );
LUPI_HOST_DEVICE double evaluate( LUPI_maybeUnused double a_x2, LUPI_maybeUnused double a_x1 ) const { return( m_value ); } // FIXME This is wrong, should be something like 1 when domainMin <= a_x1 <= domainMax ), I think. I.e., should be a probability.
template <typename RNG>
LUPI_HOST_DEVICE double sample( LUPI_maybeUnused double a_x2, LUPI_maybeUnused double a_rngValue, LUPI_maybeUnused RNG && a_rng ) const { return( m_value ); }
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
};
/*
============================================================
====================== PrimaryGamma2d =====================
============================================================
*/
class PrimaryGamma2d : public ProbabilityBase2d_d2 {
private:
double m_primaryEnergy;
double m_massFactor;
String m_finalState;
int m_initialStateIndex;
public:
LUPI_HOST_DEVICE PrimaryGamma2d( );
LUPI_HOST PrimaryGamma2d( GIDI::Functions::PrimaryGamma2d const &a_primaryGamma2d, SetupInfo *a_setupInfo );
LUPI_HOST_DEVICE ~PrimaryGamma2d( );
double primaryEnergy( ) const { return( m_primaryEnergy ); } /**< Returns the value of the *m_primaryEnergy* member. */
double massFactor( ) const { return( m_massFactor ); } /**< Returns the value of the *m_massFactor* member. */
String const &finalState( ) const { return( m_finalState ); } /**< Returns a const reference to the *m_finalState* member. */
int initialStateIndex( ) const { return( m_initialStateIndex ); } /**< Returns the value of the *m_initialStateIndex* member. */
LUPI_HOST_DEVICE double evaluate( double a_x2, double a_x1 ) const ;
template <typename RNG>
LUPI_HOST_DEVICE double sample( double a_x2, LUPI_maybeUnused double a_rngValue, LUPI_maybeUnused RNG && a_rng ) const { return( m_primaryEnergy + a_x2 * m_massFactor ); }
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
};
/*
============================================================
========================= Recoil2d =========================
============================================================
*/
class Recoil2d: public ProbabilityBase2d_d2 {
private:
String m_xlink;
public:
LUPI_HOST_DEVICE Recoil2d( );
LUPI_HOST Recoil2d( GIDI::Functions::Recoil2d const &a_recoil2d );
LUPI_HOST_DEVICE ~Recoil2d( );
LUPI_HOST_DEVICE double evaluate( double a_x2, double a_x1 ) const ;
template <typename RNG>
LUPI_HOST_DEVICE double sample( double a_x2, double a_rngValue, RNG && a_rng ) const ;
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
};
/*
============================================================
==================== NBodyPhaseSpace2d =====================
============================================================
*/
class NBodyPhaseSpace2d : public ProbabilityBase2d_d2 {
private:
int m_numberOfProducts;
double m_mass;
double m_energy_in_COMFactor;
double m_massFactor;
double m_Q;
ProbabilityBase1d *m_dist;
public:
LUPI_HOST_DEVICE NBodyPhaseSpace2d( );
LUPI_HOST NBodyPhaseSpace2d( GIDI::Functions::NBodyPhaseSpace2d const &a_NBodyPhaseSpace2d, SetupInfo *a_setupInfo );
LUPI_HOST_DEVICE ~NBodyPhaseSpace2d( );
LUPI_HOST_DEVICE double evaluate( double a_x2, double a_x1 ) const ;
template <typename RNG>
LUPI_HOST_DEVICE double sample( double a_x2, double a_rngValue, RNG && a_rng ) const ;
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
};
/*
============================================================
====================== Evaporation2d =======================
============================================================
*/
class Evaporation2d: public ProbabilityBase2d_d2 {
private:
double m_U;
Functions::Function1d_d1 *m_theta;
public:
LUPI_HOST_DEVICE Evaporation2d( );
LUPI_HOST Evaporation2d( GIDI::Functions::Evaporation2d const &a_generalEvaporation2d );
LUPI_HOST_DEVICE ~Evaporation2d( );
LUPI_HOST_DEVICE double evaluate( double a_x2, double a_x1 ) const ;
template <typename RNG>
LUPI_HOST_DEVICE double sample( double a_x2, double a_rngValue, RNG && a_rng ) const ;
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
};
/*
============================================================
=================== GeneralEvaporation2d ===================
============================================================
*/
class GeneralEvaporation2d: public ProbabilityBase2d_d2 {
private:
Functions::Function1d_d1 *m_theta;
ProbabilityBase1d *m_g;
public:
LUPI_HOST_DEVICE GeneralEvaporation2d( );
LUPI_HOST GeneralEvaporation2d( GIDI::Functions::GeneralEvaporation2d const &a_generalEvaporation2d );
LUPI_HOST_DEVICE ~GeneralEvaporation2d( );
LUPI_HOST_DEVICE double evaluate( double a_x2, double a_x1 ) const ;
template <typename RNG>
LUPI_HOST_DEVICE double sample( double a_x2, double a_rngValue, RNG && a_rng ) const ;
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
};
/*
============================================================
================= SimpleMaxwellianFission2d ================
============================================================
*/
class SimpleMaxwellianFission2d: public ProbabilityBase2d_d2 {
private:
double m_U;
Functions::Function1d_d1 *m_theta;
public:
LUPI_HOST_DEVICE SimpleMaxwellianFission2d( );
LUPI_HOST SimpleMaxwellianFission2d( GIDI::Functions::SimpleMaxwellianFission2d const &a_simpleMaxwellianFission2d );
LUPI_HOST_DEVICE ~SimpleMaxwellianFission2d( );
LUPI_HOST_DEVICE double evaluate( double a_x2, double a_x1 ) const ;
template <typename RNG>
LUPI_HOST_DEVICE double sample( double a_x2, double a_rngValue, RNG && a_rng ) const ;
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
};
/*
============================================================
========================== Watt2d ==========================
============================================================
*/
class Watt2d : public ProbabilityBase2d_d2 {
private:
double m_U;
Functions::Function1d_d1 *m_a;
Functions::Function1d_d1 *m_b;
public:
LUPI_HOST_DEVICE Watt2d( );
LUPI_HOST Watt2d( GIDI::Functions::Watt2d const &a_Watt2d );
LUPI_HOST_DEVICE ~Watt2d( );
LUPI_HOST_DEVICE double evaluate( double a_x2, double a_x1 ) const ;
template <typename RNG>
LUPI_HOST_DEVICE double sample( double a_x2, double a_rngValue, RNG && a_rng ) const ;
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
};
/*
============================================================
=================== WeightedFunctionals2d ==================
============================================================
*/
class WeightedFunctionals2d: public ProbabilityBase2d {
private:
Vector<Functions::Function1d_d1 *> m_weight;
Vector<ProbabilityBase2d_d1 *> m_energy;
public:
LUPI_HOST_DEVICE WeightedFunctionals2d( );
LUPI_HOST WeightedFunctionals2d( GIDI::Functions::WeightedFunctionals2d const &a_weightedFunctionals2d );
LUPI_HOST_DEVICE ~WeightedFunctionals2d( );
LUPI_HOST_DEVICE double evaluate( double a_x2, double a_x1 ) const ;
template <typename RNG>
LUPI_HOST_DEVICE double sample( double a_x2, double a_rngValue, RNG && a_rng ) const ;
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
};
/*
============================================================
===================== ProbabilityBase3d ====================
============================================================
*/
class ProbabilityBase3d : public ProbabilityBase {
protected:
ProbabilityBase3dType m_type;
public:
LUPI_HOST_DEVICE ProbabilityBase3d( );
LUPI_HOST ProbabilityBase3d( GIDI::Functions::FunctionForm const &a_probabilty, Vector<double> const &a_Xs );
LUPI_HOST_DEVICE ~ProbabilityBase3d( );
LUPI_HOST_DEVICE ProbabilityBase3dType type( ) const { return m_type; }
LUPI_HOST_DEVICE String typeString( ) const ;
LUPI_HOST_DEVICE MCGIDI_VIRTUAL_FUNCTION double evaluate( double a_x3, double a_x2, double a_x1 ) const MCGIDI_TRUE_VIRTUAL;
template <typename RNG>
LUPI_HOST_DEVICE MCGIDI_VIRTUAL_FUNCTION double sample( double a_x3, double a_x2_1, double a_x2_2, double a_rngValue, RNG && a_rng ) const MCGIDI_TRUE_VIRTUAL;
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
};
/*
============================================================
========================== XYs3d ===========================
============================================================
*/
class XYs3d : public ProbabilityBase3d {
private:
Vector<ProbabilityBase2d_d1 *> m_probabilities;
public:
LUPI_HOST_DEVICE XYs3d( );
LUPI_HOST XYs3d( GIDI::Functions::XYs3d const &a_XYs3d );
LUPI_HOST_DEVICE ~XYs3d( );
LUPI_HOST_DEVICE double evaluate( double a_x3, double a_x2, double a_x1 ) const ;
template <typename RNG>
LUPI_HOST_DEVICE double sample( double a_x3, double a_x2_1, double a_x2_2, double a_rngValue, RNG && a_rng ) const ;
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
};
/*
============================================================
========================== others ==========================
============================================================
*/
LUPI_HOST ProbabilityBase1d *parseProbability1d( Transporting::MC const &a_settings, GIDI::Suite const &a_suite );
LUPI_HOST ProbabilityBase1d *parseProbability1d( GIDI::Functions::Function1dForm const *form1d );
LUPI_HOST ProbabilityBase2d *parseProbability2d( Transporting::MC const &a_settings, GIDI::Suite const &a_suite, SetupInfo *a_setupInfo );
LUPI_HOST ProbabilityBase2d *parseProbability2d( GIDI::Functions::Function2dForm const *form2d, SetupInfo *a_setupInfo );
LUPI_HOST ProbabilityBase2d_d1 *parseProbability2d_d1( GIDI::Functions::Function2dForm const *form2d, SetupInfo *a_setupInfo );
LUPI_HOST ProbabilityBase2d_d2 *parseProbability2d_d2( GIDI::Functions::Function2dForm const *form2d, SetupInfo *a_setupInfo );
LUPI_HOST ProbabilityBase3d *parseProbability3d( Transporting::MC const &a_settings, GIDI::Suite const &a_suite );
LUPI_HOST ProbabilityBase3d *parseProbability3d( GIDI::Functions::Function3dForm const *form3d );
} // End of namespace Probabilities.
/*
============================================================
========================== others ==========================
============================================================
*/
LUPI_HOST_DEVICE Interpolation GIDI2MCGIDI_interpolation( ptwXY_interpolation a_interpolation );
LUPI_HOST_DEVICE Function1dType Function1dClass( Functions::Function1d *funct );
LUPI_HOST_DEVICE Functions::Function1d *serializeFunction1d( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode, Functions::Function1d *a_function1d );
LUPI_HOST_DEVICE Functions::Function1d_d1 *serializeFunction1d_d1( LUPI::DataBuffer &a_buffer,
LUPI::DataBuffer::Mode a_mode, Functions::Function1d_d1 *a_function1d );
LUPI_HOST_DEVICE Functions::Function1d_d2 *serializeFunction1d_d2( LUPI::DataBuffer &a_buffer,
LUPI::DataBuffer::Mode a_mode, Functions::Function1d_d2 *a_function1d );
LUPI_HOST_DEVICE Function2dType Function2dClass( Functions::Function2d *funct );
LUPI_HOST_DEVICE Functions::Function2d *serializeFunction2d( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode, Functions::Function2d *a_function2d );
LUPI_HOST_DEVICE ProbabilityBase1dType ProbabilityBase1dClass( Probabilities::ProbabilityBase1d *funct );
LUPI_HOST_DEVICE Probabilities::ProbabilityBase1d *serializeProbability1d( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode, Probabilities::ProbabilityBase1d *a_probability1d );
LUPI_HOST_DEVICE ProbabilityBase2dType ProbabilityBase2dClass( Probabilities::ProbabilityBase2d *funct );
LUPI_HOST_DEVICE Probabilities::ProbabilityBase2d *serializeProbability2d( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode,
Probabilities::ProbabilityBase2d *a_probability2d );
LUPI_HOST_DEVICE Probabilities::ProbabilityBase2d_d1 *serializeProbability2d_d1( LUPI::DataBuffer &a_buffer,
LUPI::DataBuffer::Mode a_mode, Probabilities::ProbabilityBase2d_d1 *a_probability2d );
LUPI_HOST_DEVICE Probabilities::ProbabilityBase2d_d2 *serializeProbability2d_d2( LUPI::DataBuffer &a_buffer,
LUPI::DataBuffer::Mode a_mode, Probabilities::ProbabilityBase2d_d2 *a_probability2d );
LUPI_HOST_DEVICE ProbabilityBase3dType ProbabilityBase3dClass( Probabilities::ProbabilityBase3d *funct );
LUPI_HOST_DEVICE Probabilities::ProbabilityBase3d *serializeProbability3d( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode, Probabilities::ProbabilityBase3d *a_probability3d );
} // End of namespace MCGIDI.
#endif // End of MCGIDI_functions_hpp_included
File diff suppressed because it is too large Load Diff
@@ -1,74 +0,0 @@
/*
# <<BEGIN-copyright>>
# <<END-copyright>>
*/
#ifndef MCGIDI_map_h_included
#define MCGIDI_map_h_included
#include <statusMessageReporting.h>
#if defined __cplusplus
extern "C" {
namespace GIDI {
#endif
enum MCGIDI_map_status { MCGIDI_map_status_Ok, MCGIDI_map_status_memory, MCGIDI_map_status_mapParsing,
MCGIDI_map_status_UnknownType };
enum MCGIDI_mapEntry_type { MCGIDI_mapEntry_type_target, MCGIDI_mapEntry_type_path };
typedef struct MCGIDI_map_s MCGIDI_map;
typedef struct MCGIDI_mapEntry_s MCGIDI_mapEntry;
typedef struct MCGIDI_map_smr_s MCGIDI_map_smr;
struct MCGIDI_map_smr_s {
smr_userInterface smrUserInterface;
MCGIDI_map *map;
};
struct MCGIDI_mapEntry_s {
MCGIDI_mapEntry *next;
enum MCGIDI_mapEntry_type type;
MCGIDI_map *parent;
char *schema;
char *path;
char *evaluation;
char *projectile;
char *targetName;
int globalPoPsIndexProjectile, globalPoPsIndexTarget;
MCGIDI_map *map;
};
struct MCGIDI_map_s {
enum MCGIDI_map_status status;
MCGIDI_map_smr smrUserInterface;
char *path;
char *mapFileName;
int numberOfEntries;
MCGIDI_mapEntry *mapEntries;
};
MCGIDI_map *MCGIDI_map_new( statusMessageReporting *smr );
int MCGIDI_map_initialize( statusMessageReporting *smr, MCGIDI_map *map );
MCGIDI_map *MCGIDI_map_readFile( statusMessageReporting *smr, const char *basePath, const char *mapFileName );
void *MCGIDI_map_free( statusMessageReporting *smr, MCGIDI_map *map );
void MCGIDI_map_release( statusMessageReporting *smr, MCGIDI_map *map );
MCGIDI_mapEntry *MCGIDI_map_getFirstEntry( MCGIDI_map *map );
MCGIDI_mapEntry *MCGIDI_map_getNextEntry( MCGIDI_mapEntry *entry );
int MCGIDI_map_addTarget( statusMessageReporting *smr, MCGIDI_map *map, const char *method, const char *path, const char *evaluation, const char *projectile, const char *targetName );
int MCGIDI_map_addPath( statusMessageReporting *smr, MCGIDI_map *map, const char *path );
char *MCGIDI_map_findTargetViaPoPIDs( statusMessageReporting *smr, MCGIDI_map *map, const char *evaluation, int projectile_PoPID, int target_PoPID );
char *MCGIDI_map_findTarget( statusMessageReporting *smr, MCGIDI_map *map, const char *evaluation, const char *projectile, const char *targetName );
MCGIDI_map *MCGIDI_map_findAllOfTargetViaPoPIDs( statusMessageReporting *smr, MCGIDI_map *map, int projectile_PoPID, int target_PoPID );
MCGIDI_map *MCGIDI_map_findAllOfTarget( statusMessageReporting *smr, MCGIDI_map *map, const char *projectile, const char *targetName );
char *MCGIDI_map_getFullPath( statusMessageReporting *smr, MCGIDI_map *map, const char *endPath );
char *MCGIDI_map_getTargetsFullPath( statusMessageReporting *smr, MCGIDI_mapEntry *target );
int MCGIDI_map_walkTree( statusMessageReporting *smr, MCGIDI_map *map, int (*handler)( MCGIDI_mapEntry *entry, int level, void *userData), void *userData );
char *MCGIDI_map_toXMLString( statusMessageReporting *smr, MCGIDI_map *map );
void MCGIDI_map_simpleWrite( FILE *f, MCGIDI_map *map );
#if defined __cplusplus
}
}
#endif
#endif /* End of MCGIDI_map_h_included. */
@@ -1,20 +0,0 @@
/*
# <<BEGIN-copyright>>
# <<END-copyright>>
*/
#ifndef MCGIDI_mass_h_included
#define MCGIDI_mass_h_included
#if defined __cplusplus
extern "C" {
namespace GIDI {
#endif
double MCGIDI_particleMass_AMU( statusMessageReporting *smr, const char *name );
#if defined __cplusplus
}
}
#endif
#endif /* End of MCGIDI_mass_h_included. */
@@ -1,47 +0,0 @@
/*
# <<BEGIN-copyright>>
# <<END-copyright>>
*/
#ifndef MCGIDI_misc_h_included
#define MCGIDI_misc_h_included
#include <statusMessageReporting.h>
#include <xDataTOM_importXML_private.h>
#include "MCGIDI_private.h"
#if defined __cplusplus
extern "C" {
namespace GIDI {
#endif
char const *MCGIDI_misc_pointerToTOMAttributeIfAllOk( statusMessageReporting *smr, char const *path, int required,
xDataTOM_attributionList *attributes, char const *name, char const *file, int line );
char const *MCGIDI_misc_pointerToAttributeIfAllOk( statusMessageReporting *smr, xDataXML_element *element, char const *path, int required,
xDataTOM_attributionList *attributes, char const *name, char const *file, int line );
int MCGIDI_misc_setMessageError_Element( statusMessageReporting *smr, void *userInterface, xDataXML_element *element, char const *file, int line, int code,
char const *fmt, ... );
char *MCGIDI_misc_getAbsPath( statusMessageReporting *smr, char const *fileName );
int MCGIDI_misc_copyXMLAttributesToTOM( statusMessageReporting *smr, xDataTOM_attributionList *TOM, xDataXML_attributionList *XML );
#define MCGIDI_misc_pointerToTOMAttributeIfAllOk2( smr, required, attributes, name ) \
MCGIDI_misc_pointerToTOMAttributeIfAllOk( smr, NULL, required, attributes, name, __FILE__, __LINE__ )
#define MCGIDI_misc_pointerToTOMAttributeIfAllOk3( smr, path, required, attributes, name ) \
MCGIDI_misc_pointerToTOMAttributeIfAllOk( smr, path, required, attributes, name, __FILE__, __LINE__ )
#define MCGIDI_misc_pointerToAttributeIfAllOk2( smr, element, required, attributes, name ) \
MCGIDI_misc_pointerToAttributeIfAllOk( smr, element, NULL, required, attributes, name, __FILE__, __LINE__ )
#define MCGIDI_misc_pointerToAttributeIfAllOk3( smr, path, required, attributes, name ) \
MCGIDI_misc_pointerToAttributeIfAllOk( smr, NULL, path, required, attributes, name, __FILE__, __LINE__ )
enum xDataTOM_frame MCGIDI_misc_getProductFrame( statusMessageReporting *smr, xDataTOM_element *frameElement );
double MCGIDI_misc_getUnitConversionFactor( statusMessageReporting *smr, char const *fromUnit, char const *toUnit );
ptwXYPoints *MCGIDI_misc_dataFromXYs2ptwXYPointsInUnitsOf( statusMessageReporting *smr, xDataTOM_XYs *XYs,
ptwXY_interpolation interpolation, char const *units[2] );
ptwXYPoints *MCGIDI_misc_dataFromElement2ptwXYPointsInUnitsOf( statusMessageReporting *smr, xDataTOM_element *linear, char const *toUnits[2] );
#if defined __cplusplus
}
}
#endif
#endif /* End of MCGIDI_misc_h_included. */
@@ -1,20 +0,0 @@
/*
# <<BEGIN-copyright>>
# <<END-copyright>>
*/
#ifndef MCGIDI_private_h_included
#define MCGIDI_private_h_included
#if defined __cplusplus
extern "C" {
namespace GIDI {
#endif
#define MCGIDI_token_productFrame "productFrame"
#if defined __cplusplus
}
}
#endif
#endif /* End of MCGIDI_private_h_included. */
@@ -0,0 +1,305 @@
/*
# <<BEGIN-copyright>>
# Copyright 2019, Lawrence Livermore National Security, LLC.
# This file is part of the gidiplus package (https://github.com/LLNL/gidiplus).
# gidiplus is licensed under the MIT license (see https://opensource.org/licenses/MIT).
# SPDX-License-Identifier: MIT
# <<END-copyright>>
*/
#ifndef MCGIDI_sampling_hpp_included
#define MCGIDI_sampling_hpp_included 1
#include <LUPI_declareMacro.hpp>
#include <MCGIDI_vector.hpp>
#include <MCGIDI_string.hpp>
namespace MCGIDI {
/*
============================================================
======================= DomainHash =========================
============================================================
*/
class DomainHash {
private:
int m_bins; /**< The number of bins for the hash. */
double m_domainMin; /**< The minimum domain value for the hash. */
double m_domainMax; /**< The maximum domain value for the hash. */
double m_u_domainMin; /**< The log of m_domainMin ). */
double m_u_domainMax; /**< The log of m_domainMax ). */
double m_inverse_du; /**< The value *m_bins* / ( *m_u_domainMax* - *m_u_domainMin* ). */
public:
LUPI_HOST_DEVICE DomainHash( );
LUPI_HOST_DEVICE DomainHash( int a_bins, double a_domainMin, double a_domainMax );
LUPI_HOST_DEVICE DomainHash( DomainHash const &a_domainHash );
LUPI_HOST_DEVICE int bins( ) const { return( m_bins ); } /**< Returns the value of the **m_bins**. */
LUPI_HOST_DEVICE double domainMin( ) const { return( m_domainMin ); } /**< Returns the value of the **m_domainMax**. */
LUPI_HOST_DEVICE double domainMax( ) const { return( m_domainMax ); } /**< Returns the value of the **m_domainMax**. */
LUPI_HOST_DEVICE double u_domainMin( ) const { return( m_u_domainMin ); } /**< Returns the value of the **m_u_domainMin**. */
LUPI_HOST_DEVICE double u_domainMax( ) const { return( m_u_domainMax ); } /**< Returns the value of the **m_u_domainMax**. */
LUPI_HOST_DEVICE double inverse_du( ) const { return( m_inverse_du ); } /**< Returns the value of the **m_inverse_du**. */
LUPI_HOST_DEVICE int index( double a_domain ) const ;
LUPI_HOST_DEVICE Vector<int> map( Vector<double> const &a_domainValues ) const ;
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
LUPI_HOST void print( bool a_printValues ) const ;
};
namespace Sampling {
enum class SampledType { firstTwoBody, secondTwoBody, uncorrelatedBody, unspecified, photon };
LUPI_HOST_DEVICE int evaluationForHashIndex( int a_hashIndex, Vector<int> const &a_hashIndices, double a_energy,
Vector<double> const &a_energies, double *a_energyFraction );
namespace Upscatter {
enum class Model { none, A, B, BSnLimits, DBRC };
/*
============================================================
===================== ModelDBRC_data =======================
============================================================
*/
class ModelDBRC_data {
public:
double m_neutronMass; /**< The mass of the neutron. */
double m_targetMass; /**< The mass of the target. */
Vector<double> m_energies; /**< The energy grid for the cross section. */
Vector<double> m_crossSections; /**< The cross sections corresponding to the energy grid. */
Vector<int> m_hashIndices; /**< The indicies for the energy hash function. */
MCGIDI::DomainHash m_domainHash; /**< The hash "function". */
public:
LUPI_HOST_DEVICE ModelDBRC_data( );
LUPI_HOST ModelDBRC_data( double a_neutronMass, double a_targetMass, Vector<double> const &a_energies, Vector<double> const &a_crossSections,
DomainHash const &a_domainHash );
LUPI_HOST_DEVICE ~ModelDBRC_data( );
LUPI_HOST_DEVICE double evaluate( double a_energy );
LUPI_HOST_DEVICE double targetThermalSpeed( double a_temperature );
LUPI_HOST_DEVICE double crossSectionMax( double a_energy, double a_targetThermalSpeed );
LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
};
LUPI_HOST_DEVICE ModelDBRC_data *serializeModelDBRC_data( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode, ModelDBRC_data *a_modelDBRC_data );
} // End of namespace Upscatter.
/*
============================================================
================ ClientRandomNumberGenerator ===============
============================================================
*/
class ClientRandomNumberGenerator {
private:
double (*m_generator)( void * ); /**< User supplied generator. */
void *m_state; /**< User supplied state. */
public:
LUPI_HOST_DEVICE ClientRandomNumberGenerator( double (*a_generator)( void * ), void *a_state );
LUPI_HOST_DEVICE double (*generator( ))( void * ) { return( m_generator ); }
LUPI_HOST_DEVICE void *state( ) { return( m_state ); }
LUPI_HOST_DEVICE double Double( ) { return( m_generator( m_state ) ); }
// The following are deprecated.
LUPI_HOST_DEVICE double (*rng( ))( void * ) { return( generator( ) ); }
LUPI_HOST_DEVICE void *rngState( ) { return( state( ) ); }
LUPI_HOST_DEVICE double dRng( ) { return( Double( ) ); }
};
/*
============================================================
=================== Client Code RNG Data ===================
============================================================
*/
class ClientCodeRNGData : public ClientRandomNumberGenerator {
public:
LUPI_HOST_DEVICE ClientCodeRNGData( double (*a_generator)( void * ), void *a_state );
};
/*
============================================================
=========================== Input ==========================
============================================================
*/
class Input {
private:
bool m_wantVelocity = true ; /**< See member m_isVelocity in class Product for meaning. This is user input. */
public:
double m_temperature = 0.0; /**< Set by user. */
Upscatter::Model m_upscatterModel = Upscatter::Model::none; /**< The upscatter model to use when sampling a target's velocity. */
// The rest of the members are set by MCGIDI methods.
// These five are used for upscatter model A.
bool m_dataInTargetFrame = false; /**< **true if the data are in the target's frame and **false** otherwise. */
double m_projectileBeta = 0.0; /**< The beta = speed / c of the projectile. */
double m_relativeMu = 0.0; /**< BRB */
double m_targetBeta = 0.0; /**< The beta = speed / c of the target. */
double m_relativeBeta = 0.0; /**< The beta = speed / c of the relative speed between the projectile and the target.*/
double m_projectileEnergy = 0.0; /**< The energy of the projectile. */
SampledType m_sampledType = SampledType::uncorrelatedBody; /**< BRB */
Reaction const *m_reaction = nullptr; /**< The current reaction whose products are being sampled. */
double m_projectileMass = 0.0; /**< The mass of the projectile. */
double m_targetMass = 0.0; /**< The mass of the target. */
GIDI::Frame m_frame = GIDI::Frame::lab; /**< The frame the product data are returned in. */
int m_numberOfDBRC_rejections = 0; /**< For the DBRC upscattering model, this is the number of rejections + 1 per product sample. */
double m_mu = 0.0; /**< The sampled mu = cos( theta ) for the product. */
double m_phi = 0.0; /**< The sampled phi for the product. */
double m_energyOut1 = 0.0; /**< The sampled energy of the product. */
double m_px_vx1 = 0.0; /**< Variable used for two-body sampling. */
double m_py_vy1 = 0.0; /**< Variable used for two-body sampling. */
double m_pz_vz1 = 0.0; /**< Variable used for two-body sampling. */
double m_energyOut2 = 0.0; /**< The sampled energy of the second product for a two-body interaction. */
double m_px_vx2 = 0.0; /**< Variable used for two-body sampling. */
double m_py_vy2 = 0.0; /**< Variable used for two-body sampling. */
double m_pz_vz2 = 0.0; /**< Variable used for two-body sampling. */
int m_delayedNeutronIndex = -1; /**< If the product is a delayed neutron, this is its index. */
double m_delayedNeutronDecayRate = 0.0; /**< If the product is a delayed neutron, this is its decay rate. */
int m_GRIN_intermediateResidual = -1; /**< For special GRIN product sampling, this is the GNDS intid of the intermediate residual. */
LUPI_HOST_DEVICE Input( bool a_wantVelocity, Upscatter::Model a_upscatterModel );
LUPI_HOST_DEVICE bool wantVelocity( ) const { return( m_wantVelocity ); } /**< BRB */
};
/*
============================================================
========================== Product =========================
============================================================
*/
class Product {
public:
SampledType m_sampledType;
bool m_isVelocity; /**< If true, m_px_vx, m_py_vy and m_pz_vz are velocities otherwise momenta. */
int m_productIntid; /**< The intid of the sampled product. */
int m_productIndex; /**< The index of the sampled product. */
int m_userProductIndex; /**< The user particle index of the sampled product. */
int m_numberOfDBRC_rejections; /**< For the DBRC upscattering model, this is the number of rejections + 1 per product sample. */
double m_productMass; /**< The mass of the sampled product. */
double m_kineticEnergy; /**< The kinetic energy of the sampled product. */
double m_px_vx; /**< The velocity or momentum along the x-axis of the sampled product. */
double m_py_vy; /**< The velocity or momentum along the y-axis of the sampled product. */
double m_pz_vz; /**< The velocity or momentum along the z-axis of the sampled product. The z-axis is along the direction of the projectile's velolcity. */
int m_delayedNeutronIndex; /**< If the product is a delayed neutron, this is its index. */
double m_delayedNeutronDecayRate; /**< If the product is a delayed neutron, this is its decay rate. */
double m_birthTimeSec; /**< Some products, like delayed fission neutrons, are to appear (be born) later. This is the time in seconds that such a particle should be born since the interaction. */
};
/*
============================================================
====================== ProductHandler ======================
============================================================
*/
class ProductHandler {
public:
LUPI_HOST_DEVICE ProductHandler( ) {}
LUPI_HOST_DEVICE ~ProductHandler( ) {}
template <typename RNG, typename PUSHBACK>
LUPI_HOST_DEVICE void add( double a_projectileEnergy, int a_productIntid, int a_productIndex, int a_userProductIndex, double a_productMass, Input &a_input,
RNG && a_rng, PUSHBACK && push_back, bool isPhoton );
};
/*
============================================================
================ StdVectorProductHandler ===================
============================================================
*/
#ifdef __CUDACC__
#define MCGIDI_CUDACC_numberOfProducts 1000
class StdVectorProductHandler : public ProductHandler {
private:
std::size_t m_size;
Product m_products[1024];
public:
LUPI_HOST_DEVICE StdVectorProductHandler( ) : m_size( 0 ) { }
LUPI_HOST_DEVICE ~StdVectorProductHandler( ) { }
LUPI_HOST_DEVICE std::size_t size( ) { return( m_size ); }
LUPI_HOST_DEVICE Product &operator[]( long a_index ) { return( m_products[a_index] ); }
LUPI_HOST_DEVICE void push_back( Product &a_product ) {
if( m_size < MCGIDI_CUDACC_numberOfProducts ) {
m_products[m_size] = a_product;
++m_size;
}
}
LUPI_HOST_DEVICE void clear( ) { m_size = 0; }
};
#else
class StdVectorProductHandler : public ProductHandler {
private:
std::vector<Product> m_products; /**< The list of products sampled. */
public:
LUPI_HOST_DEVICE StdVectorProductHandler( ) : m_products( ) { }
LUPI_HOST_DEVICE ~StdVectorProductHandler( ) { }
LUPI_HOST_DEVICE std::size_t size( ) { return( m_products.size( ) ); }
LUPI_HOST_DEVICE Product &operator[]( long a_index ) { return( m_products[a_index] ); }
LUPI_HOST_DEVICE std::vector<Product> &products( ) { return( m_products ); }
LUPI_HOST_DEVICE void push_back( Product &a_product ) { m_products.push_back( a_product ); }
LUPI_HOST_DEVICE void clear( ) { m_products.clear( ); }
};
#endif
/*
============================================================
============== MCGIDIVectorProductHandler ==================
============================================================
*/
class MCGIDIVectorProductHandler : public ProductHandler {
private:
Vector<Product> m_products; /**< The list of products sampled. */
public:
LUPI_HOST_DEVICE MCGIDIVectorProductHandler( std::size_t a_size = 20 ) :
m_products( ) {
m_products.reserve( a_size );
}
LUPI_HOST_DEVICE ~MCGIDIVectorProductHandler( ) {}
LUPI_HOST_DEVICE std::size_t size( ) { return( m_products.size( ) ); }
LUPI_HOST_DEVICE Product const &operator[]( std::size_t a_index ) const { return( m_products[a_index] ); }
LUPI_HOST_DEVICE Vector<Product> const &products( ) const { return( m_products ); }
LUPI_HOST_DEVICE void push_back( Product &a_product ) { m_products.push_back( a_product ); }
LUPI_HOST_DEVICE void clear( ) { m_products.clear( ); }
};
} // End of namespace Sampling.
} // End of namespace MCGIDI.
#endif // End of MCGIDI_sampling_hpp_included
@@ -0,0 +1,174 @@
/*
# <<BEGIN-copyright>>
# Copyright 2019, Lawrence Livermore National Security, LLC.
# This file is part of the gidiplus package (https://github.com/LLNL/gidiplus).
# gidiplus is licensed under the MIT license (see https://opensource.org/licenses/MIT).
# SPDX-License-Identifier: MIT
# <<END-copyright>>
*/
#ifndef MCGIDI_STRING_HPP
#define MCGIDI_STRING_HPP
/* Modified from Karsten Burger's version 2017
* Made changes to make it more compatible with GPUs.
* Allow for data to be initialized to nullptr.
*
* Modified from public domain software:
* Karsten Burger 2014
*
* Sourceforge project "Simple C++ String Class"
* http://sourceforge.net/projects/simplecstringclass/
* This a simple C++ string class based on class my_string by
* Christian Stigen Larsen, 2007, http://csl.name/programming/my_string/
*
* It only uses the C-string functions and is thus independent of the
* standard C++ library.
*
* It is public domain, in the hope, that you find it useful.
* Please note that there is no guarantee of any kind: it is supplied
* without any warranty; without even the implied warranty of
* merchantability or fitness for a particular purpose.
*
* You can probably replace std::string with this one in many
* cases, but a lot of stuff is missing, and I would recommend
* you stick to std::string anyway.
*
* I want to point out that there is nothing fancy about this class.
* It keeps every string in its own buffer, and copies as often as
* needed.
* The data always contains a trailing NUL char.
*
* However, I believe that is a good approach. For instance, it
* uses malloc rather than new, which makes it possible to use
* realloc. On many systems, realloc will try to use up "invisible"
* space that was used by malloc to pad a string for memory alignment.
* That makes it potentially fast for small concatenations.
*
* I don't propose to use this class for anything practical, since
* we already have std::string, but it may be an interesting read
* for C++ novices at the very least. Also, additional functions can
* easily be expanded.
*
* Also I met a case, where I had to avoid std::string because of
* link problems with an application using mixed libraries, especially
* one compiled with an old Intel compiler icc 7.
*
* Bugs/suggestions to info [at) dr-burger ]dot[ com
* or via the Sourceforge project page.
*/
#include <sys/types.h> // size_t
#include <stdexcept>
#include <LUPI_declareMacro.hpp>
/** @brief Simple C++ string class, useful as replacement for
std::string if this cannot be used, or just for fun.
*/
namespace MCGIDI {
class String
{
char* p; ///< The data
size_t allocated_; ///< The allocated memory size (including trailing NUL)
size_t size_; ///< The currently used memory size (excluding trailing NUL)
public:
typedef size_t size_type;
static const size_type npos;
LUPI_HOST_DEVICE String();
LUPI_HOST_DEVICE ~String();
LUPI_HOST_DEVICE String(const String&);
LUPI_HOST_DEVICE String(const char*);
LUPI_HOST_DEVICE String& operator=(const char*);
LUPI_HOST_DEVICE String& operator=(const String&);
LUPI_HOST_DEVICE String& operator+=(const String&);
LUPI_HOST_DEVICE String& operator+=(const char*);
LUPI_HOST_DEVICE String& operator+=(char);
LUPI_HOST_DEVICE void push_back(char);
friend String
LUPI_HOST_DEVICE operator+(const String& lhs, const String& rhs);
LUPI_HOST_DEVICE bool operator==(const char*) const;
LUPI_HOST_DEVICE bool operator==(const String&) const;
LUPI_HOST_DEVICE void clear(); // set string to empty string (memory remains reserved)
LUPI_HOST_DEVICE void clearMemory(); // set string to empty string (memory is free'd)
LUPI_HOST_DEVICE size_type size() const { return size_; } ///< size without terminating NUL
LUPI_HOST_DEVICE size_type length() const { return size_; } ///< as size()
// size if fully used
LUPI_HOST_DEVICE size_type capacity() const { return allocated_-1; }
// 8 byte alligned size
LUPI_HOST_DEVICE long internalSize() const {
long delta = allocated_;
long sub = delta % 8;
if (sub != 0) delta += (8-sub);
return delta * sizeof(char);
}
LUPI_HOST_DEVICE bool empty() const { return size_ == 0; }
LUPI_HOST_DEVICE const char* c_str() const { return p; } ///< raw data
/** Reserve internal string memory so that n characters can be put into the
string (plus 1 for the NUL char). If there is already enough memory,
nothing happens, if not, the memory will be realloated to exactly this
amount.
*/
LUPI_HOST_DEVICE void reserve( size_type n, char ** address = nullptr);
/** Resize string. If n is less than the current size, the string will be truncated.
If n is larger, then the memory will be reallocated to exactly this amount, and
the additional characters will be NUL characters.
*/
LUPI_HOST_DEVICE void resize( size_type n, char ** address = nullptr);
/** Resize string. If n is less than the current size, the string will be truncated.
If n is larger, then the memory will be reallocated to exactly this amount, and
the additional characters will be c characters.
*/
LUPI_HOST_DEVICE void resize( size_type n, char c, char ** address = nullptr);
/// swap contents
LUPI_HOST_DEVICE void swap( String& );
LUPI_HOST_DEVICE String substr(const size_type pos, size_type length) const;
// unchecked access:
LUPI_HOST_DEVICE char& operator[](const size_type i) { return p[i]; }
LUPI_HOST_DEVICE char operator[](const size_type i) const { return p[i]; }
// checked access:
LUPI_HOST_DEVICE char& at(const size_type i);
LUPI_HOST_DEVICE char at(const size_type i) const;
/// erase len characters at position pos
LUPI_HOST_DEVICE String& erase(size_type pos, size_type len);
/// Append n characters of a string
LUPI_HOST_DEVICE String& append(const char* str, size_type n);
LUPI_HOST_DEVICE int compare( size_type pos, size_type len, const String& str ) const;
LUPI_HOST_DEVICE int compare( size_type pos, size_type len, const char* str ) const;
private:
// reallocate the internal memory
LUPI_HOST_DEVICE void my_realloc( size_type n, char ** address = nullptr);
LUPI_HOST_DEVICE char* strdup_never_null(const char* other);
};
// class
LUPI_HOST_DEVICE bool operator<(const String&, const String&);
}
#endif
@@ -0,0 +1,468 @@
/*
# <<BEGIN-copyright>>
# Copyright 2019, Lawrence Livermore National Security, LLC.
# This file is part of the gidiplus package (https://github.com/LLNL/gidiplus).
# gidiplus is licensed under the MIT license (see https://opensource.org/licenses/MIT).
# SPDX-License-Identifier: MIT
# <<END-copyright>>
*/
#ifndef MCGIDI_VECTOR_HPP
#define MCGIDI_VECTOR_HPP
#define CPU_MEM false
#define UVM_MEM true
#ifdef HAVE_OPENMP_TARGET
#ifdef USE_OPENMP_NO_GPU
#define VAR_MEM false
#else
#define VAR_MEM true
#endif
#else
#define VAR_MEM false
#endif
typedef int MCGIDI_VectorSizeType;
#define MCGIDI_SWAP(a,b,type) {type ttttttttt=a;a=b;b=ttttttttt;}
#if defined(__CUDACC__) && !defined(__CUDA_ARCH__)
#include <cuda.h>
#include <cuda_runtime.h>
#include <cuda_runtime_api.h>
#endif
#if defined(__HIP__)
#include <hip/hip_version.h>
#include <hip/hip_runtime.h>
#include <hip/hip_runtime_api.h>
#include <hip/hip_common.h>
#endif
#include <string.h>
#include <stdio.h>
#include "cassert"
#include <algorithm>
#include <LUPI_declareMacro.hpp>
#include <vector>
namespace MCGIDI {
template <class T>
class Vector
{
private:
T* _data;
std::size_t _capacity;
std::size_t _size;
bool _mem_type;
public:
typedef T* iterator;
typedef T* const_iterator;
LUPI_HOST_DEVICE Vector() : _data(0), _capacity(0), _size(0), _mem_type(CPU_MEM) {};
LUPI_HOST_DEVICE Vector( std::size_t s, bool mem_flag = CPU_MEM ) : _data(0), _capacity(s), _size(s), _mem_type(mem_flag)
{
if( s == 0 ){ _data = nullptr; return;}
switch ((int)_mem_type){
case CPU_MEM:
_data = new T [_capacity];
break;
case UVM_MEM:
{
void *ptr = nullptr;
#if defined(__CUDACC__) && !defined(__CUDA_ARCH__)
cudaMallocManaged(&ptr, _capacity*sizeof(T), cudaMemAttachGlobal);
#elif defined(__HIP__) && !defined(__HIP_DEVICE_COMPILE__)
hipMallocManaged(&ptr, _capacity*sizeof(T), hipMemAttachGlobal);
#endif
_data = new(ptr) T[_capacity];
break;
}
default:
_data = new T [_capacity];
break;
}
}
LUPI_HOST_DEVICE Vector( std::size_t s, const T& d, bool mem_flag = CPU_MEM ) : _data(0), _capacity(s), _size(s), _mem_type(mem_flag)
{
if( s == 0 ){ _data = nullptr; return;}
switch ( (int) _mem_type){
case CPU_MEM:
_data = new T [_capacity];
break;
case UVM_MEM:
{
void *ptr = nullptr;
#if defined(__CUDACC__) && !defined(__CUDA_ARCH__)
cudaMallocManaged(&ptr, _capacity*sizeof(T), cudaMemAttachGlobal);
#elif defined(__HIP__) && !defined(__HIP_DEVICE_COMPILE__)
hipMallocManaged(&ptr, _capacity*sizeof(T), hipMemAttachGlobal);
#endif
_data = new(ptr) T[_capacity];
break;
}
default:
_data = new T [_capacity];
break;
}
for (std::size_t ii = 0; ii < _capacity; ++ii)
_data[ii] = d;
}
LUPI_HOST_DEVICE Vector(const Vector<T>& aa )
: _data(0), _capacity(aa._capacity), _size(aa._size), _mem_type(aa._mem_type)
{
if( _capacity == 0 ){ _data = nullptr; return; }
switch ( (int) _mem_type){
case CPU_MEM:
_data = new T [_capacity];
break;
case UVM_MEM:
{
void *ptr = nullptr;
#if defined(__CUDACC__) && !defined(__CUDA_ARCH__)
cudaMallocManaged(&ptr, _capacity*sizeof(T), cudaMemAttachGlobal);
#elif defined(__HIP__) && !defined(__HIP_DEVICE_COMPILE__)
hipMallocManaged(&ptr, _capacity*sizeof(T), hipMemAttachGlobal);
#endif
_data = new(ptr) T[_capacity];
break;
}
default:
_data = new T [_capacity];
break;
}
for (std::size_t ii=0; ii<_size; ++ii)
_data[ii] = aa._data[ii];
}
LUPI_HOST Vector(const std::vector<T>& aa )
: _data(0), _capacity(aa.size()), _size(aa.size()), _mem_type(CPU_MEM)
{
if( _capacity == 0 ){ _data = nullptr; return;}
switch ( (int) _mem_type){
case CPU_MEM:
_data = new T [_capacity];
break;
case UVM_MEM:
{
void *ptr = nullptr;
#if defined(__CUDACC__) && !defined(__CUDA_ARCH__)
cudaMallocManaged(&ptr, _capacity*sizeof(T), cudaMemAttachGlobal);
#elif defined(__HIP__) && !defined(__HIP_DEVICE_COMPILE__)
hipMallocManaged(&ptr, _capacity*sizeof(T), hipMemAttachGlobal);
#endif
_data = new(ptr) T[_capacity];
break;
}
default:
_data = new T [_capacity];
break;
}
for (std::size_t ii=0; ii<_size; ++ii)
_data[ii] = aa[ii];
}
LUPI_HOST_DEVICE ~Vector() {
switch ( (int) _mem_type){
case CPU_MEM:
delete[] _data;
break;
case UVM_MEM:
for (std::size_t i=0; i < _size; ++i)
_data[i].~T();
#if defined(__CUDACC__) && !defined(__CUDA_ARCH__)
cudaFree(_data);
#elif defined(__HIP__) && !defined(__HIP_DEVICE_COMPILE__)
hipFree(_data);
#endif
break;
default:
delete[] _data;
break;
}
}
LUPI_HOST_DEVICE iterator begin() { return _data; }
LUPI_HOST_DEVICE const_iterator begin() const { return _data; }
LUPI_HOST_DEVICE iterator end() { return _data + _size; }
LUPI_HOST_DEVICE const_iterator end() const { return _data + _size; }
/// Needed for copy-swap idiom
LUPI_HOST_DEVICE void swap(Vector<T>& other)
{
MCGIDI_SWAP(_data, other._data, T*);
MCGIDI_SWAP(_capacity, other._capacity, std::size_t);
MCGIDI_SWAP(_size, other._size, std::size_t);
MCGIDI_SWAP(_mem_type, other._mem_type, bool);
}
/// Implement assignment using copy-swap idiom
LUPI_HOST_DEVICE Vector<T>& operator=(const Vector<T>& aa)
{
if (&aa != this)
{
Vector<T> temp(aa);
this->swap(temp);
}
return *this;
}
LUPI_HOST Vector<T>& operator=(const std::vector<T>& aa)
{
Vector<T> temp(aa);
this->swap(temp);
return *this;
}
LUPI_HOST_DEVICE int get_mem_type()
{
return _mem_type;
}
LUPI_HOST_DEVICE void push_back( const T& dataElem )
{
assert( _size < _capacity );
_data[_size] = dataElem;
_size++;
}
LUPI_HOST_DEVICE const T& operator[]( std::size_t index ) const
{
// assert( index < _capacity );
// assert( index >= 0); comment out pointless assertion size_t type is >= 0 by definition
return _data[index];
}
LUPI_HOST_DEVICE T& operator[]( std::size_t index )
{
// assert( index < _capacity );
// assert( index >= 0); comment out pointless assertion size_t type is >= 0 by definition
return _data[index];
}
LUPI_HOST_DEVICE std::size_t capacity() const
{
return _capacity;
}
LUPI_HOST_DEVICE std::size_t size() const
{
return _size;
}
LUPI_HOST_DEVICE T& back()
{
return _data[_size-1];
}
LUPI_HOST_DEVICE T& back() const
{
return _data[_size-1];
}
LUPI_HOST_DEVICE void reserve( std::size_t s, char ** address = nullptr, bool mem_flag = CPU_MEM )
{
if (s == _capacity) return;
assert( _capacity == 0 );
_capacity = s;
_mem_type = mem_flag;
if( s == 0 ){ _data = nullptr; return;}
switch ( (int) _mem_type){
case CPU_MEM:
if (address == nullptr || *address == nullptr) _data = new T [_capacity];
else {
_data = new(*address) T [_capacity];
*address += sizeof(T) * _capacity;
}
break;
case UVM_MEM:
{
void *ptr = nullptr;
#if defined(__CUDACC__) && !defined(__CUDA_ARCH__)
cudaMallocManaged(&ptr, _capacity*sizeof(T), cudaMemAttachGlobal);
#elif defined(__HIP__) && !defined(__HIP_DEVICE_COMPILE__)
hipMallocManaged(&ptr, _capacity*sizeof(T), hipMemAttachGlobal);
#endif
_data = new(ptr) T[_capacity];
break;
}
default:
if (address == nullptr || *address == nullptr) _data = new T [_capacity];
else {
_data = new(*address) T [_capacity];
*address += sizeof(T) * _capacity;
}
break;
}
}
LUPI_HOST_DEVICE void resize( std::size_t s, char ** address = nullptr, bool mem_flag = CPU_MEM )
{
if (_capacity != 0) {
assert( _capacity >= s);
_size = s;
return;
}
assert( _capacity == 0 );
_capacity = s;
_size = s;
_mem_type = mem_flag;
if( s == 0 ){ _data = nullptr; return;}
switch ( (int) _mem_type){
case CPU_MEM:
if (address == nullptr || *address == nullptr) {
_data = new T [_capacity];
}
else {
_data = new(*address) T [_capacity];
std::size_t delta = sizeof(T) * _capacity;
std::size_t sub = delta % 8;
if (sub != 0) delta += (8-sub);
*address += delta;
}
break;
case UVM_MEM:
{
void *ptr = nullptr;
#if defined(__CUDACC__) && !defined(__CUDA_ARCH__)
cudaMallocManaged(&ptr, _capacity*sizeof(T), cudaMemAttachGlobal);
#elif defined(__HIP__) && !defined(__HIP_DEVICE_COMPILE__)
hipMallocManaged(&ptr, _capacity*sizeof(T), hipMemAttachGlobal);
#endif
_data = new(ptr) T[_capacity];
break;
}
default:
if (address == nullptr || *address == nullptr) _data = new T [_capacity];
else {
_data = new(*address) T [_capacity];
std::size_t delta = sizeof(T) * _capacity;
std::size_t sub = delta % 8;
if (sub != 0) delta += (8-sub);
*address += delta;
}
break;
}
}
LUPI_HOST_DEVICE void resize( std::size_t s, const T& d, char ** address = nullptr, bool mem_flag = CPU_MEM )
{
assert( _capacity == 0 );
_capacity = s;
_size = s;
_mem_type = mem_flag;
if( s == 0 ){ _data = nullptr; return;}
switch ( (int) _mem_type){
case CPU_MEM:
if (address == nullptr || *address == nullptr) _data = new T [_capacity];
else {
_data = new(*address) T [_capacity];
std::size_t delta = sizeof(T) * _capacity;
std::size_t sub = delta % 8;
if (sub != 0) delta += (8-sub);
*address += delta;
}
break;
case UVM_MEM:
{
void *ptr = nullptr;
#if defined(__CUDACC__) && !defined(__CUDA_ARCH__)
cudaMallocManaged(&ptr, _capacity*sizeof(T), cudaMemAttachGlobal);
#elif defined(__HIP__) && !defined(__HIP_DEVICE_COMPILE__)
hipMallocManaged(&ptr, _capacity*sizeof(T), hipMemAttachGlobal);
#endif
_data = new(ptr) T[_capacity];
break;
}
default:
if (address == nullptr || *address == nullptr) _data = new T [_capacity];
else {
_data = new(*address) T [_capacity];
std::size_t delta = sizeof(T) * _capacity;
std::size_t sub = delta % 8;
if (sub != 0) delta += (8-sub);
*address += delta;
*address += sizeof(T) * _capacity;
}
break;
}
for (std::size_t ii = 0; ii < _capacity; ++ii)
_data[ii] = d;
}
LUPI_HOST_DEVICE bool empty() const
{
return ( _size == 0 );
}
LUPI_HOST_DEVICE void eraseEnd( std::size_t NewEnd )
{
assert( NewEnd <= _size );
_size = NewEnd;
}
LUPI_HOST_DEVICE void pop_back()
{
assert(_size > 0);
_size--;
}
LUPI_HOST_DEVICE void clear()
{
_size = 0;
}
LUPI_HOST_DEVICE void appendList( std::size_t listSize, T* list )
{
assert( _size + listSize < _capacity );
for( std::size_t i = _size; i < _size + listSize; i++ )
{
_data[i] = list[ i-_size ];
}
}
//Atomically retrieve an availible index then increment that index some amount
LUPI_HOST_DEVICE std::size_t atomic_Index_Inc( std::size_t inc )
{
if (_size+inc > _capacity)
{MCGIDI_PRINTF("inc too much (size %d, inc %d cap %d)\n", _size, inc, _capacity); abort(); }
assert(_size+inc <= _capacity);
std::size_t pos;
// #include "mc_omp_atomic_capture.hh"
{pos = _size; _size = _size + inc;}
return pos;
}
// This will not work for a vector of base classes.
LUPI_HOST_DEVICE std::size_t internalSize() const {
std::size_t delta = sizeof(T) * _size;
std::size_t sub = delta % 8;
if (sub != 0) delta += (8-sub);
return delta;
}
LUPI_HOST_DEVICE void forceCreate(std::size_t a_size, T* a_data) {
_capacity = a_size;
_size = a_size;
_data = a_data;
}
};
}
#endif
File diff suppressed because it is too large Load Diff
@@ -1,126 +0,0 @@
/*
# <<BEGIN-copyright>>
# <<END-copyright>>
*/
#ifndef PoPs_h_included
#define PoPs_h_included
/* Disable Effective C++ warnings in PoP code. */
#if __INTEL_COMPILER > 1399
#pragma warning( disable:593 )
#endif
#include <statusMessageReporting.h>
/*
* MPI stuff.
*/
#ifdef PoPs_MPI
#include <mpi.h>
#endif
#if defined __cplusplus
extern "C" {
namespace GIDI {
#endif
#define POPS_VERSION_MAJOR 1
#define POPS_VERSION_MINOR 0
#define POPS_VERSION_PATCHLEVEL 5
#define PoPs_packageSymbol "PoPs (properties of particles)"
#define PoPs_packageName PoPs_packageSymbol " (properties of particles)"
typedef struct PoP_s PoP;
enum PoPs_errorTokens { PoPs_errorToken_Okay, PoPs_errorToken_badName, PoPs_errorToken_badIndex, PoPs_errorToken_badUnitConversion };
enum PoPs_genre { PoPs_genre_invalid, PoPs_genre_unknown, PoPs_genre_alias, PoPs_genre_photon, PoPs_genre_lepton,
PoPs_genre_quark, PoPs_genre_meson, PoPs_genre_baryon, PoPs_genre_nucleus, PoPs_genre_atom };
/*
* In the following struct, 'index' is the index of the particle (proper or aliased) in the list of particles. If a particle
* is a proper particle its properIndex is -1. Otherwise, it is the index of the aliased particle's proper particle. If a proper
* particle does not have an aliased particle referring to it, aliasIndex is -1. If a proper particle has aliaes particles,
* its aliasIndex is the index of its first aliased particle. If a second alias is added to a proper particle, then its first
* aliased particle's aliasIndex is the index of that particle, and so on. The last aliased particle added has aliasIndex = -1.
*/
struct PoP_s { /* Any changes here must be reflected in functions PoP_initialize and PoP_copyParticle and in file PoPs_Bcast.c logic. */
int index, properIndex, aliasIndex;
enum PoPs_genre genre;
char const *name;
int Z, A, l;
double mass; /* Mass to be added to base. */
char const *massUnit;
};
extern int PoPs_smr_ID;
const char *PoPs_version( void );
int PoPs_versionMajor( void );
int PoPs_versionMinor( void );
int PoPs_versionPatchLevel( void );
int PoPs_register( void );
int PoPs_readDatabase( statusMessageReporting *smr, char const *fileName );
int PoPs_release( statusMessageReporting *smr );
PoP *PoPs_addParticleIfNeeded( statusMessageReporting *smr, PoP *pop );
PoP *PoPs_copyAddParticleIfNeeded( statusMessageReporting *smr, PoP *pop );
PoP *PoPs_addAliasIfNeeded( statusMessageReporting *smr, char const *name, char const *alias );
int PoPs_numberOfParticle( void );
int PoPs_particleIndex( char const *name );
int PoPs_particleIndex_smr( statusMessageReporting *smr, char const *name, char const *file, int line, char const *func );
char const *PoPs_getName_atIndex( statusMessageReporting *smr, int index );
double PoPs_getMassInUnitOf( statusMessageReporting *smr, char const *name, char const *unit );
double PoPs_getMassInUnitOf_atIndex( statusMessageReporting *smr, int index, char const *unit );
enum PoPs_genre PoPs_getGenre( statusMessageReporting *smr, char const *name );
enum PoPs_genre PoPs_getGenre_atIndex( statusMessageReporting *smr, int index );
int PoPs_getZ_A_l( statusMessageReporting *smr, char const *name, int *Z, int *A, int *l );
int PoPs_getZ_A_l_atIndex( statusMessageReporting *smr, int index, int *Z, int *A, int *l );
int PoPs_hasNucleus( statusMessageReporting *smr, char const *name, int protonIsNucleus );
int PoPs_hasNucleus_atIndex( statusMessageReporting *smr, int index, int protonIsNucleus );
char const *PoPs_getAtomsName( statusMessageReporting *smr, char const *name );
char const *PoPs_getAtomsName_atIndex( statusMessageReporting *smr, int index );
int PoPs_getAtomsIndex( statusMessageReporting *smr, char const *name );
int PoPs_getAtomsIndex_atIndex( statusMessageReporting *smr, int index );
PoP *PoPs_getParticle_atIndex( int index );
char const *PoPs_genreTokenToString( enum PoPs_genre genre );
void PoPs_print( int sorted );
void PoPs_write( FILE *f, int sorted );
PoP *PoP_new( statusMessageReporting *smr );
int PoP_initialize( statusMessageReporting *smr, PoP *pop );
int PoP_release( PoP *pop );
PoP *PoP_free( PoP *pop );
int PoP_copyParticle( statusMessageReporting *smr, PoP *desc, PoP *src );
PoP *PoP_makeParticle( statusMessageReporting *smr, enum PoPs_genre genre, char const *name, double mass, char const *massUnit );
int PoP_setZ_A_l( statusMessageReporting *smr, PoP *pop, int Z, int A, int l );
int PoP_getIndex( PoP *pop );
char const *PoP_getName( PoP *pop );
int PoPs_particleReadDatabase( statusMessageReporting *smr, char const *name );
PoP *PoPs_particleCreateLoadInfo( statusMessageReporting *smr, const char *name );
int PoPs_particleLoadInfo( statusMessageReporting *smr, const char *name, PoP *pop );
double PoP_getMassInUnitOf( statusMessageReporting *smr, PoP *pop, char const *unit );
PoP *PoP_makeAlias( statusMessageReporting *smr, char const *name, char const *alias );
int PoPs_unitConversionRatio( char const *_from, char const *_to, double *ratio );
int lPoPs_addParticleIfNeeded( statusMessageReporting *smr, char const *name, char const *special );
/*
* MPI stuff.
*/
#ifdef PoPs_MPI
int PoPs_Bcast( statusMessageReporting *smr, MPI_Comm comm, int bossRank );
#endif
/* Use the next function with caution as it is only for initial testing of the package and will soon be gone. */
int PoPs_setBDFLS_File( char const *name );
#if defined __cplusplus
}
}
#endif
#endif /* End of PoPs_h_included. */
@@ -1,22 +0,0 @@
/*
# <<BEGIN-copyright>>
# <<END-copyright>>
*/
#ifndef PoPs_Bcast_private_h_included
#define PoPs_Bcast_private_h_included
#if defined __cplusplus
extern "C" {
namespace GIDI {
#endif
int PoPs_Bcast2( statusMessageReporting *smr, MPI_Comm comm, int bossRank, unitsDB *unitsRoot, PoPs *popsRoot );
#if defined __cplusplus
}
}
#endif
#endif /* End of PoPs_Bcast_private_h_included. */
File diff suppressed because it is too large Load Diff
@@ -1,22 +0,0 @@
/*
# <<BEGIN-copyright>>
# <<END-copyright>>
*/
#ifndef PoPs_mass_h_included
#define PoPs_mass_h_included
#include <statusMessageReporting.h>
#if defined __cplusplus
extern "C" {
namespace GIDI {
#endif
double PoPs_particleMass_AMU( statusMessageReporting *smr, char const *name );
#if defined __cplusplus
}
}
#endif
#endif /* End of PoPs_mass_h_included. */
@@ -1,41 +0,0 @@
/*
# <<BEGIN-copyright>>
# <<END-copyright>>
*/
#ifndef PoPs_private_h_included
#define PoPs_private_h_included
#if defined __cplusplus
extern "C" {
namespace GIDI {
#endif
typedef struct unitsDB_s unitsDB;
typedef struct PoPs_s PoPs;
struct unitsDB_s {
int numberOfUnits;
int allocated;
char const **unsorted;
};
struct PoPs_s {
int numberOfParticles;
int allocated;
PoP **pops;
PoP **sorted;
};
int PoPs_releasePrivate( statusMessageReporting *smr );
char const *unitsDB_addUnitIfNeeded( statusMessageReporting *smr, char const *unit );
int unitsDB_index( statusMessageReporting *smr, char const *unit );
char const *unitsDB_stringFromIndex( statusMessageReporting *smr, int index );
#if defined __cplusplus
}
}
#endif
#endif /* End of PoPs_private_h_included. */
@@ -0,0 +1,130 @@
/*
# <<BEGIN-copyright>>
# Copyright 2019, Lawrence Livermore National Security, LLC.
# This file is part of the gidiplus package (https://github.com/LLNL/gidiplus).
# gidiplus is licensed under the MIT license (see https://opensource.org/licenses/MIT).
# SPDX-License-Identifier: MIT
# <<END-copyright>>
*/
#ifndef RISI_hpp_included
#define RISI_hpp_included 1
#include <map>
#include <set>
#include <LUPI.hpp>
namespace GIDI {
namespace RISI {
class Projectile;
class Reaction {
public:
double m_effectiveThreshold; /**< The effective threshold for the reaction. */
std::vector<std::string> m_products; /**< The list of final products for the reaction. */
std::vector<int> m_multiplicities; /**< The multiplicities for each product in *m_products*. */
std::vector<std::string> m_intermediates; /**< The list of intermediates products for the reaction. */
std::string m_process; /**< The process for the reaction. */
std::string m_reactionLabel; /**< The label of the reaction. */
std::string m_convarianceFlag; /**< A flag indicating if covariance data are present for the reaction. */
public:
Reaction( double a_effectiveThreshold, std::vector<std::string> const &a_products, std::vector<int> const &a_multiplicities,
std::vector<std::string> const &a_intermediates, std::string const &a_process, std::string const &reactionLabel,
std::string const &convarianceFlag );
void products( double a_energyMax, std::set<std::string> &a_products ) const ;
};
class Protare {
private:
int m_addMode; /**< Indicates which method **add** calls. */
std::string m_projectile; /**< The PoPs id for the projectile. */
std::string m_target; /**< The PoPs id for the target. */
std::string m_evaluation; /**< The evaluation for the protare. */
double m_energyConversionFactor; /**< Factor to convert from file energy units to user energy units. */
std::map<std::string, std::string> m_aliases; /**< The list of meta-stable aliases in the protare. */
std::vector<Reaction *> m_reactions; /**< The list of **Reaction** instances for the protare. */
public:
Protare( std::string const &a_projectile, std::string const &a_target, std::string const &a_evaluation,
std::string const &a_protareEnergyUnit, std::string const &a_requestedEnergyUnit );
~Protare();
std::string const &projectile( ) { return( m_projectile ); }
std::string const &target( ) { return( m_target ); }
std::string const &evaluation( ) { return( m_evaluation ); }
void Oops( std::vector<std::string> const &a_elements );
void addAlias( std::vector<std::string> const &a_elements );
void setAddingAliases( ) { m_addMode = 1; } /**< Tells **add** method to call the **addAlias** method. */
void addReaction( std::vector<std::string> const &a_elements );
void setAddingReactions( ) { m_addMode = 2; } /**< Tells **add** method to call the **addReaction** method. */
void add( std::vector<std::string> const &a_elements );
void products( Projectile const *a_projectile, int a_level, int a_maxLevel, double a_energyMax, std::map<std::string, int> &a_products ) const ;
};
class Target {
private:
std::string m_id;
std::vector<Protare *> m_protares;
public:
Target( std::string const &a_id ) :
m_id( a_id ) {
}
~Target( );
void add( Protare *a_protare );
void products( Projectile const *a_projectile, int a_level, int a_maxLevel, double a_energyMax, std::map<std::string, int> &a_products ) const ;
void print( std::string const &a_indent = "" ) const ;
};
class Projectile {
private:
std::string m_id;
std::map<std::string, Target *> m_targets;
public:
Projectile( std::string const &a_id ) :
m_id( a_id ) {
}
~Projectile( );
void add( Protare *a_protare );
void products( std::string const &a_target, int a_level, int a_maxLevel, double a_energyMax, std::map<std::string, int> &a_products ) const ;
void print( std::string const &a_indent = "" ) const ;
};
class Projectiles {
private:
std::map<std::string, Projectile *> m_projectiles;
public:
Projectiles( ) {}
~Projectiles( );
void add( Protare *a_protare );
void clear( );
std::vector<std::string> products( std::string const &a_projectile, std::vector<std::string> const &a_seedTargets, int a_maxLevel,
double a_energyMax ) const ;
void print( std::string const &a_indent = "" ) const ;
};
void readRIS( std::string const &a_fileName, std::string const &a_energyUnit, Projectiles &a_projectiles );
} // End of namespace RISI.
} // End of namespace GIDI.
#endif // End of RISI_hpp_included
@@ -0,0 +1,5 @@
#define G4GIDI_MAJOR 1
#define G4GIDI_MINOR 1
#define G4GIDI_PATCHLEVEL 13
#define G4GIDI_VERSION "1.1.13"
#define G4GIDI_GIT "62db2f9b95bcd850c8821e70db50c4c94874cc4d"
@@ -1,5 +1,9 @@
/*
# <<BEGIN-copyright>>
# Copyright 2019, Lawrence Livermore National Security, LLC.
# This file is part of the gidiplus package (https://github.com/LLNL/gidiplus).
# gidiplus is licensed under the MIT license (see https://opensource.org/licenses/MIT).
# SPDX-License-Identifier: MIT
# <<END-copyright>>
*/
@@ -11,16 +15,16 @@
#if defined __cplusplus
extern "C" {
namespace GIDI {
#endif
#define nf_Legendre_minMaxOrder 4
#define nf_Legendre_maxMaxOrder 64
#define nf_Legendre_maxMaxOrder 128
#define nf_Legendre_sizeIncrement 8
typedef struct nf_Legendre_s nf_Legendre;
struct nf_Legendre_s {
nfu_status status;
int maxOrder;
int allocated; /* Will never be less than nf_Legendre_minMaxOrder. */
double *Cls;
@@ -31,21 +35,22 @@ typedef nfu_status (*nf_Legendre_GaussianQuadrature_callback)( double x, double
/*
* Methods in nf_Legendre.c
*/
nf_Legendre *nf_Legendre_new( int initialSize, int maxOrder, double *Cls, nfu_status *status );
nfu_status nf_Legendre_setup( nf_Legendre *nfL, int initialSize, int maxOrder );
nfu_status nf_Legendre_release( nf_Legendre *nfL );
nf_Legendre *nf_Legendre_new( statusMessageReporting *smr, int initialSize, int maxOrder, double *Cls );
nfu_status nf_Legendre_initialize( statusMessageReporting *smr, nf_Legendre *nfL, int initialSize, int maxOrder );
nfu_status nf_Legendre_release( statusMessageReporting *smr, nf_Legendre *nfL );
nf_Legendre *nf_Legendre_free( nf_Legendre *nfL );
nf_Legendre *nf_Legendre_clone( nf_Legendre *nfL, nfu_status *status );
nfu_status nf_Legendre_reallocateCls( nf_Legendre *Legendre, int size, int forceSmallerResize );
int nf_Legendre_maxOrder( nf_Legendre *Legendre );
int nf_Legendre_allocated( nf_Legendre *Legendre );
double nf_Legendre_getCl( nf_Legendre *Legendre, int l, nfu_status *status );
nfu_status nf_Legendre_setCl( nf_Legendre *Legendre, int l, double Cl );
nfu_status nf_Legendre_normalize( nf_Legendre *Legendre );
double nf_Legendre_evauluateAtMu( nf_Legendre *nfL, double mu, nfu_status *status );
nf_Legendre *nf_Legendre_clone( statusMessageReporting *smr, nf_Legendre *nfL );
nfu_status nf_Legendre_reallocateCls( statusMessageReporting *smr, nf_Legendre *Legendre, int size, int forceSmallerResize );
nfu_status nf_Legendre_maxOrder( statusMessageReporting *smr, nf_Legendre *Legendre, int *maxOrder );
nfu_status nf_Legendre_allocated( statusMessageReporting *smr, nf_Legendre *Legendre, int *allocated );
nfu_status nf_Legendre_getCl( statusMessageReporting *smr, nf_Legendre *Legendre, int l, double *Cl );
nfu_status nf_Legendre_setCl( statusMessageReporting *smr, nf_Legendre *Legendre, int l, double Cl );
nfu_status nf_Legendre_normalize( statusMessageReporting *smr, nf_Legendre *Legendre );
nfu_status nf_Legendre_evauluateAtMu( statusMessageReporting *smr, nf_Legendre *nfL, double mu, double *P );
double nf_Legendre_PofL_atMu( int l, double mu );
ptwXYPoints *nf_Legendre_to_ptwXY( nf_Legendre *nfL, double accuracy, int biSectionMax, int checkForRoots, nfu_status *status );
nf_Legendre *nf_Legendre_from_ptwXY( ptwXYPoints *ptwXY, int maxOrder, nfu_status *status );
ptwXYPoints *nf_Legendre_to_ptwXY( statusMessageReporting *smr, nf_Legendre *nfL, double accuracy, int biSectionMax,
int checkForRoots );
nf_Legendre *nf_Legendre_from_ptwXY( statusMessageReporting *smr, ptwXYPoints *ptwXY, int maxOrder );
/*
* Methods in nf_Legendre_GaussianQuadrature.c
@@ -54,7 +59,6 @@ nfu_status nf_Legendre_GaussianQuadrature( int degree, double x1, double x2, nf_
#if defined __cplusplus
}
}
#endif
#endif /* End of nf_Legendre_h_included. */
@@ -0,0 +1,128 @@
/*
# <<BEGIN-copyright>>
# Copyright 2019, Lawrence Livermore National Security, LLC.
# This file is part of the gidiplus package (https://github.com/LLNL/gidiplus).
# gidiplus is licensed under the MIT license (see https://opensource.org/licenses/MIT).
# SPDX-License-Identifier: MIT
# <<END-copyright>>
*/
#ifndef nf_buffer_h_included
#define nf_buffer_h_included
#if defined __cplusplus
#include <iterator>
template<typename T>
class nf_Buffer {
private:
T *m_data;
size_t m_length;
public:
using iterator = T*;
using const_iterator = T const *;
inline
constexpr
nf_Buffer() noexcept : m_data(nullptr), m_length(0) {}
inline
nf_Buffer(nf_Buffer const &c) :
m_data(new T[c.m_length]),
m_length(c.m_length)
{
for(size_t i = 0;i < m_length;++ i){
m_data[i] = c.m_data[i];
}
}
inline
~nf_Buffer() noexcept {
deallocate();
}
inline
constexpr
size_t size() const noexcept { return m_length; }
inline
void clear(T value){
for(size_t i = 0;i < m_length;++ i){
m_data[i] = value;
}
}
inline
void allocate(size_t length){
deallocate();
m_length = length;
m_data = new T[length];
}
inline
void deallocate() noexcept {
delete[] m_data;
m_length = 0;
}
inline
void resize(size_t length){
allocate(length);
}
inline
std::vector<T> vector() const {
return std::vector<T>(cbegin(), cend());
}
inline
T* data() noexcept {return m_data;}
inline
constexpr
T const * data() const noexcept {return m_data;}
template<typename I>
inline
T& operator[](I idx) noexcept {return m_data[idx];}
template<typename I>
inline
constexpr
T const & operator[](I idx) const noexcept {return m_data[idx];}
inline
iterator begin() noexcept { return m_data; }
inline
constexpr
const_iterator begin() const noexcept { return m_data; }
inline
iterator end() noexcept { return m_data + m_length; }
inline
constexpr
const_iterator end() const noexcept { return m_data + m_length; }
inline
constexpr
const_iterator cbegin() const noexcept { return m_data; }
inline
constexpr
const_iterator cend() const noexcept { return m_data + m_length; }
};
#endif
#endif /* End of nf_buffer_h_included. */
@@ -1,5 +1,9 @@
/*
# <<BEGIN-copyright>>
# Copyright 2019, Lawrence Livermore National Security, LLC.
# This file is part of the gidiplus package (https://github.com/LLNL/gidiplus).
# gidiplus is licensed under the MIT license (see https://opensource.org/licenses/MIT).
# SPDX-License-Identifier: MIT
# <<END-copyright>>
*/
@@ -11,7 +15,6 @@
#if defined __cplusplus
extern "C" {
namespace GIDI {
#endif
#define nf_GnG_adaptiveQuadrature_MaxMaxDepth 20
@@ -24,7 +27,6 @@ nfu_status nf_GnG_adaptiveQuadrature( nf_GnG_adaptiveQuadrature_callback quadrat
#if defined __cplusplus
}
}
#endif
#endif /* End of nf_integration_h_included. */
@@ -1,44 +0,0 @@
/*
# <<BEGIN-copyright>>
# <<END-copyright>>
*/
#ifndef specialFunctions_h_included
#define specialFunctions_h_included
#define _USE_MATH_DEFINES
#include <math.h>
#include <float.h>
#include "nf_utilities.h"
#if defined __cplusplus
extern "C" {
namespace GIDI {
#endif
double nf_polevl( double x, double coef[], int N );
double nf_p1evl( double x, double coef[], int N );
double nf_exponentialIntegral( int n, double x, nfu_status *status );
double nf_gammaFunction( double x, nfu_status *status );
double nf_logGammaFunction( double x, nfu_status *status );
double nf_incompleteGammaFunction( double a, double x, nfu_status *status );
double nf_incompleteGammaFunctionComplementary( double a, double x, nfu_status *status );
double nf_amc_log_factorial( int );
double nf_amc_factorial( int );
double nf_amc_wigner_3j( int, int, int, int, int, int );
double nf_amc_wigner_6j( int, int, int, int, int, int );
double nf_amc_wigner_9j( int, int, int, int, int, int, int, int, int );
double nf_amc_racah( int, int, int, int, int, int );
double nf_amc_clebsh_gordan( int, int, int, int, int );
double nf_amc_z_coefficient( int, int, int, int, int, int );
double nf_amc_zbar_coefficient( int, int, int, int, int, int );
double nf_amc_reduced_matrix_element( int, int, int, int, int, int, int );
#if defined __cplusplus
}
}
#endif
#endif /* End of ptwXY_h_included. */

Some files were not shown because too many files have changed in this diff Show More