Import Geant4 11.4.0.beta source tree
This commit is contained in:
@@ -6,6 +6,41 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
## 2025-05-24 Vladimir Ivanchenko (hadr-cross-V11-03-05)
|
||||
- G4CrossSectionFactory, G4CrossSectionFactoryRegistry, G4CrossSectionFactory,
|
||||
G4ElectroNuclearCrossSection, G4ChipsAntiBaryonElasticXS - fixed memory leak
|
||||
at exit; value of memory leak is limited but may shadow real problem.
|
||||
|
||||
## 2025-05-22 Vladimir Ivanchenko (hadr-cross-V11-03-04)
|
||||
- G4ChargeExchangeXS - added extra method for sampling of scattering angle,
|
||||
update parameterisation using new fit to data.
|
||||
|
||||
## 2025-04-15 Vladimir Ivanchenko (hadr-cross-V11-03-03)
|
||||
- G4ChargeExchangeXS - fixed selection of reaction for compound materials,
|
||||
for that extra public and private methods are added.
|
||||
|
||||
## 2025-03-31 Vladimir Ivanchenko (hadr-cross-V11-03-02)
|
||||
- G4ParticleInelasticXS - fixed trivial Coverity warning.
|
||||
- G4EMDissociationCrossSection - fixed several technical inaccuracy of the
|
||||
code to address Coverity warning and to use G4Pow correctly.
|
||||
- G4EMDissociationSpectrum - added protection against beta=0, which should never
|
||||
happen but needed for Coverity; use G4Pow more correctly.
|
||||
|
||||
## 2025-03-20 Vladimir Ivanchenko (hadr-cross-V11-03-01)
|
||||
- G4NeutronInelasticXS, G4ParticleInelasticXS - enabled option for initialisation
|
||||
for all Z values, which remove possible lazy initialisation if these cross
|
||||
sections are used by any other model.
|
||||
- G4NeutronElasticXS, G4NeutronCaptureXS - removed option to initilise all
|
||||
data, because these cross sections are not used by other hadronic model.
|
||||
In summary, for simple applications initialisation CPU time is increased
|
||||
for about 10%, for complex applications this increase will not be seen.
|
||||
No locks will be set by these cross section classes in the run time.
|
||||
|
||||
## 2025-02-10 Vladimir Ivanchenko (hadr-cross-V11-03-00)
|
||||
- G4NeutronElasticXS, G4NeutronInelasticXS, G4ParticleInelasticXS - added
|
||||
an option to download data for all elements in class constructor
|
||||
avoiding lazy initialisation in run time
|
||||
|
||||
## 2024-11-15 Vladimir Ivanchenko (hadr-cross-V11-02-18)
|
||||
- G4ChargeExchangeXS - handle special case of positive meson scattering off
|
||||
Hydrogen, the cross section is propotional to the percent of deuterons
|
||||
|
||||
@@ -79,8 +79,13 @@ public:
|
||||
void CrossSectionDescription(std::ostream&) const final;
|
||||
|
||||
const G4ParticleDefinition*
|
||||
SampleSecondaryType(const G4ParticleDefinition*,
|
||||
const G4int Z, const G4int A);
|
||||
SampleSecondaryType(const G4ParticleDefinition*, const G4Material*,
|
||||
G4int Z, G4int A, G4double etot);
|
||||
|
||||
G4double GetPartialPionXS(G4int idx);
|
||||
|
||||
G4double GetPionTFactor(G4int idx, const G4ParticleDefinition* part,
|
||||
G4double pEtot);
|
||||
|
||||
void SetEnergyLimit(G4double val) { fEnergyLimit = val; };
|
||||
|
||||
@@ -93,6 +98,9 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
G4double GetCrossSection(const G4ParticleDefinition*, const G4Material*,
|
||||
G4int Z, G4double etot);
|
||||
|
||||
G4double ComputeDeuteronFraction(const G4Material*);
|
||||
|
||||
G4Pow* g4calc;
|
||||
|
||||
@@ -34,24 +34,31 @@
|
||||
|
||||
class G4VBaseXSFactory
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
G4VBaseXSFactory()
|
||||
{
|
||||
fRegistry = G4CrossSectionFactoryRegistry::Instance();
|
||||
}
|
||||
|
||||
virtual ~G4VBaseXSFactory() = default;
|
||||
|
||||
virtual G4VCrossSectionDataSet* Instantiate() = 0;
|
||||
|
||||
protected:
|
||||
G4CrossSectionFactoryRegistry* fRegistry;
|
||||
};
|
||||
|
||||
|
||||
//Generic template XS-factory
|
||||
template <typename T, int mode> class G4CrossSectionFactory : public G4VBaseXSFactory
|
||||
{
|
||||
public:
|
||||
G4CrossSectionFactory(const G4String& name)
|
||||
{
|
||||
G4CrossSectionFactoryRegistry::Instance()->Register(name,this);
|
||||
fRegistry->Register(name, this);
|
||||
}
|
||||
|
||||
virtual G4VCrossSectionDataSet* Instantiate()
|
||||
|
||||
G4VCrossSectionDataSet* Instantiate() override
|
||||
{
|
||||
G4ExceptionDescription msg;
|
||||
msg<<"Factory mode: "<<mode<<" not supported!";
|
||||
@@ -66,15 +73,15 @@ template <typename T> class G4CrossSectionFactory<T,0> : public G4VBaseXSFactory
|
||||
{
|
||||
public:
|
||||
|
||||
G4CrossSectionFactory(const G4String& name)
|
||||
{
|
||||
G4CrossSectionFactoryRegistry::Instance()->Register(name,this);
|
||||
}
|
||||
|
||||
virtual G4VCrossSectionDataSet* Instantiate()
|
||||
{
|
||||
return new T();
|
||||
}
|
||||
G4CrossSectionFactory(const G4String& name)
|
||||
{
|
||||
fRegistry->Register(name, this);
|
||||
}
|
||||
|
||||
G4VCrossSectionDataSet* Instantiate() override
|
||||
{
|
||||
return new T();
|
||||
}
|
||||
};
|
||||
|
||||
//Partial specialized template for singleton, shared factory
|
||||
@@ -82,32 +89,32 @@ public:
|
||||
template <typename T> class G4CrossSectionFactory<T,1> : public G4VBaseXSFactory
|
||||
{
|
||||
public:
|
||||
G4CrossSectionFactory(const G4String& name)
|
||||
{
|
||||
G4CrossSectionFactoryRegistry::Instance()->Register(name,this);
|
||||
}
|
||||
|
||||
virtual G4VCrossSectionDataSet* Instantiate()
|
||||
{
|
||||
static T* shared = new T();
|
||||
return shared;
|
||||
}
|
||||
G4CrossSectionFactory(const G4String& name)
|
||||
{
|
||||
fRegistry->Register(name,this);
|
||||
}
|
||||
|
||||
G4VCrossSectionDataSet* Instantiate() override
|
||||
{
|
||||
static T* shared = new T();
|
||||
return shared;
|
||||
}
|
||||
};
|
||||
|
||||
//Partial specialized template for singleton, shared factory
|
||||
// each call to Instantiate returns pointer to static thread-local object
|
||||
template <typename T> class G4CrossSectionFactory<T,2> : public G4VBaseXSFactory
|
||||
{
|
||||
G4CrossSectionFactory(const G4String& name)
|
||||
{
|
||||
G4CrossSectionFactoryRegistry::Instance()->Register(name,this);
|
||||
}
|
||||
|
||||
virtual G4VCrossSectionDataSet* Instantiate()
|
||||
{
|
||||
static G4ThreadLocal T* shared = new T();
|
||||
return shared;
|
||||
}
|
||||
G4CrossSectionFactory(const G4String& name)
|
||||
{
|
||||
fRegistry->Register(name,this);
|
||||
}
|
||||
|
||||
G4VCrossSectionDataSet* Instantiate() override
|
||||
{
|
||||
static G4ThreadLocal T* shared = new T();
|
||||
return shared;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -47,19 +47,27 @@ class G4VBaseXSFactory;
|
||||
|
||||
class G4CrossSectionFactoryRegistry
|
||||
{
|
||||
friend std::ostream& operator<<(std::ostream&, const G4CrossSectionFactoryRegistry&);
|
||||
private:
|
||||
std::map<G4String, G4VBaseXSFactory*> factories;
|
||||
static G4CrossSectionFactoryRegistry* instance; //Note this is shared among threads
|
||||
G4CrossSectionFactoryRegistry();
|
||||
G4CrossSectionFactoryRegistry(const G4CrossSectionFactoryRegistry& );
|
||||
G4CrossSectionFactoryRegistry& operator=(const G4CrossSectionFactoryRegistry&);
|
||||
//Disable copy-ctr and assignement operator
|
||||
friend std::ostream& operator<<(std::ostream&, const G4CrossSectionFactoryRegistry&);
|
||||
public:
|
||||
static G4CrossSectionFactoryRegistry* Instance();
|
||||
G4VBaseXSFactory* GetFactory( const G4String& name , G4bool abortIfNotFound = true) const;
|
||||
//Search a cross-section factory by name, by default rise an exception if factory is not found
|
||||
void Register( const G4String& name , G4VBaseXSFactory* factory );
|
||||
static G4CrossSectionFactoryRegistry* Instance();
|
||||
~G4CrossSectionFactoryRegistry() = default;
|
||||
|
||||
G4VBaseXSFactory* GetFactory( const G4String& name, G4bool abortIfNotFound = true) const;
|
||||
|
||||
//Search a cross-section factory by name, by default rise an exception if factory is not found
|
||||
void Register( const G4String& name, G4VBaseXSFactory* factory );
|
||||
|
||||
void DeRegister( G4VBaseXSFactory* factory );
|
||||
|
||||
G4CrossSectionFactoryRegistry(const G4CrossSectionFactoryRegistry&) = delete;
|
||||
G4CrossSectionFactoryRegistry& operator=(const G4CrossSectionFactoryRegistry&) = delete;
|
||||
|
||||
private:
|
||||
|
||||
G4CrossSectionFactoryRegistry();
|
||||
|
||||
std::map<G4String, G4VBaseXSFactory*> factories;
|
||||
static G4CrossSectionFactoryRegistry* instance; //Note this is shared among threads
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& msg, const G4CrossSectionFactoryRegistry& rhs);
|
||||
|
||||
@@ -60,16 +60,16 @@ class G4ElectroNuclearCrossSection : public G4VCrossSectionDataSet
|
||||
public:
|
||||
|
||||
G4ElectroNuclearCrossSection();
|
||||
virtual ~G4ElectroNuclearCrossSection();
|
||||
~G4ElectroNuclearCrossSection() override;
|
||||
|
||||
static const char* Default_Name() {return "ElectroNuclearXS";}
|
||||
|
||||
virtual void CrossSectionDescription(std::ostream&) const;
|
||||
void CrossSectionDescription(std::ostream&) const override;
|
||||
|
||||
virtual G4bool IsElementApplicable(const G4DynamicParticle*, G4int Z,
|
||||
const G4Material*);
|
||||
virtual G4double GetElementCrossSection(const G4DynamicParticle*, G4int Z,
|
||||
const G4Material* mat);
|
||||
G4bool IsElementApplicable(const G4DynamicParticle*, G4int Z,
|
||||
const G4Material*) override;
|
||||
G4double GetElementCrossSection(const G4DynamicParticle*, G4int Z,
|
||||
const G4Material* mat) override;
|
||||
|
||||
G4double GetEquivalentPhotonEnergy();
|
||||
|
||||
@@ -77,6 +77,10 @@ public:
|
||||
|
||||
G4double GetEquivalentPhotonQ2(G4double nu);
|
||||
|
||||
G4ElectroNuclearCrossSection& operator=
|
||||
(const G4ElectroNuclearCrossSection &right) = delete;
|
||||
G4ElectroNuclearCrossSection(const G4ElectroNuclearCrossSection&) = delete;
|
||||
|
||||
private:
|
||||
G4int GetFunctions(G4double a, G4double* x, G4double* y, G4double* z);
|
||||
|
||||
|
||||
@@ -44,8 +44,8 @@
|
||||
|
||||
#include "G4VCrossSectionDataSet.hh"
|
||||
#include "globals.hh"
|
||||
#include "G4ElementData.hh"
|
||||
#include "G4PhysicsVector.hh"
|
||||
#include <vector>
|
||||
|
||||
class G4DynamicParticle;
|
||||
class G4ParticleDefinition;
|
||||
@@ -58,7 +58,7 @@ public:
|
||||
|
||||
G4NeutronElasticXS();
|
||||
|
||||
~G4NeutronElasticXS() final;
|
||||
~G4NeutronElasticXS() override = default;
|
||||
|
||||
static const char* Default_Name() {return "G4NeutronElasticXS";}
|
||||
|
||||
@@ -97,7 +97,7 @@ public:
|
||||
|
||||
G4double ElementCrossSection(G4double kinEnergy, G4double loge, G4int Z);
|
||||
|
||||
G4NeutronElasticXS & operator=(const G4NeutronElasticXS &right) = delete;
|
||||
G4NeutronElasticXS& operator=(const G4NeutronElasticXS &right) = delete;
|
||||
G4NeutronElasticXS(const G4NeutronElasticXS&) = delete;
|
||||
|
||||
private:
|
||||
@@ -108,25 +108,30 @@ private:
|
||||
|
||||
const G4String& FindDirectoryPath();
|
||||
|
||||
inline G4PhysicsVector* GetPhysicsVector(G4int Z);
|
||||
inline const G4PhysicsVector* GetPhysicsVector(G4int Z);
|
||||
|
||||
G4VComponentCrossSection* ggXsection = nullptr;
|
||||
G4PhysicsVector* RetrieveVector(std::ostringstream& in, G4bool warn);
|
||||
|
||||
G4VComponentCrossSection* ggXsection{nullptr};
|
||||
const G4ParticleDefinition* neutron;
|
||||
|
||||
G4bool isFirst = false;
|
||||
G4bool isInitializer{false};
|
||||
|
||||
static const G4int MAXZEL = 93;
|
||||
static G4PhysicsVector* data[MAXZEL];
|
||||
static G4ElementData* data;
|
||||
static G4double coeff[MAXZEL];
|
||||
static G4String gDataDirectory;
|
||||
static G4bool fLock;
|
||||
};
|
||||
|
||||
inline
|
||||
inline const
|
||||
G4PhysicsVector* G4NeutronElasticXS::GetPhysicsVector(G4int Z)
|
||||
{
|
||||
if(nullptr == data[Z]) { InitialiseOnFly(Z); }
|
||||
return data[Z];
|
||||
const G4PhysicsVector* pv = data->GetElementData(Z);
|
||||
if (pv == nullptr) {
|
||||
InitialiseOnFly(Z);
|
||||
pv = data->GetElementData(Z);
|
||||
}
|
||||
return pv;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -107,6 +107,8 @@ private:
|
||||
|
||||
void Initialise(G4int Z);
|
||||
|
||||
void InitialiseOnFly(G4int Z);
|
||||
|
||||
inline const G4PhysicsVector* GetPhysicsVector(G4int Z);
|
||||
|
||||
G4PhysicsVector* RetrieveVector(std::ostringstream& in, G4bool warn);
|
||||
@@ -130,7 +132,7 @@ const G4PhysicsVector* G4ParticleInelasticXS::GetPhysicsVector(G4int Z)
|
||||
{
|
||||
const G4PhysicsVector* pv = data[index]->GetElementData(Z);
|
||||
if (pv == nullptr) {
|
||||
Initialise(Z);
|
||||
InitialiseOnFly(Z);
|
||||
pv = data[index]->GetElementData(Z);
|
||||
}
|
||||
return pv;
|
||||
|
||||
@@ -53,14 +53,22 @@
|
||||
|
||||
namespace {
|
||||
// V. Lyubovitsky parameterisation
|
||||
const G4double piA[5] = {430., 36., 1.37, 2.0, 60.}; // A
|
||||
const G4double pAP[5] = {1.04, 1.26, 1.35, 0.94, 0.94}; // 2 - 2alphaP
|
||||
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
|
||||
const G4double pG0[5] = {2.55, 4.6, 3.7, 5.5, 4.6}; // g0
|
||||
const G4double pG1[5] = {-0.23, -0.5, 0., 0., -2.}; // g1
|
||||
|
||||
const G4double beta_prime_pi = 0.0410;
|
||||
// parameterisation of intranuclear absorption
|
||||
const G4double beta_prime_pi = 0.0036;
|
||||
|
||||
// For unit conversion
|
||||
const G4double inv1e7 = 0.1/(CLHEP::GeV*CLHEP::GeV);
|
||||
const G4double fact = 1e-30*CLHEP::cm2;
|
||||
const G4double pfact = 0.1/CLHEP::GeV;
|
||||
const G4double kfact = 56.3*fact;
|
||||
const G4double csmax = 1e-16;
|
||||
}
|
||||
|
||||
G4ChargeExchangeXS::G4ChargeExchangeXS()
|
||||
@@ -96,20 +104,25 @@ G4bool G4ChargeExchangeXS::IsElementApplicable(const G4DynamicParticle*,
|
||||
}
|
||||
|
||||
G4double
|
||||
G4ChargeExchangeXS::GetElementCrossSection(const G4DynamicParticle* aParticle,
|
||||
G4int ZZ, const G4Material* mat)
|
||||
G4ChargeExchangeXS::GetElementCrossSection(const G4DynamicParticle* dp,
|
||||
G4int Z, const G4Material* mat)
|
||||
{
|
||||
G4double pE = dp->GetTotalEnergy();
|
||||
return (pE > fEnergyLimit) ?
|
||||
GetCrossSection(dp->GetDefinition(), mat, Z, pE) : 0.0;
|
||||
}
|
||||
|
||||
G4double G4ChargeExchangeXS::GetCrossSection(const G4ParticleDefinition* part,
|
||||
const G4Material* mat,
|
||||
G4int ZZ, G4double pEtot)
|
||||
{
|
||||
G4double result = 0.0;
|
||||
const G4double pE = aParticle->GetTotalEnergy();
|
||||
if (pE <= fEnergyLimit) { return result; }
|
||||
|
||||
auto part = aParticle->GetDefinition();
|
||||
G4int pdg = part->GetPDGEncoding();
|
||||
|
||||
// Get or calculate the proton mass, particle mass, and s(Lorentz invariant)
|
||||
G4double tM = CLHEP::proton_mass_c2;
|
||||
G4double pM = part->GetPDGMass();
|
||||
G4double lorentz_s = tM*tM + 2*tM*pE + pM*pM;
|
||||
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);
|
||||
@@ -117,20 +130,15 @@ G4ChargeExchangeXS::GetElementCrossSection(const G4DynamicParticle* aParticle,
|
||||
|
||||
if (verboseLevel > 1) {
|
||||
G4cout << "### G4ChargeExchangeXS: " << part->GetParticleName()
|
||||
<< " Z=" << Z << " A=" << A << " Etot(GeV)=" << pE/CLHEP::GeV
|
||||
<< " Z=" << Z << " A=" << A << " Etot(GeV)=" << pEtot/CLHEP::GeV
|
||||
<< " s(GeV^2)=" << lorentz_s/(CLHEP::GeV*CLHEP::GeV) << G4endl;
|
||||
}
|
||||
|
||||
// For unit conversion
|
||||
const G4double inv1e7 = 0.1/(CLHEP::GeV*CLHEP::GeV);
|
||||
const G4double fact = 1e-30*CLHEP::cm2;
|
||||
const G4double pfact = 0.1/CLHEP::GeV;
|
||||
const G4double kfact = 56.3*fact;
|
||||
const G4double csmax = 1e-16;
|
||||
|
||||
|
||||
// The approximation of Glauber-Gribov formula -> extend it from interaction with
|
||||
// proton to nuclei Z^(2/3). The factor g4calc->powA(A,-beta_prime_pi*G4Log(A))
|
||||
// takes into account absorption of pi0 and eta
|
||||
// takes into account absorption of mesons within the nucleus
|
||||
|
||||
// pi- + p -> n + meson (0- pi0, 1- eta, 2- eta', 3- omega, 4- f2(1270))
|
||||
if (pdg == -211) {
|
||||
@@ -138,7 +146,7 @@ G4ChargeExchangeXS::GetElementCrossSection(const G4DynamicParticle* aParticle,
|
||||
G4double x = lorentz_s*inv1e7;
|
||||
G4double logX = G4Log(x);
|
||||
G4double logA = g4calc->logZ(A);
|
||||
G4double xf = g4calc->powZ(A, -beta_prime_pi*logA);
|
||||
G4double xf = fact*g4calc->powZ(A, -beta_prime_pi*(logA + 2*logA));
|
||||
G4double sum = 0.0;
|
||||
for (G4int i=0; i<5; ++i) {
|
||||
G4double xg = std::max(1.0 + pG0[i] + pG1[i]*logX, 0.0);
|
||||
@@ -147,7 +155,7 @@ G4ChargeExchangeXS::GetElementCrossSection(const G4DynamicParticle* aParticle,
|
||||
sum += xs;
|
||||
fXSecPion[i] = sum;
|
||||
}
|
||||
result = sum*fact;
|
||||
result = sum;
|
||||
}
|
||||
|
||||
// pi+ + n -> p + meson (0- pi0, 1- eta, 2- eta', 3- omega, 4- f2(1270))
|
||||
@@ -156,7 +164,7 @@ G4ChargeExchangeXS::GetElementCrossSection(const G4DynamicParticle* aParticle,
|
||||
G4double x = lorentz_s*inv1e7;
|
||||
G4double logX = G4Log(x);
|
||||
G4double logA = g4calc->logZ(A);
|
||||
G4double xf = g4calc->powZ(A, -beta_prime_pi*logA);
|
||||
G4double xf = fact*g4calc->powZ(A, -beta_prime_pi*(logA + 2*logA));
|
||||
|
||||
// hydrogen target case Z = A = 1
|
||||
// the cross section is defined by fraction of deuteron and tritium
|
||||
@@ -169,19 +177,19 @@ G4ChargeExchangeXS::GetElementCrossSection(const G4DynamicParticle* aParticle,
|
||||
sum += xs;
|
||||
fXSecPion[i] = sum;
|
||||
}
|
||||
result = sum*fact;
|
||||
result = sum;
|
||||
}
|
||||
|
||||
// Kaon x-sections depend on the primary particles momentum
|
||||
// K- + p -> Kbar + n
|
||||
else if (pdg == -321) {
|
||||
G4double p_momentum = std::sqrt(pE*pE - pM*pM)*pfact;
|
||||
G4double p_momentum = std::sqrt(pEtot*pEtot - pM*pM)*pfact;
|
||||
result = g4calc->Z23(Z)*g4calc->powA(p_momentum, -1.60)*kfact;
|
||||
}
|
||||
|
||||
// K+ + n -> Kbar + p
|
||||
else if (pdg == 321) {
|
||||
G4double p_momentum = std::sqrt(pE*pE - pM*pM)*pfact;
|
||||
G4double p_momentum = std::sqrt(pEtot*pEtot - pM*pM)*pfact;
|
||||
G4double n23 = g4calc->Z23(A-Z);
|
||||
// hydrogen target case Z = A = 1
|
||||
// the cross section is defined by fraction of deuteron and tritium
|
||||
@@ -192,13 +200,14 @@ G4ChargeExchangeXS::GetElementCrossSection(const G4DynamicParticle* aParticle,
|
||||
// KL
|
||||
else if (pdg == 130) {
|
||||
// Cross section of KL = 0.5*(Cross section of K+ + Cross section of K-)
|
||||
const G4double p_momentum = std::sqrt(pE*pE - pM*pM)*pfact;
|
||||
const G4double p_momentum = std::sqrt(pEtot*pEtot - pM*pM)*pfact;
|
||||
result = 0.5*(g4calc->Z23(Z) + g4calc->Z23(A-Z))*
|
||||
g4calc->powA(p_momentum, -1.60)*kfact;
|
||||
}
|
||||
result *= fFactor;
|
||||
if (verboseLevel > 1) {
|
||||
G4cout << " Done for " << part->GetParticleName() << " Etot(GeV)=" << pE/CLHEP::GeV
|
||||
G4cout << " Done for " << part->GetParticleName() << " Etot(GeV)="
|
||||
<< pEtot/CLHEP::GeV
|
||||
<< " res(mb)=" << result/CLHEP::millibarn << G4endl;
|
||||
}
|
||||
return result;
|
||||
@@ -206,8 +215,12 @@ G4ChargeExchangeXS::GetElementCrossSection(const G4DynamicParticle* aParticle,
|
||||
|
||||
const G4ParticleDefinition*
|
||||
G4ChargeExchangeXS::SampleSecondaryType(const G4ParticleDefinition* part,
|
||||
const G4int Z, const G4int A)
|
||||
const G4Material* mat,
|
||||
G4int Z, G4int A, G4double etot)
|
||||
{
|
||||
// recompute x-section for the element in complex material
|
||||
GetCrossSection(part, mat, Z, etot);
|
||||
|
||||
const G4ParticleDefinition* pd = nullptr;
|
||||
G4int pdg = std::abs(part->GetPDGEncoding());
|
||||
|
||||
@@ -265,3 +278,26 @@ G4ChargeExchangeXS::ComputeDeuteronFraction(const G4Material* mat)
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
G4double G4ChargeExchangeXS::GetPartialPionXS(G4int idx)
|
||||
{
|
||||
G4double res = 0.0;
|
||||
if (0 == idx) { res = fXSecPion[0]; }
|
||||
else if (0 < idx && 5 > idx) {
|
||||
res = fXSecPion[idx] - fXSecPion[idx - 1];
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -64,7 +64,6 @@ G4_REFERENCE_XS_FACTORY(G4ChipsPionMinusInelasticXS);
|
||||
G4_REFERENCE_XS_FACTORY(G4ChipsPionMinusElasticXS);
|
||||
G4_REFERENCE_XS_FACTORY(G4ChipsAntiBaryonInelasticXS);
|
||||
G4_REFERENCE_XS_FACTORY(G4ChipsAntiBaryonElasticXS);
|
||||
G4_REFERENCE_XS_FACTORY(G4ElectroNuclearCrossSection);
|
||||
|
||||
G4ThreadLocal G4CrossSectionDataSetRegistry* G4CrossSectionDataSetRegistry::instance = nullptr;
|
||||
|
||||
@@ -164,8 +163,8 @@ G4VCrossSectionDataSet*
|
||||
G4CrossSectionDataSetRegistry::GetCrossSectionDataSet(const G4String& name,
|
||||
G4bool warning)
|
||||
{
|
||||
for (auto & xsec : xSections) {
|
||||
if(nullptr != xsec && xsec->GetName() == name) { return xsec; }
|
||||
for (auto const & xsec : xSections) {
|
||||
if (nullptr != xsec && xsec->GetName() == name) { return xsec; }
|
||||
}
|
||||
// check if factory exists...
|
||||
//
|
||||
@@ -174,7 +173,7 @@ G4CrossSectionDataSetRegistry::GetCrossSectionDataSet(const G4String& name,
|
||||
// This throws if factory is not found, add second parameter
|
||||
// to false to avoid this
|
||||
G4VBaseXSFactory* factory = factories->GetFactory(name, warning );
|
||||
if ( factory ) {
|
||||
if (nullptr != factory ) {
|
||||
return factory->Instantiate();
|
||||
} else {
|
||||
G4VCrossSectionDataSet* ptr = nullptr;
|
||||
|
||||
@@ -32,73 +32,63 @@
|
||||
#include "G4AutoLock.hh"
|
||||
#include "globals.hh"
|
||||
|
||||
//This is used to lock on shared resource
|
||||
// G4TypeMutex<G4CrossSectionFactoryRegistry>()
|
||||
namespace
|
||||
{
|
||||
G4Mutex regMutex = G4MUTEX_INITIALIZER;
|
||||
}
|
||||
|
||||
G4CrossSectionFactoryRegistry* G4CrossSectionFactoryRegistry::instance = 0;
|
||||
G4CrossSectionFactoryRegistry* G4CrossSectionFactoryRegistry::Instance()
|
||||
{
|
||||
G4AutoLock l(G4TypeMutex<G4CrossSectionFactoryRegistry>());
|
||||
if (!instance)
|
||||
new G4CrossSectionFactoryRegistry();
|
||||
return instance;
|
||||
static G4CrossSectionFactoryRegistry reg;
|
||||
return ®
|
||||
}
|
||||
|
||||
G4CrossSectionFactoryRegistry::G4CrossSectionFactoryRegistry()
|
||||
{
|
||||
instance = this;
|
||||
}
|
||||
|
||||
G4CrossSectionFactoryRegistry::G4CrossSectionFactoryRegistry(const G4CrossSectionFactoryRegistry&)
|
||||
{
|
||||
G4Exception("G4CrossSectionFactoryRegistry::G4CrossSectionFactoryRegistry",
|
||||
"CrossSection004",FatalException,"Use of copy constructor not allowed");
|
||||
}
|
||||
G4CrossSectionFactoryRegistry& G4CrossSectionFactoryRegistry::operator=(const G4CrossSectionFactoryRegistry&)
|
||||
{
|
||||
G4Exception("G4CrossSectionFactoryRegistry::G4CrossSectionFactoryRegistry",
|
||||
"CrossSection004",FatalException,"Use of assignment operator not allowed");
|
||||
return *this;
|
||||
}
|
||||
{}
|
||||
|
||||
void G4CrossSectionFactoryRegistry::Register( const G4String& name, G4VBaseXSFactory* factory )
|
||||
{
|
||||
G4AutoLock l(G4TypeMutex<G4CrossSectionFactoryRegistry>());
|
||||
if ( factories.find(name) != factories.end() )
|
||||
{
|
||||
G4ExceptionDescription msg;
|
||||
msg <<"Cross section factory with name: "<<name
|
||||
<<" already existing, old factory has been replaced";
|
||||
G4Exception("G4CrossSectionFactoryRegistry::Register(...)",
|
||||
"CrossSection002",JustWarning,msg);
|
||||
if ( factories.find(name) == factories.end() ) {
|
||||
G4AutoLock l(regMutex);
|
||||
if ( factories.find(name) == factories.end() ) {
|
||||
factories[name] = factory;
|
||||
}
|
||||
factories[name] = factory;
|
||||
l.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
G4VBaseXSFactory* G4CrossSectionFactoryRegistry::GetFactory( const G4String& name, G4bool abortIfNotFound ) const
|
||||
void G4CrossSectionFactoryRegistry::DeRegister( G4VBaseXSFactory* factory )
|
||||
{
|
||||
G4AutoLock l(G4TypeMutex<G4CrossSectionFactoryRegistry>());
|
||||
std::map<G4String,G4VBaseXSFactory*>::const_iterator it = factories.find(name);
|
||||
if ( it != factories.end() ) return it->second;
|
||||
else
|
||||
{
|
||||
if ( abortIfNotFound )
|
||||
{
|
||||
G4ExceptionDescription msg;
|
||||
msg <<"Cross section factory with name: "<<name
|
||||
<<" not found.";
|
||||
G4Exception("G4CrossSectionFactoryRegistry::Register(...)",
|
||||
"CrossSection003",FatalException,msg);
|
||||
}
|
||||
if ( nullptr == factory || factories.empty() ) { return; }
|
||||
G4AutoLock l(regMutex);
|
||||
for ( auto const & f : factories ) {
|
||||
if ( factory == f.second ) {
|
||||
factories[f.first] = nullptr;
|
||||
}
|
||||
return static_cast<G4VBaseXSFactory*>(0);
|
||||
}
|
||||
l.unlock();
|
||||
}
|
||||
|
||||
G4VBaseXSFactory*
|
||||
G4CrossSectionFactoryRegistry::GetFactory( const G4String& name, G4bool abortIfNotFound ) const
|
||||
{
|
||||
G4VBaseXSFactory* ptr = nullptr;
|
||||
auto it = factories.find(name);
|
||||
if ( it != factories.end() ) {
|
||||
ptr = it->second;
|
||||
} else if ( abortIfNotFound ) {
|
||||
G4ExceptionDescription msg;
|
||||
msg << "Cross section factory with name: " << name << " not found.";
|
||||
G4Exception("G4CrossSectionFactoryRegistry::GetFactory(...)",
|
||||
"CrossSection003", FatalException, msg);
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& msg, const G4CrossSectionFactoryRegistry& rhs) {
|
||||
msg<<"Factory Registry "<<&rhs<<" has factories: [";
|
||||
for ( std::map<G4String,G4VBaseXSFactory*>::const_iterator it =rhs.factories.begin() ;
|
||||
it != rhs.factories.end() ; ++it )
|
||||
msg<<"Factory Registry "<<&rhs<<" has factories: [";
|
||||
for ( std::map<G4String,G4VBaseXSFactory*>::const_iterator it =rhs.factories.begin();
|
||||
it != rhs.factories.end() ; ++it )
|
||||
{
|
||||
msg<<(*it).first<<":"<<(*it).second<<",";
|
||||
}
|
||||
|
||||
@@ -102,28 +102,16 @@ G4EMDissociationCrossSection::~G4EMDissociationCrossSection()
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4bool
|
||||
G4EMDissociationCrossSection::IsElementApplicable(const G4DynamicParticle* part,
|
||||
G4EMDissociationCrossSection::IsElementApplicable(const G4DynamicParticle*,
|
||||
G4int /*ZZ*/, const G4Material*)
|
||||
{
|
||||
//
|
||||
// The condition for the applicability of this class is that the projectile
|
||||
// must be an ion and the target must have more than one nucleon. In reality
|
||||
// the value of A for either the projectile or target could be much higher,
|
||||
// since for cases where both he projectile and target are medium to small
|
||||
// Z, the probability of the EMD process is, I think, VERY small.
|
||||
//
|
||||
if (G4ParticleTable::GetParticleTable()->GetIonTable()->IsIon(part->GetDefinition())) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4EMDissociationCrossSection::GetElementCrossSection
|
||||
(const G4DynamicParticle* theDynamicParticle, G4int Z,
|
||||
const G4Material*)
|
||||
(const G4DynamicParticle* theDynamicParticle, G4int Z, const G4Material*)
|
||||
{
|
||||
// VI protection for Hydrogen
|
||||
if(1 >= Z) { return 0.0; }
|
||||
|
||||
@@ -79,44 +79,46 @@ G4EMDissociationSpectrum::~G4EMDissociationSpectrum ()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4EMDissociationSpectrum::GetGeneralE1Spectrum
|
||||
(G4double Eg, G4double b, G4double bmin)
|
||||
(G4double Eg, G4double b0, G4double bmin)
|
||||
{
|
||||
G4double b = std::max(b0, 1.e-6);
|
||||
G4double b2 = b*b;
|
||||
G4double gg = 1.0/std::sqrt(1.0-b2);
|
||||
G4double xi = Eg * bmin / gg / b / hbarc;
|
||||
G4double gg = 1.0/std::sqrt(1.0 - b2);
|
||||
G4double xi = Eg * bmin / (gg * b * hbarc);
|
||||
G4double K0 = bessel->K0(xi);
|
||||
G4double K1 = bessel->K1(xi);
|
||||
G4double n = 2.0 * fine_structure_const / pi / b2 / Eg *
|
||||
G4double n = 2.0 * fine_structure_const / (pi * b2 * Eg) *
|
||||
(xi*K0*K1 - xi*xi*b2/2.0*(K1*K1-K0*K0));
|
||||
return n;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4EMDissociationSpectrum::GetGeneralE2Spectrum
|
||||
(G4double Eg, G4double b, G4double bmin)
|
||||
(G4double Eg, G4double b0, G4double bmin)
|
||||
{
|
||||
G4double b = std::max(b0, 1.e-6);
|
||||
G4double b2 = b * b;
|
||||
G4double b4 = b2 * b2;
|
||||
G4double gg = 1.0/std::sqrt(1.0-b2);
|
||||
G4double xi = Eg * bmin / gg / b / hbarc;
|
||||
G4double gg = 1.0/std::sqrt(1.0-b2);
|
||||
G4double xi = Eg * bmin / (gg * b * hbarc);
|
||||
G4double K0 = bessel->K0(xi);
|
||||
G4double K1 = bessel->K1(xi);
|
||||
G4double n = 2.0 * fine_structure_const / pi / b4 / Eg *
|
||||
(2.0*(1.0-b2)*K1*K1 + xi*G4Pow::GetInstance()->powA((2.0-b2),2.0)*K0*K1 -
|
||||
G4double n = 2.0 * fine_structure_const / (pi * b4 * Eg) *
|
||||
(2.0*(1.0-b2)*K1*K1 + xi*(2.0-b2)*(2.0-b2)*K0*K1 -
|
||||
xi*xi*b4/2.0*(K1*K1-K0*K0));
|
||||
return n;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4EMDissociationSpectrum::GetClosestApproach
|
||||
(const G4double AP, const G4double ZP, G4double AT, G4double ZT, G4double b)
|
||||
(const G4double AP, const G4double ZP, G4double AT, G4double ZT, G4double b0)
|
||||
{
|
||||
G4double bsq = b * b;
|
||||
G4double gg = 1.0/std::sqrt(1-bsq);
|
||||
G4double AProot3 = G4Pow::GetInstance()->powA(AP,1.0/3.0);
|
||||
G4double ATroot3 = G4Pow::GetInstance()->powA(AT,1.0/3.0);
|
||||
G4double b = std::max(b0, 1.e-6);
|
||||
G4double bsq = b * b;
|
||||
G4double gg = 1.0/std::sqrt(1. - bsq);
|
||||
G4double AProot3 = G4Pow::GetInstance()->A13(AP);
|
||||
G4double ATroot3 = G4Pow::GetInstance()->A13(AT);
|
||||
G4double bc = 1.34 * fermi * (AProot3+ATroot3 - 0.75 *(1.0/AProot3+1.0/ATroot3));
|
||||
// G4double a0 = ZP * ZT * classic_electr_radius/bsq;
|
||||
G4double a0 = ZP * ZT * elm_coupling / (AT*AP*amu_c2/(AT+AP)) / bsq;
|
||||
G4double bmin = 1.25 * bc + halfpi*a0/gg;
|
||||
return bmin;
|
||||
|
||||
@@ -46,9 +46,9 @@
|
||||
#include "G4ElectroNuclearCrossSection.hh"
|
||||
|
||||
// factory
|
||||
#include "G4CrossSectionFactory.hh"
|
||||
//#include "G4CrossSectionFactory.hh"
|
||||
//
|
||||
G4_DECLARE_XS_FACTORY(G4ElectroNuclearCrossSection);
|
||||
//G4_DECLARE_XS_FACTORY(G4ElectroNuclearCrossSection);
|
||||
|
||||
//
|
||||
//A. Dotti 2-May-2013
|
||||
|
||||
@@ -53,10 +53,11 @@
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
G4PhysicsVector* G4NeutronElasticXS::data[] = {nullptr};
|
||||
G4double G4NeutronElasticXS::coeff[] = {0.0};
|
||||
G4ElementData* G4NeutronElasticXS::data = nullptr;
|
||||
G4double G4NeutronElasticXS::coeff[] = {1.0};
|
||||
G4String G4NeutronElasticXS::gDataDirectory = "";
|
||||
G4bool G4NeutronElasticXS::fLock = true;
|
||||
|
||||
static std::once_flag applyOnce;
|
||||
|
||||
namespace
|
||||
{
|
||||
@@ -67,8 +68,7 @@ G4NeutronElasticXS::G4NeutronElasticXS()
|
||||
: G4VCrossSectionDataSet(Default_Name()),
|
||||
neutron(G4Neutron::Neutron())
|
||||
{
|
||||
// verboseLevel = 0;
|
||||
if (verboseLevel > 0){
|
||||
if (verboseLevel > 0) {
|
||||
G4cout << "G4NeutronElasticXS::G4NeutronElasticXS Initialise for Z < "
|
||||
<< MAXZEL << G4endl;
|
||||
}
|
||||
@@ -77,16 +77,10 @@ G4NeutronElasticXS::G4NeutronElasticXS()
|
||||
if (ggXsection == nullptr)
|
||||
ggXsection = new G4ComponentGGHadronNucleusXsc();
|
||||
SetForAllAtomsAndEnergies(true);
|
||||
FindDirectoryPath();
|
||||
}
|
||||
|
||||
G4NeutronElasticXS::~G4NeutronElasticXS()
|
||||
{
|
||||
if (isFirst) {
|
||||
for(G4int i=0; i<MAXZEL; ++i) {
|
||||
delete data[i];
|
||||
data[i] = nullptr;
|
||||
}
|
||||
if (nullptr == data) {
|
||||
data = new G4ElementData(MAXZEL);
|
||||
data->SetName("nElastic");
|
||||
FindDirectoryPath();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,9 +124,10 @@ G4NeutronElasticXS::ComputeCrossSectionPerElement(G4double ekin, G4double loge,
|
||||
return ElementCrossSection(ekin, loge, elm->GetZasInt());
|
||||
}
|
||||
|
||||
G4double G4NeutronElasticXS::ElementCrossSection(G4double ekin, G4double loge, G4int ZZ)
|
||||
G4double
|
||||
G4NeutronElasticXS::ElementCrossSection(G4double ekin, G4double loge, G4int ZZ)
|
||||
{
|
||||
G4int Z = (ZZ >= MAXZEL) ? MAXZEL - 1 : ZZ;
|
||||
G4int Z = std::min(ZZ, MAXZEL-1);
|
||||
auto pv = GetPhysicsVector(Z);
|
||||
|
||||
G4double xs = (ekin <= pv->GetMaxEnergy()) ? pv->LogVectorValue(ekin, loge)
|
||||
@@ -152,19 +147,21 @@ G4double G4NeutronElasticXS::ElementCrossSection(G4double ekin, G4double loge, G
|
||||
G4double
|
||||
G4NeutronElasticXS::ComputeIsoCrossSection(G4double ekin, G4double loge,
|
||||
const G4ParticleDefinition*,
|
||||
G4int Z, G4int A,
|
||||
G4int ZZ, G4int A,
|
||||
const G4Isotope*, const G4Element*,
|
||||
const G4Material*)
|
||||
{
|
||||
G4int Z = std::min(ZZ, MAXZEL-1);
|
||||
return ElementCrossSection(ekin, loge, Z)*A/aeff[Z];
|
||||
}
|
||||
|
||||
G4double
|
||||
G4NeutronElasticXS::GetIsoCrossSection(const G4DynamicParticle* aParticle,
|
||||
G4int Z, G4int A,
|
||||
G4int ZZ, G4int A,
|
||||
const G4Isotope*, const G4Element*,
|
||||
const G4Material*)
|
||||
{
|
||||
G4int Z = std::min(ZZ, MAXZEL-1);
|
||||
return ElementCrossSection(aParticle->GetKineticEnergy(),
|
||||
aParticle->GetLogKineticEnergy(), Z)*A/aeff[Z];
|
||||
|
||||
@@ -176,7 +173,6 @@ const G4Isotope* G4NeutronElasticXS::SelectIsotope(
|
||||
G4int nIso = (G4int)anElement->GetNumberOfIsotopes();
|
||||
const G4Isotope* iso = anElement->GetIsotope(0);
|
||||
|
||||
//G4cout << "SelectIsotope NIso= " << nIso << G4endl;
|
||||
if(1 == nIso) { return iso; }
|
||||
|
||||
const G4double* abundVector = anElement->GetRelativeAbundanceVector();
|
||||
@@ -209,19 +205,17 @@ G4NeutronElasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
|
||||
FatalException, ed, "");
|
||||
return;
|
||||
}
|
||||
if (fLock || isFirst) {
|
||||
// initialise static tables only once
|
||||
std::call_once(applyOnce, [this]() { isInitializer = true; });
|
||||
|
||||
if (isInitializer) {
|
||||
G4AutoLock l(&nElasticXSMutex);
|
||||
if (fLock) {
|
||||
isFirst = true;
|
||||
fLock = false;
|
||||
FindDirectoryPath();
|
||||
}
|
||||
|
||||
// Access to elements
|
||||
const G4ElementTable* table = G4Element::GetElementTable();
|
||||
for ( auto & elm : *table ) {
|
||||
for ( auto const & elm : *table ) {
|
||||
G4int Z = std::max( 1, std::min( elm->GetZasInt(), MAXZEL-1) );
|
||||
if ( nullptr == data[Z] ) { Initialise(Z); }
|
||||
if ( nullptr == data->GetElementData(Z) ) { Initialise(Z); }
|
||||
}
|
||||
l.unlock();
|
||||
}
|
||||
@@ -247,40 +241,49 @@ void G4NeutronElasticXS::InitialiseOnFly(G4int Z)
|
||||
|
||||
void G4NeutronElasticXS::Initialise(G4int Z)
|
||||
{
|
||||
if(data[Z] != nullptr) { return; }
|
||||
|
||||
// upload data from file
|
||||
data[Z] = new G4PhysicsLogVector();
|
||||
if (nullptr != data->GetElementData(Z)) { return; }
|
||||
|
||||
// upload element data
|
||||
std::ostringstream ost;
|
||||
ost << FindDirectoryPath() << Z ;
|
||||
std::ifstream filein(ost.str().c_str());
|
||||
if (!filein.is_open()) {
|
||||
G4ExceptionDescription ed;
|
||||
ed << "Data file <" << ost.str().c_str()
|
||||
<< "> is not opened!";
|
||||
G4Exception("G4NeutronElasticXS::Initialise(..)","had014",
|
||||
FatalException, ed, "Check G4PARTICLEXSDATA");
|
||||
return;
|
||||
}
|
||||
if(verboseLevel > 1) {
|
||||
G4cout << "file " << ost.str()
|
||||
<< " is opened by G4NeutronElasticXS" << G4endl;
|
||||
}
|
||||
|
||||
// retrieve data from DB
|
||||
if(!data[Z]->Retrieve(filein, true)) {
|
||||
G4ExceptionDescription ed;
|
||||
ed << "Data file <" << ost.str().c_str()
|
||||
<< "> is not retrieved!";
|
||||
G4Exception("G4NeutronElasticXS::Initialise(..)","had015",
|
||||
FatalException, ed, "Check G4PARTICLEXSDATA");
|
||||
return;
|
||||
}
|
||||
ost << FindDirectoryPath() << Z;
|
||||
G4PhysicsVector* v = RetrieveVector(ost, true);
|
||||
data->InitialiseForElement(Z, v);
|
||||
|
||||
// smooth transition
|
||||
G4double sig1 = (*(data[Z]))[data[Z]->GetVectorLength()-1];
|
||||
G4double ehigh = data[Z]->GetMaxEnergy();
|
||||
G4double sig2 = ggXsection->GetElasticElementCrossSection(neutron,
|
||||
ehigh, Z, aeff[Z]);
|
||||
G4double sig1 = (*v)[v->GetVectorLength()-1];
|
||||
G4double ehigh = v->GetMaxEnergy();
|
||||
G4double sig2 =
|
||||
ggXsection->GetElasticElementCrossSection(neutron, ehigh, Z, aeff[Z]);
|
||||
coeff[Z] = (sig2 > 0.) ? sig1/sig2 : 1.0;
|
||||
}
|
||||
|
||||
G4PhysicsVector*
|
||||
G4NeutronElasticXS::RetrieveVector(std::ostringstream& ost, G4bool warn)
|
||||
{
|
||||
G4PhysicsLogVector* v = nullptr;
|
||||
std::ifstream filein(ost.str().c_str());
|
||||
if (!filein.is_open()) {
|
||||
if (warn) {
|
||||
G4ExceptionDescription ed;
|
||||
ed << "Data file <" << ost.str().c_str()
|
||||
<< "> is not opened!";
|
||||
G4Exception("G4NeutronElasticXS::RetrieveVector(..)","had014",
|
||||
FatalException, ed, "Check G4PARTICLEXSDATA");
|
||||
}
|
||||
} else {
|
||||
if (verboseLevel > 1) {
|
||||
G4cout << "File " << ost.str()
|
||||
<< " is opened by G4NeutronElasticXS" << G4endl;
|
||||
}
|
||||
// retrieve data from DB
|
||||
v = new G4PhysicsLogVector();
|
||||
if (!v->Retrieve(filein, true)) {
|
||||
G4ExceptionDescription ed;
|
||||
ed << "Data file <" << ost.str().c_str()
|
||||
<< "> is not retrieved!";
|
||||
G4Exception("G4NeutronElasticXS::RetrieveVector(..)","had015",
|
||||
FatalException, ed, "Check G4PARTICLEXSDATA");
|
||||
}
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
@@ -78,15 +78,17 @@ G4NeutronInelasticXS::G4NeutronInelasticXS()
|
||||
<< MAXZINEL << G4endl;
|
||||
}
|
||||
loglowElimit = G4Log(lowElimit);
|
||||
ggXsection =
|
||||
G4CrossSectionDataSetRegistry::Instance()->GetComponentCrossSection("Glauber-Gribov");
|
||||
if (ggXsection == nullptr)
|
||||
ggXsection = new G4ComponentGGHadronNucleusXsc();
|
||||
|
||||
if (nullptr == data) {
|
||||
data = new G4ElementData(MAXZINEL);
|
||||
data->SetName("nInelastic");
|
||||
FindDirectoryPath();
|
||||
for (G4int Z=1; Z<MAXZINEL; ++Z) { Initialise(Z); }
|
||||
}
|
||||
ggXsection =
|
||||
G4CrossSectionDataSetRegistry::Instance()->GetComponentCrossSection("Glauber-Gribov");
|
||||
if(ggXsection == nullptr)
|
||||
ggXsection = new G4ComponentGGHadronNucleusXsc();
|
||||
|
||||
SetForAllAtomsAndEnergies(true);
|
||||
}
|
||||
@@ -199,19 +201,28 @@ G4NeutronInelasticXS::IsoCrossSection(G4double eKin, G4double logE,
|
||||
G4double ekin = eKin;
|
||||
G4double loge = logE;
|
||||
|
||||
/*
|
||||
G4cout << "G4NeutronInelasticXS::IsoCrossSection Z= "
|
||||
<< Z << " A= " << A << G4endl;
|
||||
G4cout << " Amin= " << amin[Z] << " Amax= " << amax[Z]
|
||||
<< " E(MeV)= " << ekin << " Ncomp="
|
||||
<< data->GetNumberOfComponents(Z) << G4endl;
|
||||
*/
|
||||
// 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;
|
||||
}
|
||||
#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;
|
||||
}
|
||||
const G4double e0 = pviso->Energy(0);
|
||||
if (ekin > e0) {
|
||||
xs = pviso->LogVectorValue(ekin, loge);
|
||||
@@ -277,8 +288,6 @@ const G4Isotope* G4NeutronInelasticXS::SelectIsotope(
|
||||
if(nn < nIso) { temp.resize(nIso, 0.); }
|
||||
|
||||
for (j=0; j<nIso; ++j) {
|
||||
// G4cout << j << "-th isotope " << anElement->GetIsotope(j)->GetN()
|
||||
// << " abund= " << abundVector[j] << G4endl;
|
||||
sum += abundVector[j]*IsoCrossSection(kinEnergy, logE, Z,
|
||||
anElement->GetIsotope((G4int)j)->GetN());
|
||||
temp[j] = sum;
|
||||
|
||||
@@ -71,6 +71,7 @@ G4ParticleInelasticXS::G4ParticleInelasticXS(const G4ParticleDefinition* part)
|
||||
particle(part),
|
||||
elimit(20*CLHEP::MeV)
|
||||
{
|
||||
auto xsr = G4CrossSectionDataSetRegistry::Instance();
|
||||
if (nullptr == part) {
|
||||
G4Exception("G4ParticleInelasticXS::G4ParticleInelasticXS(..)","had015",
|
||||
FatalException, "NO particle definition in constructor");
|
||||
@@ -81,7 +82,6 @@ G4ParticleInelasticXS::G4ParticleInelasticXS(const G4ParticleDefinition* part)
|
||||
G4cout << "G4ParticleInelasticXS::G4ParticleInelasticXS for "
|
||||
<< particleName << " on atoms with Z < " << MAXZINELP << G4endl;
|
||||
}
|
||||
auto xsr = G4CrossSectionDataSetRegistry::Instance();
|
||||
if (particleName == "proton") {
|
||||
highEnergyXsection = xsr->GetComponentCrossSection("Glauber-Gribov");
|
||||
if(highEnergyXsection == nullptr) {
|
||||
@@ -100,6 +100,10 @@ G4ParticleInelasticXS::G4ParticleInelasticXS(const G4ParticleDefinition* part)
|
||||
if (1 < index) { SetMaxKinEnergy(25.6*CLHEP::PeV); }
|
||||
}
|
||||
}
|
||||
// this should never happens but ...
|
||||
if (nullptr == highEnergyXsection) {
|
||||
highEnergyXsection = xsr->GetComponentCrossSection("Glauber-Gribov");
|
||||
}
|
||||
SetForAllAtomsAndEnergies(true);
|
||||
if (gDataDirectory.empty()) {
|
||||
gDataDirectory = G4HadronicParameters::Instance()->GetDirPARTICLEXS();
|
||||
@@ -109,6 +113,7 @@ G4ParticleInelasticXS::G4ParticleInelasticXS(const G4ParticleDefinition* part)
|
||||
if (data[index] == nullptr) {
|
||||
data[index] = new G4ElementData(MAXZINELP);
|
||||
data[index]->SetName(pname[index] + "PartInel");
|
||||
for (G4int Z=1; Z<MAXZINELP; ++Z) { Initialise(Z); }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -320,53 +325,55 @@ G4ParticleInelasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
|
||||
if (n > nIso) { nIso = n; }
|
||||
G4int Z = std::min( elm->GetZasInt(), MAXZINELP-1);
|
||||
if ( nullptr == (data[index])->GetElementData(Z) ) {
|
||||
Initialise(Z);
|
||||
InitialiseOnFly(Z);
|
||||
}
|
||||
}
|
||||
temp.resize(nIso, 0.0);
|
||||
}
|
||||
|
||||
void G4ParticleInelasticXS::InitialiseOnFly(G4int Z)
|
||||
{
|
||||
G4AutoLock l(&pInelasticXSMutex);
|
||||
Initialise(Z);
|
||||
l.unlock();
|
||||
}
|
||||
|
||||
void G4ParticleInelasticXS::Initialise(G4int Z)
|
||||
{
|
||||
if ( nullptr != (data[index])->GetElementData(Z) ) { return; }
|
||||
|
||||
G4AutoLock l(&pInelasticXSMutex);
|
||||
if ( nullptr == (data[index])->GetElementData(Z) ) {
|
||||
// upload element data
|
||||
std::ostringstream ost;
|
||||
ost << gDataDirectory << "/" << pname[index] << "/inel" << Z;
|
||||
G4PhysicsVector* v = RetrieveVector(ost, true);
|
||||
data[index]->InitialiseForElement(Z, v);
|
||||
// upload element data
|
||||
std::ostringstream ost;
|
||||
ost << gDataDirectory << "/" << pname[index] << "/inel" << Z;
|
||||
G4PhysicsVector* v = RetrieveVector(ost, true);
|
||||
data[index]->InitialiseForElement(Z, v);
|
||||
|
||||
// upload isotope data
|
||||
G4bool noComp = true;
|
||||
if (amin[Z] < amax[Z]) {
|
||||
|
||||
for (G4int A=amin[Z]; A<=amax[Z]; ++A) {
|
||||
std::ostringstream ost1;
|
||||
ost1 << gDataDirectory << "/" << pname[index] << "/inel" << Z << "_" << A;
|
||||
G4PhysicsVector* v1 = RetrieveVector(ost1, false);
|
||||
if (nullptr != v1) {
|
||||
if (noComp) {
|
||||
G4int nmax = amax[Z] - A + 1;
|
||||
data[index]->InitialiseForComponent(Z, nmax);
|
||||
noComp = false;
|
||||
}
|
||||
data[index]->AddComponent(Z, A, v1);
|
||||
// upload isotope data
|
||||
G4bool noComp = true;
|
||||
if (amin[Z] < amax[Z]) {
|
||||
for (G4int A=amin[Z]; A<=amax[Z]; ++A) {
|
||||
std::ostringstream ost1;
|
||||
ost1 << gDataDirectory << "/" << pname[index] << "/inel" << Z << "_" << A;
|
||||
G4PhysicsVector* v1 = RetrieveVector(ost1, false);
|
||||
if (nullptr != v1) {
|
||||
if (noComp) {
|
||||
G4int nmax = amax[Z] - A + 1;
|
||||
data[index]->InitialiseForComponent(Z, nmax);
|
||||
noComp = false;
|
||||
}
|
||||
data[index]->AddComponent(Z, A, v1);
|
||||
}
|
||||
}
|
||||
// no components case
|
||||
if (noComp) { data[index]->InitialiseForComponent(Z, 0); }
|
||||
|
||||
// smooth transition
|
||||
G4double sig1 = (*v)[v->GetVectorLength()-1];
|
||||
G4double ehigh = v->GetMaxEnergy();
|
||||
G4double sig2 = highEnergyXsection->GetInelasticElementCrossSection(
|
||||
particle, ehigh, Z, aeff[Z]);
|
||||
coeff[Z][index] = (sig2 > 0.) ? sig1/sig2 : 1.0;
|
||||
}
|
||||
l.unlock();
|
||||
// no components case
|
||||
if (noComp) { data[index]->InitialiseForComponent(Z, 0); }
|
||||
|
||||
// smooth transition
|
||||
G4double sig1 = (*v)[v->GetVectorLength()-1];
|
||||
G4double ehigh = v->GetMaxEnergy();
|
||||
G4double sig2 = highEnergyXsection->GetInelasticElementCrossSection(
|
||||
particle, ehigh, Z, aeff[Z]);
|
||||
coeff[Z][index] = (sig2 > 0.) ? sig1/sig2 : 1.0;
|
||||
}
|
||||
|
||||
G4PhysicsVector*
|
||||
|
||||
Reference in New Issue
Block a user