Import Geant4 11.4.0 source tree
This commit is contained in:
@@ -6,6 +6,27 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
## 2025-11-24 Vladimir Ivanchenko (hadr-cross-V11-03-09)
|
||||
- G4EMDissociationCrossSection - fixed compilation warning
|
||||
|
||||
## 2025-11-06 Vladimir Ivanchenko (hadr-cross-V11-03-08)
|
||||
- G4ChargeExchangeXS - fixed units inside SampleTforPion(..) method
|
||||
- G4NeutronInelasticXS, G4NeutronElasticXS, G4NeutronCaptureXS - added extra
|
||||
flag to enable/disable reading and usage of precise data in resonance
|
||||
region, which will allow to reduce RSS memory for simple applications,
|
||||
for applications required higher precision of neutron transport the
|
||||
flag should be defined via G4HadronicParameters::SetUseRFilesForXS(true).
|
||||
|
||||
## 2025-10-27 Vladimir Ivanchenko (hadr-cross-V11-03-07)
|
||||
- G4ChargeExchangeXS - added extra method SampleTforPion(..), which is based on
|
||||
the V. Lyubovitsky parameterisation for different reaction channels.
|
||||
|
||||
## 2025-09-30 Vladimir Ivanchenko (hadr-cross-V11-03-06)
|
||||
- G4NeutronInelasticXS, G4NeutronElasticXS, G4NeutronCaptureXS - split data
|
||||
tables on two parts: low-energy for neutron resonance region and high
|
||||
energy above this region. This allows increase accuracy of neutron cross
|
||||
sections for non HP (for example, HEP) applications.
|
||||
|
||||
## 2025-05-24 Vladimir Ivanchenko (hadr-cross-V11-03-05)
|
||||
- G4CrossSectionFactory, G4CrossSectionFactoryRegistry, G4CrossSectionFactory,
|
||||
G4ElectroNuclearCrossSection, G4ChipsAntiBaryonElasticXS - fixed memory leak
|
||||
|
||||
@@ -82,32 +82,36 @@ public:
|
||||
SampleSecondaryType(const G4ParticleDefinition*, const G4Material*,
|
||||
G4int Z, G4int A, G4double etot);
|
||||
|
||||
G4double GetPartialPionXS(G4int idx);
|
||||
|
||||
G4double GetPionTFactor(G4int idx, const G4ParticleDefinition* part,
|
||||
G4double pEtot);
|
||||
|
||||
G4double GetPartialPionXS(G4int idx) const;
|
||||
|
||||
void SetEnergyLimit(G4double val) { fEnergyLimit = val; };
|
||||
|
||||
void SetCrossSectionFactor(G4double val) { fFactor = val; };
|
||||
|
||||
G4double GetCrossSectionFactor() const { return fFactor; };
|
||||
|
||||
G4bool isPion() const { return findex >= 0; };
|
||||
|
||||
G4double SampleTforPion(const G4double etot,
|
||||
const G4double tmax) const;
|
||||
|
||||
G4ChargeExchangeXS & operator=(const G4ChargeExchangeXS &right) = delete;
|
||||
G4ChargeExchangeXS(const G4ChargeExchangeXS&) = delete;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
G4double GetCrossSection(const G4ParticleDefinition*, const G4Material*,
|
||||
G4int Z, G4double etot);
|
||||
|
||||
G4double ComputeDeuteronFraction(const G4Material*);
|
||||
G4double ComputeDeuteronFraction(const G4Material*) const;
|
||||
|
||||
G4Pow* g4calc;
|
||||
G4int findex{-1};
|
||||
const G4ParticleDefinition* fPionSecPD[5];
|
||||
G4double fXSecPion[5] = {0.0, 0.0, 0.0, 0.0, 0.0};
|
||||
G4double fEnergyLimit{0.0};
|
||||
G4double fFactor{1.0};
|
||||
G4double fMassPi;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -114,6 +114,8 @@ private:
|
||||
|
||||
inline const G4PhysicsVector* GetPhysicsVector(G4int Z);
|
||||
|
||||
inline const G4PhysicsVector* GetPhysicsVectorR(G4int Z);
|
||||
|
||||
G4PhysicsVector* RetrieveVector(std::ostringstream& in, G4bool warn);
|
||||
|
||||
G4double emax;
|
||||
@@ -123,8 +125,10 @@ private:
|
||||
std::vector<G4double> temp;
|
||||
|
||||
G4bool isInitializer{false};
|
||||
G4bool fRfilesEnabled{false};
|
||||
|
||||
static G4ElementData* data;
|
||||
static G4ElementData* dataR;
|
||||
static G4String gDataDirectory;
|
||||
};
|
||||
|
||||
@@ -132,11 +136,22 @@ inline
|
||||
const G4PhysicsVector* G4NeutronCaptureXS::GetPhysicsVector(G4int Z)
|
||||
{
|
||||
const G4PhysicsVector* pv = data->GetElementData(Z);
|
||||
if(pv == nullptr) {
|
||||
if (pv == nullptr) {
|
||||
InitialiseOnFly(Z);
|
||||
pv = data->GetElementData(Z);
|
||||
}
|
||||
return pv;
|
||||
}
|
||||
|
||||
inline
|
||||
const G4PhysicsVector* G4NeutronCaptureXS::GetPhysicsVectorR(G4int Z)
|
||||
{
|
||||
const G4PhysicsVector* pv = dataR->GetElementData(Z);
|
||||
if (pv == nullptr) {
|
||||
InitialiseOnFly(Z);
|
||||
pv = dataR->GetElementData(Z);
|
||||
}
|
||||
return pv;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -110,15 +110,19 @@ private:
|
||||
|
||||
inline const G4PhysicsVector* GetPhysicsVector(G4int Z);
|
||||
|
||||
inline const G4PhysicsVector* GetPhysicsVectorR(G4int Z);
|
||||
|
||||
G4PhysicsVector* RetrieveVector(std::ostringstream& in, G4bool warn);
|
||||
|
||||
G4VComponentCrossSection* ggXsection{nullptr};
|
||||
const G4ParticleDefinition* neutron;
|
||||
|
||||
G4bool isInitializer{false};
|
||||
G4bool fRfilesEnabled{false};
|
||||
|
||||
static const G4int MAXZEL = 93;
|
||||
static G4ElementData* data;
|
||||
static G4ElementData* dataR;
|
||||
static G4double coeff[MAXZEL];
|
||||
static G4String gDataDirectory;
|
||||
};
|
||||
@@ -134,4 +138,15 @@ G4PhysicsVector* G4NeutronElasticXS::GetPhysicsVector(G4int Z)
|
||||
return pv;
|
||||
}
|
||||
|
||||
inline
|
||||
const G4PhysicsVector* G4NeutronElasticXS::GetPhysicsVectorR(G4int Z)
|
||||
{
|
||||
const G4PhysicsVector* pv = dataR->GetElementData(Z);
|
||||
if (pv == nullptr) {
|
||||
InitialiseOnFly(Z);
|
||||
pv = dataR->GetElementData(Z);
|
||||
}
|
||||
return pv;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -112,6 +112,8 @@ private:
|
||||
|
||||
inline const G4PhysicsVector* GetPhysicsVector(G4int Z);
|
||||
|
||||
inline const G4PhysicsVector* GetPhysicsVectorR(G4int Z);
|
||||
|
||||
G4PhysicsVector* RetrieveVector(std::ostringstream& in, G4bool warn);
|
||||
|
||||
G4VComponentCrossSection* ggXsection = nullptr;
|
||||
@@ -120,14 +122,15 @@ private:
|
||||
|
||||
std::vector<G4double> temp;
|
||||
|
||||
G4double elimit;
|
||||
G4double lowElimit;
|
||||
G4double loglowElimit;
|
||||
|
||||
G4bool isInitializer{false};
|
||||
G4bool fRfilesEnabled{false};
|
||||
|
||||
static const G4int MAXZINEL = 93;
|
||||
static G4ElementData* data;
|
||||
static G4ElementData* dataR;
|
||||
static G4double coeff[MAXZINEL];
|
||||
static G4double lowcoeff[MAXZINEL];
|
||||
static G4String gDataDirectory;
|
||||
@@ -144,4 +147,15 @@ const G4PhysicsVector* G4NeutronInelasticXS::GetPhysicsVector(G4int Z)
|
||||
return pv;
|
||||
}
|
||||
|
||||
inline
|
||||
const G4PhysicsVector* G4NeutronInelasticXS::GetPhysicsVectorR(G4int Z)
|
||||
{
|
||||
const G4PhysicsVector* pv = dataR->GetElementData(Z);
|
||||
if (pv == nullptr) {
|
||||
InitialiseOnFly(Z);
|
||||
pv = dataR->GetElementData(Z);
|
||||
}
|
||||
return pv;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -44,16 +44,18 @@
|
||||
#include "G4Pow.hh"
|
||||
|
||||
#include "G4PionZero.hh"
|
||||
#include "G4PionPlus.hh"
|
||||
#include "G4Eta.hh"
|
||||
#include "G4KaonZeroLong.hh"
|
||||
#include "G4KaonZeroShort.hh"
|
||||
#include "G4KaonPlus.hh"
|
||||
#include "G4KaonMinus.hh"
|
||||
#include "G4ParticleTable.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
|
||||
namespace {
|
||||
// V. Lyubovitsky parameterisation
|
||||
const G4double piA[5] = {122., 78.8, 59.4, 24.0, 213.5}; // A
|
||||
const G4double piA[5] = {122., 78.8, 59.4, 24.0, 213.5};// A
|
||||
const G4double pAP[5] = {1.23, 1.53, 1.35, 0.94, 0.94}; // 2 - 2alphaP
|
||||
const G4double pC0[5] = {12.7, 6.0, 6.84, 6.5, 8.0}; // c0
|
||||
const G4double pC1[5] = {1.57, 1.6, 1.7, 1.23, 2.6}; // c1
|
||||
@@ -63,8 +65,9 @@ namespace {
|
||||
// parameterisation of intranuclear absorption
|
||||
const G4double beta_prime_pi = 0.0036;
|
||||
|
||||
// For unit conversion
|
||||
const G4double inv1e7 = 0.1/(CLHEP::GeV*CLHEP::GeV);
|
||||
// For unit conversion
|
||||
const G4double GeV2 = (CLHEP::GeV*CLHEP::GeV);
|
||||
const G4double inv1e7 = 0.1/GeV2;
|
||||
const G4double fact = 1e-30*CLHEP::cm2;
|
||||
const G4double pfact = 0.1/CLHEP::GeV;
|
||||
const G4double kfact = 56.3*fact;
|
||||
@@ -76,6 +79,7 @@ G4ChargeExchangeXS::G4ChargeExchangeXS()
|
||||
if (verboseLevel > 1) {
|
||||
G4cout << "G4ChargeExchangeXS::G4ChargeExchangeXS" << G4endl;
|
||||
}
|
||||
fMassPi = G4PionPlus::PionPlus()->GetPDGMass();
|
||||
g4calc = G4Pow::GetInstance();
|
||||
auto table = G4ParticleTable::GetParticleTable();
|
||||
const G4String nam[5] = {"pi0", "eta", "eta_prime", "omega", "f2(1270)"};
|
||||
@@ -123,6 +127,7 @@ G4double G4ChargeExchangeXS::GetCrossSection(const G4ParticleDefinition* part,
|
||||
G4double tM = CLHEP::proton_mass_c2;
|
||||
G4double pM = part->GetPDGMass();
|
||||
G4double lorentz_s = tM*tM + 2*tM*pEtot + pM*pM;
|
||||
|
||||
if (lorentz_s <= (tM + pM)*(tM + pM)) { return result; }
|
||||
|
||||
const G4int Z = std::min(ZZ, ZMAXNUCLEARDATA);
|
||||
@@ -131,11 +136,9 @@ G4double G4ChargeExchangeXS::GetCrossSection(const G4ParticleDefinition* part,
|
||||
if (verboseLevel > 1) {
|
||||
G4cout << "### G4ChargeExchangeXS: " << part->GetParticleName()
|
||||
<< " Z=" << Z << " A=" << A << " Etot(GeV)=" << pEtot/CLHEP::GeV
|
||||
<< " s(GeV^2)=" << lorentz_s/(CLHEP::GeV*CLHEP::GeV) << G4endl;
|
||||
<< " s(GeV^2)=" << lorentz_s/GeV2 << G4endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// The approximation of Glauber-Gribov formula -> extend it from interaction with
|
||||
// proton to nuclei Z^(2/3). The factor g4calc->powA(A,-beta_prime_pi*G4Log(A))
|
||||
// takes into account absorption of mesons within the nucleus
|
||||
@@ -218,19 +221,21 @@ G4ChargeExchangeXS::SampleSecondaryType(const G4ParticleDefinition* part,
|
||||
const G4Material* mat,
|
||||
G4int Z, G4int A, G4double etot)
|
||||
{
|
||||
// index of pion partial x-section
|
||||
findex = -1;
|
||||
// recompute x-section for the element in complex material
|
||||
GetCrossSection(part, mat, Z, etot);
|
||||
|
||||
const G4ParticleDefinition* pd = nullptr;
|
||||
G4int pdg = std::abs(part->GetPDGEncoding());
|
||||
|
||||
G4cout << pdg << G4endl;
|
||||
// pi- + p / pi+ + n
|
||||
if (pdg == 211) {
|
||||
pd = fPionSecPD[0];
|
||||
G4double x = fXSecPion[4]*G4UniformRand();
|
||||
for (G4int i=0; i<5; ++i) {
|
||||
if (x <= fXSecPion[i]) {
|
||||
pd = fPionSecPD[i];
|
||||
for (findex = 0; findex < 5; ++findex) {
|
||||
if (x <= fXSecPion[findex]) {
|
||||
pd = fPionSecPD[findex];
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -257,12 +262,39 @@ G4ChargeExchangeXS::SampleSecondaryType(const G4ParticleDefinition* part,
|
||||
pd = G4KaonPlus::KaonPlus();
|
||||
}
|
||||
}
|
||||
|
||||
if (verboseLevel > 1) {
|
||||
G4cout << "G4ChargeExchangeXS::SampleSecondaryType for "
|
||||
<< pd->GetParticleName() << " findex=" << findex
|
||||
<< G4endl;
|
||||
}
|
||||
return pd;
|
||||
}
|
||||
|
||||
G4double G4ChargeExchangeXS::SampleTforPion(const G4double etot,
|
||||
const G4double ltmax) const
|
||||
{
|
||||
G4double tmax = ltmax/GeV2;
|
||||
G4double tM = CLHEP::proton_mass_c2;
|
||||
G4double logX = G4Log((tM*tM + 2*tM*etot + fMassPi*fMassPi)*inv1e7);
|
||||
|
||||
G4double gl = pG0[findex] + pG1[findex]*logX;
|
||||
G4double cl = pC0[findex] + pC1[findex]*logX;
|
||||
G4double gc = gl*cl;
|
||||
|
||||
G4double t{0};
|
||||
G4double sigmaMax = (gc > 0.0) ? gl*G4Exp(-(gl - 1.0)/gl) : 1.0;
|
||||
for (G4int i = 0; i < 100000; ++i) {
|
||||
t = tmax*G4UniformRand();
|
||||
G4double sigma = (1.0 + gc*t)*G4Exp(-cl*t);
|
||||
if (G4UniformRand()*sigmaMax <= sigma) {
|
||||
return t*GeV2;
|
||||
}
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
G4double
|
||||
G4ChargeExchangeXS::ComputeDeuteronFraction(const G4Material* mat)
|
||||
G4ChargeExchangeXS::ComputeDeuteronFraction(const G4Material* mat) const
|
||||
{
|
||||
for (auto const & elm : *mat->GetElementVector()) {
|
||||
if (1 == elm->GetZasInt()) {
|
||||
@@ -279,7 +311,7 @@ G4ChargeExchangeXS::ComputeDeuteronFraction(const G4Material* mat)
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
G4double G4ChargeExchangeXS::GetPartialPionXS(G4int idx)
|
||||
G4double G4ChargeExchangeXS::GetPartialPionXS(G4int idx) const
|
||||
{
|
||||
G4double res = 0.0;
|
||||
if (0 == idx) { res = fXSecPion[0]; }
|
||||
@@ -288,16 +320,3 @@ G4double G4ChargeExchangeXS::GetPartialPionXS(G4int idx)
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
G4double G4ChargeExchangeXS::GetPionTFactor(G4int idx,
|
||||
const G4ParticleDefinition* p,
|
||||
G4double pEtot)
|
||||
{
|
||||
if (idx < 0 || idx > 4) { return 0.0; }
|
||||
G4double tM = CLHEP::proton_mass_c2;
|
||||
G4double pM = p->GetPDGMass();
|
||||
G4double logX = G4Log((tM*tM + 2*tM*pEtot + pM*pM)*inv1e7);
|
||||
G4double xg = std::max(pG0[idx] + pG1[idx]*logX, -1.0);
|
||||
G4double xc = std::max(pC0[idx] + pC1[idx]*logX, 0.0);
|
||||
return xc*xg;
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ G4double G4EMDissociationCrossSection::GetElementCrossSection
|
||||
G4double AP = definitionP->GetBaryonNumber();
|
||||
G4double ZP = definitionP->GetPDGCharge();
|
||||
G4double b = theDynamicParticle->GetBeta();
|
||||
if (b <= 0.0 && b >= 1.0) { return 0.0; }
|
||||
if (b <= 0.0) { return 0.0; }
|
||||
|
||||
G4double AT = G4NistManager::Instance()->GetAtomicMassAmu(Z);
|
||||
G4double ZT = (G4double)Z;
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
#include "G4AutoLock.hh"
|
||||
|
||||
G4ElementData* G4NeutronCaptureXS::data = nullptr;
|
||||
G4ElementData* G4NeutronCaptureXS::dataR = nullptr;
|
||||
G4String G4NeutronCaptureXS::gDataDirectory = "";
|
||||
|
||||
static std::once_flag applyOnce;
|
||||
@@ -76,6 +77,8 @@ G4NeutronCaptureXS::G4NeutronCaptureXS()
|
||||
if (nullptr == data) {
|
||||
data = new G4ElementData(MAXZCAPTURE+1);
|
||||
data->SetName("nCapture");
|
||||
dataR = new G4ElementData(MAXZCAPTURE+1);
|
||||
dataR->SetName("nRCapture");
|
||||
FindDirectoryPath();
|
||||
}
|
||||
}
|
||||
@@ -141,15 +144,31 @@ G4NeutronCaptureXS::ElementCrossSection(G4double eKin, G4double logE, G4int ZZ)
|
||||
logEkin = logElimit;
|
||||
}
|
||||
|
||||
auto pv = GetPhysicsVector(Z);
|
||||
const G4double e0 = pv->Energy(0);
|
||||
G4double xs = (ekin >= e0) ? pv->LogVectorValue(ekin, logEkin)
|
||||
: (*pv)[0]*std::sqrt(e0/ekin);
|
||||
G4double xs;
|
||||
G4bool done{false};
|
||||
|
||||
// data from the resonance region
|
||||
if (fRfilesEnabled) {
|
||||
auto pv = GetPhysicsVectorR(Z);
|
||||
if (nullptr != pv && ekin < cap_max_r_e[Z]) {
|
||||
const G4double e0 = pv->Energy(0);
|
||||
xs = (ekin >= e0) ? pv->LogVectorValue(ekin, logEkin)
|
||||
: (*pv)[0]*std::sqrt(e0/ekin);
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
// data above the resonance region
|
||||
if (!done) {
|
||||
auto pv = GetPhysicsVector(Z);
|
||||
const G4double e0 = pv->Energy(0);
|
||||
xs = (ekin >= e0) ? pv->LogVectorValue(ekin, logEkin)
|
||||
: (*pv)[0]*std::sqrt(e0/ekin);
|
||||
}
|
||||
|
||||
#ifdef G4VERBOSE
|
||||
if (verboseLevel > 1){
|
||||
G4cout << "Ekin= " << ekin/CLHEP::MeV
|
||||
<< " ElmXScap(b)= " << xs/CLHEP::barn << G4endl;
|
||||
G4cout << "Ekin= " << ekin/CLHEP::MeV
|
||||
<< " ElmXScap(b)= " << xs/CLHEP::barn << G4endl;
|
||||
}
|
||||
#endif
|
||||
return xs;
|
||||
@@ -190,34 +209,55 @@ G4double G4NeutronCaptureXS::IsoCrossSection(G4double eKin, G4double logE,
|
||||
logEkin = logElimit;
|
||||
}
|
||||
|
||||
auto pv = GetPhysicsVector(Z);
|
||||
if (pv == nullptr) { return xs; }
|
||||
G4bool done{false};
|
||||
|
||||
// use isotope x-section if possible
|
||||
if (data->GetNumberOfComponents(Z) > 0) {
|
||||
G4PhysicsVector* pviso = data->GetComponentDataByID(Z, A);
|
||||
if(pviso != nullptr) {
|
||||
const G4double e0 = pviso->Energy(0);
|
||||
xs = (ekin >= e0) ? pviso->LogVectorValue(ekin, logEkin)
|
||||
: (*pviso)[0]*std::sqrt(e0/ekin);
|
||||
#ifdef G4VERBOSE
|
||||
if(verboseLevel > 0) {
|
||||
G4cout << "G4NeutronCaptureXS::IsoXS: Ekin(MeV)= " << ekin/MeV
|
||||
<< " xs(b)= " << xs/barn
|
||||
<< " Z= " << Z << " A= " << A << G4endl;
|
||||
// data from the resonance region
|
||||
if (fRfilesEnabled) {
|
||||
auto pv = GetPhysicsVectorR(Z);
|
||||
if (nullptr != pv && ekin < cap_max_r_e[Z]) {
|
||||
// use isotope x-section if possible
|
||||
if (dataR->GetNumberOfComponents(Z) > 0) {
|
||||
auto pviso = dataR->GetComponentDataByID(Z, A);
|
||||
if (pviso != nullptr) {
|
||||
const G4double e0 = pviso->Energy(0);
|
||||
xs = (ekin >= e0) ? pviso->LogVectorValue(ekin, logEkin)
|
||||
: (*pviso)[0]*std::sqrt(e0/ekin);
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
// isotope data are not available or applicable
|
||||
if (!done) {
|
||||
const G4double e0 = pv->Energy(0);
|
||||
xs = (ekin >= e0) ? pv->LogVectorValue(ekin, logEkin)
|
||||
: (*pv)[0]*std::sqrt(e0/ekin);
|
||||
done = true;
|
||||
}
|
||||
#endif
|
||||
return xs;
|
||||
}
|
||||
}
|
||||
// isotope data are not available or applicable
|
||||
const G4double e0 = pv->Energy(0);
|
||||
xs = (ekin >= e0) ? pv->LogVectorValue(ekin, logEkin)
|
||||
: (*pv)[0]*std::sqrt(e0/ekin);
|
||||
// data above the resonance region
|
||||
if (!done) {
|
||||
auto pv = GetPhysicsVector(Z);
|
||||
// use isotope x-section if possible
|
||||
if (data->GetNumberOfComponents(Z) > 0) {
|
||||
auto pviso = data->GetComponentDataByID(Z, A);
|
||||
if (pviso != nullptr) {
|
||||
const G4double e0 = pviso->Energy(0);
|
||||
xs = (ekin >= e0) ? pviso->LogVectorValue(ekin, logEkin)
|
||||
: (*pviso)[0]*std::sqrt(e0/ekin);
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
// isotope data are not available or applicable
|
||||
if (!done) {
|
||||
const G4double e0 = pv->Energy(0);
|
||||
xs = (ekin >= e0) ? pv->LogVectorValue(ekin, logEkin)
|
||||
: (*pv)[0]*std::sqrt(e0/ekin);
|
||||
}
|
||||
}
|
||||
#ifdef G4VERBOSE
|
||||
if (verboseLevel > 0) {
|
||||
G4cout << "G4NeutronCaptureXS::IsoXS: Ekin(MeV)= " << ekin/MeV
|
||||
<< " xs(b)= " << xs/barn
|
||||
<< " xs(b)= " << xs/CLHEP::barn
|
||||
<< " Z= " << Z << " A= " << A << " no iso XS" << G4endl;
|
||||
}
|
||||
#endif
|
||||
@@ -247,7 +287,7 @@ G4NeutronCaptureXS::SelectIsotope(const G4Element* anElement,
|
||||
if (Z > MAXZCAPTURE || 0 == data->GetNumberOfComponents(Z)) {
|
||||
for (j = 0; j<nIso; ++j) {
|
||||
sum += abundVector[j];
|
||||
if(q <= sum) {
|
||||
if (q <= sum) {
|
||||
iso = anElement->GetIsotope(j);
|
||||
break;
|
||||
}
|
||||
@@ -288,6 +328,8 @@ G4NeutronCaptureXS::BuildPhysicsTable(const G4ParticleDefinition& p)
|
||||
return;
|
||||
}
|
||||
|
||||
fRfilesEnabled = G4HadronicParameters::Instance()->UseRFilesForXS();
|
||||
|
||||
// it is possible re-initialisation for the second run
|
||||
const G4ElementTable* table = G4Element::GetElementTable();
|
||||
|
||||
@@ -318,7 +360,7 @@ const G4String& G4NeutronCaptureXS::FindDirectoryPath()
|
||||
// build the complete string identifying the file with the data set
|
||||
if(gDataDirectory.empty()) {
|
||||
std::ostringstream ost;
|
||||
ost << G4HadronicParameters::Instance()->GetDirPARTICLEXS() << "/neutron/cap";
|
||||
ost << G4HadronicParameters::Instance()->GetDirPARTICLEXS() << "/neutron/";
|
||||
gDataDirectory = ost.str();
|
||||
}
|
||||
return gDataDirectory;
|
||||
@@ -337,16 +379,24 @@ void G4NeutronCaptureXS::Initialise(G4int Z)
|
||||
|
||||
// upload element data
|
||||
std::ostringstream ost;
|
||||
ost << FindDirectoryPath() << Z ;
|
||||
ost << FindDirectoryPath() << "cap" << Z;
|
||||
G4PhysicsVector* v = RetrieveVector(ost, true);
|
||||
data->InitialiseForElement(Z, v);
|
||||
G4PhysicsVector* vr = nullptr;
|
||||
if (fRfilesEnabled) {
|
||||
std::ostringstream ostr;
|
||||
ostr << FindDirectoryPath() << "Rcap" << Z;
|
||||
vr = RetrieveVector(ostr, false);
|
||||
dataR->InitialiseForElement(Z, vr);
|
||||
}
|
||||
|
||||
// upload isotope data
|
||||
G4bool noComp = true;
|
||||
G4bool noCompR = true;
|
||||
if (amin[Z] < amax[Z]) {
|
||||
for(G4int A=amin[Z]; A<=amax[Z]; ++A) {
|
||||
for (G4int A=amin[Z]; A<=amax[Z]; ++A) {
|
||||
std::ostringstream ost1;
|
||||
ost1 << gDataDirectory << Z << "_" << A;
|
||||
ost1 << gDataDirectory << "cap" << Z << "_" << A;
|
||||
G4PhysicsVector* v1 = RetrieveVector(ost1, false);
|
||||
if (nullptr != v1) {
|
||||
if (noComp) {
|
||||
@@ -356,10 +406,24 @@ void G4NeutronCaptureXS::Initialise(G4int Z)
|
||||
}
|
||||
data->AddComponent(Z, A, v1);
|
||||
}
|
||||
if (nullptr != vr) {
|
||||
std::ostringstream ost2;
|
||||
ost2 << gDataDirectory << "Rcap" << Z << "_" << A;
|
||||
G4PhysicsVector* v2 = RetrieveVector(ost2, false);
|
||||
if (nullptr != v2) {
|
||||
if (noCompR) {
|
||||
G4int nmax = amax[Z] - A + 1;
|
||||
dataR->InitialiseForComponent(Z, nmax);
|
||||
noCompR = false;
|
||||
}
|
||||
dataR->AddComponent(Z, A, v2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// no components case
|
||||
if (noComp) { data->InitialiseForComponent(Z, 0); }
|
||||
if (noCompR && nullptr != vr) { dataR->InitialiseForComponent(Z, 0); }
|
||||
}
|
||||
|
||||
G4PhysicsVector*
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
#include <sstream>
|
||||
|
||||
G4ElementData* G4NeutronElasticXS::data = nullptr;
|
||||
G4ElementData* G4NeutronElasticXS::dataR = nullptr;
|
||||
G4double G4NeutronElasticXS::coeff[] = {1.0};
|
||||
G4String G4NeutronElasticXS::gDataDirectory = "";
|
||||
|
||||
@@ -80,6 +81,8 @@ G4NeutronElasticXS::G4NeutronElasticXS()
|
||||
if (nullptr == data) {
|
||||
data = new G4ElementData(MAXZEL);
|
||||
data->SetName("nElastic");
|
||||
dataR = new G4ElementData(MAXZEL);
|
||||
dataR->SetName("nRElastic");
|
||||
FindDirectoryPath();
|
||||
}
|
||||
}
|
||||
@@ -128,14 +131,27 @@ G4double
|
||||
G4NeutronElasticXS::ElementCrossSection(G4double ekin, G4double loge, G4int ZZ)
|
||||
{
|
||||
G4int Z = std::min(ZZ, MAXZEL-1);
|
||||
auto pv = GetPhysicsVector(Z);
|
||||
|
||||
G4double xs = (ekin <= pv->GetMaxEnergy()) ? pv->LogVectorValue(ekin, loge)
|
||||
: coeff[Z]*ggXsection->GetElasticElementCrossSection(neutron, ekin,
|
||||
Z, aeff[Z]);
|
||||
G4double xs;
|
||||
G4bool done{false};
|
||||
|
||||
// data from the resonance region
|
||||
if (fRfilesEnabled) {
|
||||
auto pv = GetPhysicsVectorR(Z);
|
||||
if (nullptr != pv && ekin < el_max_r_e[Z]) {
|
||||
xs = pv->LogVectorValue(ekin, loge);
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
// data above the resonance region
|
||||
if (!done) {
|
||||
auto pv = GetPhysicsVector(Z);
|
||||
xs = (ekin <= pv->GetMaxEnergy()) ? pv->LogVectorValue(ekin, loge)
|
||||
: coeff[Z]*ggXsection->GetElasticElementCrossSection(neutron, ekin,
|
||||
Z, aeff[Z]);
|
||||
}
|
||||
|
||||
#ifdef G4VERBOSE
|
||||
if(verboseLevel > 1) {
|
||||
if (verboseLevel > 1) {
|
||||
G4cout << "Z= " << Z << " Ekin(MeV)= " << ekin/CLHEP::MeV
|
||||
<< ", nElmXSel(b)= " << xs/CLHEP::barn
|
||||
<< G4endl;
|
||||
@@ -205,6 +221,9 @@ G4NeutronElasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
|
||||
FatalException, ed, "");
|
||||
return;
|
||||
}
|
||||
|
||||
fRfilesEnabled = G4HadronicParameters::Instance()->UseRFilesForXS();
|
||||
|
||||
// initialise static tables only once
|
||||
std::call_once(applyOnce, [this]() { isInitializer = true; });
|
||||
|
||||
@@ -226,7 +245,7 @@ const G4String& G4NeutronElasticXS::FindDirectoryPath()
|
||||
// build the complete string identifying the file with the data set
|
||||
if (gDataDirectory.empty()) {
|
||||
std::ostringstream ost;
|
||||
ost << G4HadronicParameters::Instance()->GetDirPARTICLEXS() << "/neutron/el";
|
||||
ost << G4HadronicParameters::Instance()->GetDirPARTICLEXS() << "/neutron/";
|
||||
gDataDirectory = ost.str();
|
||||
}
|
||||
return gDataDirectory;
|
||||
@@ -245,10 +264,18 @@ void G4NeutronElasticXS::Initialise(G4int Z)
|
||||
|
||||
// upload element data
|
||||
std::ostringstream ost;
|
||||
ost << FindDirectoryPath() << Z;
|
||||
ost << FindDirectoryPath() << "el" << Z;
|
||||
G4PhysicsVector* v = RetrieveVector(ost, true);
|
||||
data->InitialiseForElement(Z, v);
|
||||
|
||||
G4PhysicsVector* vr = nullptr;
|
||||
if (fRfilesEnabled) {
|
||||
std::ostringstream ostr;
|
||||
ostr << FindDirectoryPath() << "Rel" << Z;
|
||||
vr = RetrieveVector(ostr, false);
|
||||
dataR->InitialiseForElement(Z, vr);
|
||||
}
|
||||
|
||||
// smooth transition
|
||||
G4double sig1 = (*v)[v->GetVectorLength()-1];
|
||||
G4double ehigh = v->GetMaxEnergy();
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
G4double G4NeutronInelasticXS::coeff[] = {1.0};
|
||||
G4double G4NeutronInelasticXS::lowcoeff[] = {1.0};
|
||||
G4ElementData* G4NeutronInelasticXS::data = nullptr;
|
||||
G4ElementData* G4NeutronInelasticXS::dataR = nullptr;
|
||||
G4String G4NeutronInelasticXS::gDataDirectory = "";
|
||||
|
||||
static std::once_flag applyOnce;
|
||||
@@ -69,7 +70,6 @@ namespace
|
||||
G4NeutronInelasticXS::G4NeutronInelasticXS()
|
||||
: G4VCrossSectionDataSet(Default_Name()),
|
||||
neutron(G4Neutron::Neutron()),
|
||||
elimit(20*CLHEP::MeV),
|
||||
lowElimit(1.0e-7*CLHEP::eV)
|
||||
{
|
||||
verboseLevel = 0;
|
||||
@@ -86,6 +86,8 @@ G4NeutronInelasticXS::G4NeutronInelasticXS()
|
||||
if (nullptr == data) {
|
||||
data = new G4ElementData(MAXZINEL);
|
||||
data->SetName("nInelastic");
|
||||
dataR = new G4ElementData(MAXZINEL);
|
||||
dataR->SetName("nRInelastic");
|
||||
FindDirectoryPath();
|
||||
for (G4int Z=1; Z<MAXZINEL; ++Z) { Initialise(Z); }
|
||||
}
|
||||
@@ -140,25 +142,33 @@ G4NeutronInelasticXS::ElementCrossSection(G4double eKin, G4double logE, G4int ZZ
|
||||
G4int Z = std::min(ZZ, MAXZINEL-1);
|
||||
G4double ekin = eKin;
|
||||
G4double loge = logE;
|
||||
G4double xs;
|
||||
G4double xs{0.0};
|
||||
G4bool done{false};
|
||||
|
||||
// very low energy limit
|
||||
if (ekin < lowElimit) {
|
||||
ekin = lowElimit;
|
||||
loge = loglowElimit;
|
||||
}
|
||||
// pv should exist
|
||||
auto pv = GetPhysicsVector(Z);
|
||||
|
||||
const G4double e0 = pv->Energy(0);
|
||||
if (ekin <= e0) {
|
||||
xs = (*pv)[0];
|
||||
if (xs > 0.0) { xs *= std::sqrt(e0/ekin); }
|
||||
} else if (ekin <= pv->GetMaxEnergy()) {
|
||||
xs = pv->LogVectorValue(ekin, loge);
|
||||
} else {
|
||||
xs = coeff[Z]*ggXsection->GetInelasticElementCrossSection(neutron, ekin,
|
||||
Z, aeff[Z]);
|
||||
// data from the resonance region
|
||||
if (fRfilesEnabled) {
|
||||
auto pv = GetPhysicsVectorR(Z);
|
||||
if (nullptr != pv && ekin < inel_max_r_e[Z]) {
|
||||
xs = pv->LogVectorValue(ekin, loge);
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
// data above the resonance region pv should always defined
|
||||
if (!done) {
|
||||
auto pv = GetPhysicsVector(Z);
|
||||
if (ekin <= pv->GetMaxEnergy()) {
|
||||
xs = pv->LogVectorValue(ekin, loge);
|
||||
}
|
||||
else {
|
||||
xs = coeff[Z]*ggXsection->GetInelasticElementCrossSection(neutron, ekin,
|
||||
Z, aeff[Z]);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef G4VERBOSE
|
||||
@@ -193,60 +203,59 @@ G4NeutronInelasticXS::GetIsoCrossSection(const G4DynamicParticle* aParticle,
|
||||
}
|
||||
|
||||
G4double
|
||||
G4NeutronInelasticXS::IsoCrossSection(G4double eKin, G4double logE,
|
||||
G4NeutronInelasticXS::IsoCrossSection(G4double ekin, G4double loge,
|
||||
G4int ZZ, G4int A)
|
||||
{
|
||||
G4double xs;
|
||||
G4double xs{0.0};
|
||||
G4int Z = std::min(ZZ, MAXZINEL-1);
|
||||
G4double ekin = eKin;
|
||||
G4double loge = logE;
|
||||
G4bool done{false};
|
||||
|
||||
// Check initialisation
|
||||
GetPhysicsVector(Z);
|
||||
|
||||
#ifdef G4VERBOSE
|
||||
if (verboseLevel > 2) {
|
||||
G4cout << "G4NeutronInelasticXS::IsoCrossSection Z= "
|
||||
<< Z << " A= " << A << G4endl;
|
||||
G4cout << " Amin= " << amin[Z] << " Amax= " << amax[Z]
|
||||
<< " E(MeV)= " << ekin << " Ncomp="
|
||||
<< data->GetNumberOfComponents(Z) << G4endl;
|
||||
// data from the resonance region
|
||||
if (fRfilesEnabled) {
|
||||
auto pv = GetPhysicsVectorR(Z);
|
||||
if (nullptr != pv && ekin < inel_max_r_e[Z]) {
|
||||
// use isotope x-section if possible
|
||||
if (dataR->GetNumberOfComponents(Z) > 0) {
|
||||
auto pviso = dataR->GetComponentDataByID(Z, A);
|
||||
if (pviso != nullptr) {
|
||||
xs = pviso->LogVectorValue(ekin, loge);
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
// isotope data are not available or applicable
|
||||
if (!done) {
|
||||
xs = pv->LogVectorValue(ekin, loge);
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// use isotope cross section if applicable
|
||||
if (ekin <= elimit && data->GetNumberOfComponents(Z) > 0) {
|
||||
auto pviso = data->GetComponentDataByID(Z, A);
|
||||
if (nullptr != pviso) {
|
||||
// very low energy limit
|
||||
if (ekin < lowElimit) {
|
||||
ekin = lowElimit;
|
||||
loge = loglowElimit;
|
||||
// data above the resonance region
|
||||
if (!done) {
|
||||
auto pv = GetPhysicsVector(Z);
|
||||
// use isotope x-section if possible
|
||||
if (data->GetNumberOfComponents(Z) > 0) {
|
||||
auto pviso = data->GetComponentDataByID(Z, A);
|
||||
if (pviso != nullptr && ekin <= pviso->GetMaxEnergy()) {
|
||||
xs = pviso->LogVectorValue(ekin, loge);
|
||||
done = true;
|
||||
}
|
||||
const G4double e0 = pviso->Energy(0);
|
||||
if (ekin > e0) {
|
||||
xs = pviso->LogVectorValue(ekin, loge);
|
||||
} else {
|
||||
xs = (*pviso)[0];
|
||||
if (xs > 0.0) { xs *= std::sqrt(e0/ekin); }
|
||||
}
|
||||
// isotope data are not available or applicable
|
||||
// use element x-section
|
||||
if (!done) {
|
||||
if (ekin <= pv->GetMaxEnergy()) {
|
||||
xs = pv->LogVectorValue(ekin, loge);
|
||||
}
|
||||
#ifdef G4VERBOSE
|
||||
if(verboseLevel > 1) {
|
||||
G4cout << "G4NeutronInelasticXS::IsoXS: Ekin(MeV)= "
|
||||
<< ekin/CLHEP::MeV
|
||||
<< " xs(b)= " << xs/CLHEP::barn
|
||||
<< " Z= " << Z << " A= " << A << G4endl;
|
||||
else {
|
||||
xs = coeff[Z]*
|
||||
ggXsection->GetInelasticElementCrossSection(neutron, ekin,
|
||||
Z, aeff[Z]);
|
||||
}
|
||||
#endif
|
||||
return xs;
|
||||
}
|
||||
}
|
||||
|
||||
// use element x-section
|
||||
xs = ElementCrossSection(ekin, loge, Z)*A/aeff[Z];
|
||||
|
||||
#ifdef G4VERBOSE
|
||||
if(verboseLevel > 1) {
|
||||
if (verboseLevel > 1) {
|
||||
G4cout << "G4NeutronInelasticXS::IsoXS: Z= " << Z << " A= " << A
|
||||
<< " Ekin(MeV)= " << ekin/CLHEP::MeV
|
||||
<< ", ElmXS(b)= " << xs/CLHEP::barn << G4endl;
|
||||
@@ -289,7 +298,7 @@ const G4Isotope* G4NeutronInelasticXS::SelectIsotope(
|
||||
|
||||
for (j=0; j<nIso; ++j) {
|
||||
sum += abundVector[j]*IsoCrossSection(kinEnergy, logE, Z,
|
||||
anElement->GetIsotope((G4int)j)->GetN());
|
||||
anElement->GetIsotope((G4int)j)->GetN());
|
||||
temp[j] = sum;
|
||||
}
|
||||
sum *= q;
|
||||
@@ -317,6 +326,9 @@ G4NeutronInelasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
|
||||
FatalException, ed, "");
|
||||
return;
|
||||
}
|
||||
|
||||
fRfilesEnabled = G4HadronicParameters::Instance()->UseRFilesForXS();
|
||||
|
||||
// it is possible re-initialisation for the new run
|
||||
const G4ElementTable* table = G4Element::GetElementTable();
|
||||
|
||||
@@ -347,7 +359,7 @@ const G4String& G4NeutronInelasticXS::FindDirectoryPath()
|
||||
// build the complete string identifying the file with the data set
|
||||
if (gDataDirectory.empty()) {
|
||||
std::ostringstream ost;
|
||||
ost << G4HadronicParameters::Instance()->GetDirPARTICLEXS() << "/neutron/inel";
|
||||
ost << G4HadronicParameters::Instance()->GetDirPARTICLEXS() << "/neutron/";
|
||||
gDataDirectory = ost.str();
|
||||
}
|
||||
return gDataDirectory;
|
||||
@@ -366,21 +378,26 @@ void G4NeutronInelasticXS::Initialise(G4int Z)
|
||||
|
||||
// upload element data
|
||||
std::ostringstream ost;
|
||||
ost << FindDirectoryPath() << Z;
|
||||
ost << FindDirectoryPath() << "inel" << Z;
|
||||
G4PhysicsVector* v = RetrieveVector(ost, true);
|
||||
data->InitialiseForElement(Z, v);
|
||||
if (verboseLevel > 1) {
|
||||
G4cout << "G4NeutronInelasticXS::Initialise for Z= " << Z
|
||||
<< " A= " << aeff[Z] << " Amin= " << amin[Z]
|
||||
<< " Amax= " << amax[Z] << G4endl;
|
||||
|
||||
G4PhysicsVector* vr = nullptr;
|
||||
if (fRfilesEnabled) {
|
||||
std::ostringstream ostr;
|
||||
ostr << FindDirectoryPath() << "Rinel" << Z;
|
||||
vr = RetrieveVector(ostr, false);
|
||||
dataR->InitialiseForElement(Z, vr);
|
||||
}
|
||||
|
||||
// upload isotope data
|
||||
G4bool noComp = true;
|
||||
G4bool noCompR = true;
|
||||
if (amin[Z] < amax[Z]) {
|
||||
|
||||
for (G4int A=amin[Z]; A<=amax[Z]; ++A) {
|
||||
std::ostringstream ost1;
|
||||
ost1 << gDataDirectory << Z << "_" << A;
|
||||
ost1 << gDataDirectory << "inel" << Z << "_" << A;
|
||||
G4PhysicsVector* v1 = RetrieveVector(ost1, false);
|
||||
if (nullptr != v1) {
|
||||
if (noComp) {
|
||||
@@ -390,10 +407,24 @@ void G4NeutronInelasticXS::Initialise(G4int Z)
|
||||
}
|
||||
data->AddComponent(Z, A, v1);
|
||||
}
|
||||
if (nullptr != vr) {
|
||||
std::ostringstream ost2;
|
||||
ost2 << gDataDirectory << "Rinel" << Z << "_" << A;
|
||||
G4PhysicsVector* v2 = RetrieveVector(ost2, false);
|
||||
if (nullptr != v2) {
|
||||
if (noCompR) {
|
||||
G4int nmax = amax[Z] - A + 1;
|
||||
dataR->InitialiseForComponent(Z, nmax);
|
||||
noCompR = false;
|
||||
}
|
||||
dataR->AddComponent(Z, A, v2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// no components case
|
||||
if (noComp) { data->InitialiseForComponent(Z, 0); }
|
||||
if (noCompR) { dataR->InitialiseForComponent(Z, 0); }
|
||||
|
||||
// smooth transition
|
||||
G4double sig1 = (*v)[v->GetVectorLength()-1];
|
||||
@@ -409,7 +440,7 @@ G4NeutronInelasticXS::RetrieveVector(std::ostringstream& ost, G4bool warn)
|
||||
G4PhysicsLogVector* v = nullptr;
|
||||
std::ifstream filein(ost.str().c_str());
|
||||
if (!filein.is_open()) {
|
||||
if(warn) {
|
||||
if (warn) {
|
||||
G4ExceptionDescription ed;
|
||||
ed << "Data file <" << ost.str().c_str()
|
||||
<< "> is not opened!";
|
||||
@@ -417,13 +448,13 @@ G4NeutronInelasticXS::RetrieveVector(std::ostringstream& ost, G4bool warn)
|
||||
FatalException, ed, "Check G4PARTICLEXSDATA");
|
||||
}
|
||||
} else {
|
||||
if(verboseLevel > 1) {
|
||||
if (verboseLevel > 1) {
|
||||
G4cout << "File " << ost.str()
|
||||
<< " is opened by G4NeutronInelasticXS" << G4endl;
|
||||
}
|
||||
// retrieve data from DB
|
||||
v = new G4PhysicsLogVector();
|
||||
if(!v->Retrieve(filein, true)) {
|
||||
if (!v->Retrieve(filein, true)) {
|
||||
G4ExceptionDescription ed;
|
||||
ed << "Data file <" << ost.str().c_str()
|
||||
<< "> is not retrieved!";
|
||||
|
||||
Reference in New Issue
Block a user