Import Geant4 11.3.0.beta source tree

This commit is contained in:
Gabriele Cosmo
2024-06-28 13:08:51 +02:00
parent f7b23877ed
commit e58e650b32
5232 changed files with 239416 additions and 244360 deletions
@@ -6,7 +6,46 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2023-12-09 Vladimir Ivanchenko (hadr-cross-V11-01-17)
## 2024-06-18 Vladimir Ivanchenko (hadr-cross-V11-02-06)
- G4BGGNucleonInelasticXS - fixed proton x-section below 14 MeV
## 2024-03-12 Gabriele Cosmo (hadr-cross-V11-02-05)
- In G4NeutronInelasticXS::SelectIsotope(), fixed compilation warnings for
implicit type conversions detected with macOS/XCode.
## 2024-03-09 Vladimir Ivanchenko (hadr-cross-V11-02-04)
- G4ComponentGGNuclNuclXsc - removed debug printout, added check of G4VERBOSE
- G4BGGPionElasticXS, G4BGGNucleonInelasticXS, G4BGGNucleonElasticXS - added
check of G4VERBOSE compilation flag
- G4vCrossSectionDataSet - cosmetic change
## 2024-03-07 Vladimir Ivanchenko (hadr-cross-V11-02-03)
- G4HadronXSDataTable - make this class to be a singleton for registration
and destruction of sttic objects with cross section data, data are deleted
only end of run
- G4BGGNucleonElasticXS, G4BGGNucleonInelasticXS, G4BGGPionElasticXS,
G4BGGPionInelasticXS, G4ComponentBarNucleonNucleusXsc,
G4UPiNuclearCrossSection, G4HadronNucleonXsc, G4CrossSectionDataSetRegistry
- code clean-up: removed "isMaster" checks, removed mutex locks,
removed unused variables and format the code
## 2024-03-05 Vladimir Ivanchenko (hadr-cross-V11-02-02)
- G4BGGNucleonElasticXS, G4BGGNucleonInelasticXS, G4NeutronInelasticXS,
G4ComponentBarNucleonNucleusXsc, G4ComponentGGNuclNuclXsc, G4PiData,
G4NucleonNuclearCrossSection - general clean-up of proton and neutron
cross sections: removed unused methods, removed not needed mutex locks,
improved printouts, cross sections outside data tables are equal to
low or high edge of a table (not zero).
## 2024-02-22 Vladimir Ivanchenko (hadr-cross-V11-02-01)
- G4NeutronCapture - lowest energy limit is set to 10^-5 eV, below this
energy no computations to avoid numerical problems, improved comments to
the code
- G4NeutronInelastic - implement 1/v cross section dependence below low-energy
limit of a cross section vector if cross section does not start from null
- G4IsotopeList.hh - moved to util sublibrary
## 2023-12-09 Vladimir Ivanchenko (hadr-cross-V11-02-00)
- G4KokoulinMuonNuclearXS - use faster interface to G4PhysicsVector
- G4ElectroNuclearCrossSection - added low-energy limit 100 MeV for x-section
@@ -51,7 +51,6 @@
#include "globals.hh"
#include "G4VCrossSectionDataSet.hh"
#include "G4ParticleDefinition.hh"
#include "G4Threading.hh"
class G4ComponentGGHadronNucleusXsc;
class G4NucleonNuclearCrossSection;
@@ -64,7 +63,7 @@ class G4BGGNucleonElasticXS final : public G4VCrossSectionDataSet
{
public:
explicit G4BGGNucleonElasticXS (const G4ParticleDefinition*);
explicit G4BGGNucleonElasticXS(const G4ParticleDefinition*);
~G4BGGNucleonElasticXS() final;
@@ -87,13 +86,16 @@ public:
void CrossSectionDescription(std::ostream&) const final;
G4BGGNucleonElasticXS & operator=
(const G4BGGNucleonElasticXS &right) = delete;
G4BGGNucleonElasticXS(const G4BGGNucleonElasticXS&) = delete;
private:
void Initialise();
G4double CoulombFactor(G4double kinEnergy, G4int Z);
G4BGGNucleonElasticXS & operator=(const G4BGGNucleonElasticXS &right);
G4BGGNucleonElasticXS(const G4BGGNucleonElasticXS&);
G4double fGlauberEnergy;
G4double fLowEnergy;
@@ -103,16 +105,11 @@ private:
static G4double theCoulombFacN[93];
static G4int theA[93];
const G4ParticleDefinition* theProton;
G4ComponentGGHadronNucleusXsc* fGlauber;
G4NucleonNuclearCrossSection* fNucleon;
G4HadronNucleonXsc* fHadron;
G4bool isProton;
G4bool isMaster;
#ifdef G4MULTITHREADED
static G4Mutex nucleonElasticXSMutex;
#endif
const G4ParticleDefinition* theProton;
G4ComponentGGHadronNucleusXsc* fGlauber;
G4NucleonNuclearCrossSection* fNucleon;
G4HadronNucleonXsc* fHadron;
G4bool isProton;
};
#endif
@@ -51,7 +51,6 @@
#include "globals.hh"
#include "G4VCrossSectionDataSet.hh"
#include "G4ParticleDefinition.hh"
#include "G4Threading.hh"
class G4ComponentGGHadronNucleusXsc;
class G4NucleonNuclearCrossSection;
@@ -87,13 +86,16 @@ public:
void CrossSectionDescription(std::ostream&) const override;
G4BGGNucleonInelasticXS & operator=
(const G4BGGNucleonInelasticXS &right) = delete;
G4BGGNucleonInelasticXS(const G4BGGNucleonInelasticXS&) = delete;
private:
void Initialise();
G4double CoulombFactor(G4double kinEnergy, G4int Z);
G4BGGNucleonInelasticXS & operator=(const G4BGGNucleonInelasticXS &right);
G4BGGNucleonInelasticXS(const G4BGGNucleonInelasticXS&);
G4double fGlauberEnergy;
G4double fLowEnergy;
@@ -103,17 +105,12 @@ private:
static G4double theCoulombFacN[93];
static G4int theA[93];
const G4ParticleDefinition* theProton;
const G4ParticleDefinition* theProton;
G4ComponentGGHadronNucleusXsc* fGlauber;
G4NucleonNuclearCrossSection* fNucleon;
G4HadronNucleonXsc* fHadron;
G4bool isProton;
G4bool isMaster;
#ifdef G4MULTITHREADED
static G4Mutex nucleonInelasticXSMutex;
#endif
G4ComponentGGHadronNucleusXsc* fGlauber;
G4NucleonNuclearCrossSection* fNucleon;
G4HadronNucleonXsc* fHadron;
G4bool isProton;
};
#endif
@@ -51,7 +51,6 @@
#include "globals.hh"
#include "G4VCrossSectionDataSet.hh"
#include "G4ParticleDefinition.hh"
#include "G4Threading.hh"
class G4ComponentGGHadronNucleusXsc;
class G4UPiNuclearCrossSection;
@@ -88,15 +87,17 @@ public:
void CrossSectionDescription(std::ostream&) const final;
G4BGGPionElasticXS & operator=(const G4BGGPionElasticXS &right) = delete;
G4BGGPionElasticXS(const G4BGGPionElasticXS&) = delete;
private:
void Initialise();
G4double CoulombFactorPiPlus(G4double kinEnergy, G4int Z);
G4double FactorPiMinus(G4double kinEnergy);
G4BGGPionElasticXS & operator=(const G4BGGPionElasticXS &right);
G4BGGPionElasticXS(const G4BGGPionElasticXS&);
G4double fGlauberEnergy;
G4double fLowEnergy;
G4double fLowestEnergy;
@@ -105,22 +106,17 @@ private:
static G4double theCoulombFacPiPlus[93];
static G4double theGlauberFacPiMinus[93];
static G4double theCoulombFacPiMinus[93];
static G4int theA[93];
static G4int theA[93];
const G4ParticleDefinition* theProton;
const G4ParticleDefinition* thePiPlus;
const G4ParticleDefinition* theProton;
const G4ParticleDefinition* thePiPlus;
G4Pow* fG4pow;
G4Pow* fG4pow;
G4ComponentGGHadronNucleusXsc* fGlauber;
G4UPiNuclearCrossSection* fPion;
G4HadronNucleonXsc* fHadron;
G4bool isPiplus;
G4bool isMaster;
#ifdef G4MULTITHREADED
static G4Mutex pionElasticXSMutex;
#endif
G4ComponentGGHadronNucleusXsc* fGlauber;
G4UPiNuclearCrossSection* fPion;
G4HadronNucleonXsc* fHadron;
G4bool isPiplus;
};
#endif
@@ -89,15 +89,17 @@ public:
void CrossSectionDescription(std::ostream&) const final;
G4BGGPionInelasticXS & operator=(const G4BGGPionInelasticXS &right) = delete;
G4BGGPionInelasticXS(const G4BGGPionInelasticXS&) = delete;
private:
void Initialise();
G4double CoulombFactorPiPlus(G4double kinEnergy, G4int Z);
G4double FactorPiMinus(G4double kinEnergy);
G4BGGPionInelasticXS & operator=(const G4BGGPionInelasticXS &right);
G4BGGPionInelasticXS(const G4BGGPionInelasticXS&);
G4double fGlauberEnergy;
G4double fLowEnergy;
G4double fLowestEnergy;
@@ -106,23 +108,17 @@ private:
static G4double theGlauberFacPiMinus[93];
static G4double theLowEPiPlus[93];
static G4double theLowEPiMinus[93];
static G4int theA[93];
static G4int theA[93];
const G4ParticleDefinition* theProton;
const G4ParticleDefinition* thePiPlus;
const G4ParticleDefinition* theProton;
const G4ParticleDefinition* thePiPlus;
G4Pow* fG4pow;
G4Pow* fG4pow;
G4ComponentGGHadronNucleusXsc* fGlauber;
G4UPiNuclearCrossSection* fPion;
G4HadronNucleonXsc* fHadron;
G4bool isPiplus;
G4bool isMaster;
#ifdef G4MULTITHREADED
static G4Mutex pionInelasticXSMutex;
#endif
G4UPiNuclearCrossSection* fPion;
G4HadronNucleonXsc* fHadron;
G4bool isPiplus;
};
#endif
@@ -43,7 +43,6 @@
#include "globals.hh"
#include "G4PiData.hh"
#include "G4Threading.hh"
#include <vector>
class G4ComponentBarNucleonNucleusXsc : public G4VComponentCrossSection
@@ -51,8 +50,8 @@ class G4ComponentBarNucleonNucleusXsc : public G4VComponentCrossSection
public:
explicit G4ComponentBarNucleonNucleusXsc();
~G4ComponentBarNucleonNucleusXsc() override;
G4ComponentBarNucleonNucleusXsc();
~G4ComponentBarNucleonNucleusXsc() override = default;
G4double GetTotalIsotopeCrossSection(const G4ParticleDefinition* aParticle,
G4double kinEnergy,
@@ -81,8 +80,6 @@ public:
void ComputeCrossSections(const G4ParticleDefinition* aParticle,
G4double kinEnergy, G4int Z);
void BuildPhysicsTable(const G4ParticleDefinition&) final;
void Description(std::ostream&) const final;
inline G4double GetElementCrossSection(const G4DynamicParticle* aParticle, G4int Z);
@@ -91,7 +88,11 @@ public:
inline G4double GetTotalXsc() { return fTotalXsc; };
inline G4double GetElasticXsc() { return fElasticXsc; };
inline G4double GetInelasticXsc() { return fInelasticXsc; };
G4ComponentBarNucleonNucleusXsc& operator=
(const G4ComponentBarNucleonNucleusXsc &right) = delete;
G4ComponentBarNucleonNucleusXsc(const G4ComponentBarNucleonNucleusXsc&) = delete;
private:
G4double Interpolate(G4int Z1, G4int Z2, G4int Z, G4double x1, G4double x2) const;
@@ -99,35 +100,26 @@ private:
void LoadData();
// cross sections
G4double fTotalXsc;
G4double fInelasticXsc;
G4double fElasticXsc;
G4double fTotalXsc{0.0};
G4double fInelasticXsc{0.0};
G4double fElasticXsc{0.0};
// particles
const G4ParticleDefinition* theProton;
const G4ParticleDefinition* theNeutron;
G4bool isMaster;
static G4double theA[93];
static G4double A75[93];
static const G4int NZ = 17;
static G4int theZ[NZ];
static std::vector<G4PiData*>* thePData;
static std::vector<G4PiData*>* theNData;
#ifdef G4MULTITHREADED
static G4Mutex barNNXSMutex;
#endif
};
inline
G4double G4ComponentBarNucleonNucleusXsc::GetElementCrossSection(
const G4DynamicParticle* dp, G4int Z)
{
ComputeCrossSections(dp->GetDefinition(), dp->GetKineticEnergy(),Z);
ComputeCrossSections(dp->GetDefinition(), dp->GetKineticEnergy(), Z);
return fInelasticXsc;
}
@@ -135,7 +127,7 @@ inline
G4double G4ComponentBarNucleonNucleusXsc::GetElasticCrossSection(
const G4DynamicParticle* dp, G4int Z)
{
ComputeCrossSections(dp->GetDefinition(), dp->GetKineticEnergy(),Z);
ComputeCrossSections(dp->GetDefinition(), dp->GetKineticEnergy(), Z);
return fElasticXsc;
}
@@ -53,8 +53,8 @@ class G4ComponentGGNuclNuclXsc : public G4VComponentCrossSection
{
public:
G4ComponentGGNuclNuclXsc ();
virtual ~G4ComponentGGNuclNuclXsc ();
G4ComponentGGNuclNuclXsc();
~G4ComponentGGNuclNuclXsc() override;
// virtual interface methods
G4double GetTotalElementCrossSection(const G4ParticleDefinition* aParticle,
@@ -91,10 +91,6 @@ public:
void Description(std::ostream&) const final;
// Extra methods
// inline G4double GetElementCrossSection(const G4DynamicParticle*,
// G4int Z, const G4Material*);
inline G4double GetZandACrossSection(const G4DynamicParticle*,
G4int Z, G4int A);
@@ -109,6 +105,7 @@ public:
G4double GetRatioSD(const G4DynamicParticle*, G4double At, G4double Zt);
G4double GetRatioQE(const G4DynamicParticle*, G4double At, G4double Zt);
// main access methods
inline G4double GetElasticGlauberGribov(const G4DynamicParticle*,G4int Z, G4int A);
inline G4double GetInelasticGlauberGribov(const G4DynamicParticle*,G4int Z, G4int A);
@@ -118,16 +115,23 @@ public:
inline G4double GetProductionGlauberGribovXsc() const { return fProductionXsc; };
inline G4double GetDiffractionGlauberGribovXsc() const { return fDiffractionXsc; };
G4ComponentGGNuclNuclXsc& operator=
(const G4ComponentGGNuclNuclXsc &right) = delete;
G4ComponentGGNuclNuclXsc(const G4ComponentGGNuclNuclXsc&) = delete;
private:
// Glauber-Gribov cross section
void ComputeCrossSections(const G4ParticleDefinition* aParticle,
G4double kinEnergy, G4int Z, G4int A);
G4double fTotalXsc, fElasticXsc, fInelasticXsc;
G4double fProductionXsc, fDiffractionXsc;
G4double fTotalXsc{0.0};
G4double fElasticXsc{0.0};
G4double fInelasticXsc{0.0};
G4double fProductionXsc{0.0};
G4double fDiffractionXsc{0.0};
// Cache
G4double fEnergy;
G4double fEnergy{0.0};
const G4ParticleDefinition* theProton;
const G4ParticleDefinition* theNeutron;
@@ -137,8 +141,9 @@ private:
G4HadronNucleonXsc* fHNXsc;
// Cache
const G4ParticleDefinition* fParticle;
G4int fZ, fA;
const G4ParticleDefinition* fParticle{nullptr};
G4int fZ{0};
G4int fA{0};
};
inline G4double
@@ -157,16 +162,6 @@ G4ComponentGGNuclNuclXsc::GetInelasticGlauberGribov(const G4DynamicParticle* dp,
return fInelasticXsc;
}
/*
inline G4double
G4ComponentGGNuclNuclXsc::GetElementCrossSection(const G4DynamicParticle* dp,
G4int Z, const G4Material*)
{
G4int A = G4lrint(fNist->GetAtomicMassAmu(Z));
ComputeCrossSections(dp->GetDefinition(), dp->GetKineticEnergy(), Z, A);
return fInelasticXsc;
}
*/
inline G4double
G4ComponentGGNuclNuclXsc::GetZandACrossSection(const G4DynamicParticle* dp,
G4int Z, G4int A)
@@ -81,18 +81,21 @@ public:
void Clean();
//clean the store
G4VCrossSectionDataSet* GetCrossSectionDataSet(const G4String& name,
G4bool warning=false);
G4VCrossSectionDataSet* GetCrossSectionDataSet(const G4String& name, G4bool warning=false);
G4VComponentCrossSection* GetComponentCrossSection(const G4String& name);
G4CrossSectionDataSetRegistry(G4CrossSectionDataSetRegistry&) = delete;
G4CrossSectionDataSetRegistry& operator=
(const G4CrossSectionDataSetRegistry &right) = delete;
private:
G4CrossSectionDataSetRegistry();
static G4ThreadLocal G4CrossSectionDataSetRegistry* instance;
std::vector <G4VCrossSectionDataSet*> xSections;
std::vector <G4VCrossSectionDataSet*> xSections;
std::vector <G4VComponentCrossSection*> xComponents;
};
@@ -52,9 +52,9 @@ class G4HadronNucleonXsc
{
public:
explicit G4HadronNucleonXsc ();
~G4HadronNucleonXsc ();
G4HadronNucleonXsc();
~G4HadronNucleonXsc() = default;
// Xsc parametrisations return total x-section
G4double HadronNucleonXsc(const G4ParticleDefinition* theParticle,
const G4ParticleDefinition* nucleon, G4double ekin);
@@ -133,7 +133,9 @@ private:
inline G4double CalculateEcmValue(G4double ekin1, G4double mass1, G4double mass2)
{ return std::sqrt(CalcMandelstamS(ekin1, mass1, mass2)); };
G4double fTotalXsc, fElasticXsc, fInelasticXsc;
G4double fTotalXsc{0.0};
G4double fElasticXsc{0.0};
G4double fInelasticXsc{0.0};
G4Pow* g4calc;
const G4ParticleDefinition* theProton;
@@ -28,111 +28,54 @@
//
// GEANT4 Class file
//
// Description: Data structure for cross sections per materials
// Description: Data structure for registration of static cross sections components
//
// Author: V.Ivanchenko 31.05.2018
// Author: V.Ivanchenko 31.05.2018
//
// Modifications:
// 07.03.2024 V.Ivanchenko updated signature - now it is a store without any access
// to stored objects
//
//----------------------------------------------------------------------------
//
#ifndef HadronXSDataTable_h
#define HadronXSDataTable_h 1
#ifndef G4HadronXSDataTable_h
#define G4HadronXSDataTable_h 1
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "globals.hh"
#include "G4Element.hh"
#include "G4ElementVector.hh"
#include "G4PhysicsVector.hh"
#include "Randomize.hh"
#include "G4PhysicsTable.hh"
#include "G4PiData.hh"
#include <vector>
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class G4Material;
class G4DynamicParticle;
class G4CrossSectionDataStore;
class G4HadElementSelector
{
public:
G4HadElementSelector(G4DynamicParticle*, G4CrossSectionDataStore*,
const G4Material*, G4int bins,
G4double emin, G4double emax, G4bool spline);
~G4HadElementSelector();
void Dump();
inline const G4Element* SelectRandomAtom(G4double e) const
{
const G4Element* element = (*theElementVector)[nElmMinusOne];
if (nElmMinusOne > 0) {
G4double x = G4UniformRand();
for(G4int i=0; i<nElmMinusOne; ++i) {
if (x <= xSections[i]->Value(e)) {
element = (*theElementVector)[i];
break;
}
}
}
return element;
}
private:
G4HadElementSelector(G4HadElementSelector &) = delete;
G4HadElementSelector& operator=(const G4HadElementSelector &right) = delete;
G4int nElmMinusOne;
const G4ElementVector* theElementVector;
std::vector<G4PhysicsVector*> xSections;
};
class G4HadronXSDataTable
{
public:
explicit G4HadronXSDataTable();
static G4HadronXSDataTable* Instance();
~G4HadronXSDataTable();
void Initialise(G4DynamicParticle*, G4CrossSectionDataStore*,
G4int bins, G4double emin, G4double emax,
G4bool spline);
void AddPiData(std::vector<G4PiData*>* ptr);
inline const G4PhysicsVector* HasData(size_t idx) const
{
return xsData[idx];
};
void AddTable(G4PhysicsTable* ptr);
inline G4double GetCrossSection(G4double e, size_t idx) const
{
return xsData[idx]->Value(e);
};
inline const G4Element* SelectRandomAtom(G4double e, size_t idx) const
{
return elmSelectors[idx]->SelectRandomAtom(e);
};
void Dump();
// Assignment operator and copy constructor
G4HadronXSDataTable & operator=(const G4HadronXSDataTable &right) = delete;
G4HadronXSDataTable(const G4HadronXSDataTable&) = delete;
private:
// Assignment operator and copy constructor
G4HadronXSDataTable & operator=
(const G4HadronXSDataTable &right) = delete;
G4HadronXSDataTable(const G4HadronXSDataTable&) = delete;
std::vector<G4PhysicsVector*> xsData;
std::vector<G4HadElementSelector*> elmSelectors;
G4HadronXSDataTable();
size_t nMaterials;
static G4HadronXSDataTable* sInstance;
std::vector<G4PiData*> fPiData;
std::vector<G4PhysicsTable*> fTable;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -124,7 +124,6 @@ private:
G4bool isInitializer{false};
static const G4int MAXZCAPTURE = 93;
static G4ElementData* data;
static G4String gDataDirectory;
};
@@ -121,6 +121,8 @@ private:
std::vector<G4double> temp;
G4double elimit;
G4double lowElimit;
G4double loglowElimit;
G4bool isInitializer{false};
@@ -134,7 +136,7 @@ inline
const G4PhysicsVector* G4NeutronInelasticXS::GetPhysicsVector(G4int Z)
{
const G4PhysicsVector* pv = data->GetElementData(Z);
if(pv == nullptr) {
if (pv == nullptr) {
InitialiseOnFly(Z);
pv = data->GetElementData(Z);
}
@@ -29,7 +29,8 @@
// Preprint JINR P2-89-770, p. 12, Dubna 1989 (scanned version from KEK)
// Based on G. Folger version of G4PiNuclearCrossSection class
//
// Modified: V.Ivanchenko
// Modified:
// 05.03.2024 V.Ivanchenko removed obsolete methods and calls
//
#ifndef G4NucleonNuclearCrossSection_h
@@ -46,28 +47,33 @@ class G4NucleonNuclearCrossSection : public G4VCrossSectionDataSet
{
public:
explicit G4NucleonNuclearCrossSection();
~G4NucleonNuclearCrossSection() override;
G4NucleonNuclearCrossSection();
~G4NucleonNuclearCrossSection() override = default;
static const char* Default_Name() {return "BarashenkovNucleonXS";}
static const char* Default_Name() { return "BarashenkovNucleonXS"; }
G4bool IsElementApplicable(const G4DynamicParticle* aParticle,
G4int Z, const G4Material* mat) final;
// return inelastic x-section
G4double GetElementCrossSection(const G4DynamicParticle* aParticle,
G4int Z, const G4Material* mat=nullptr) final;
void BuildPhysicsTable(const G4ParticleDefinition&) final;
void CrossSectionDescription(std::ostream&) const final;
inline G4double GetElasticCrossSection(const G4DynamicParticle* aParticle,
// return elastic x-section
inline G4double GetElasticCrossSection(const G4DynamicParticle* aParticle,
G4int Z);
inline G4double GetTotalXsc() { return fTotalXsc; };
// access methods should be called after ComputeCrossSection(...)
inline G4double GetTotalXsc() { return fTotalXsc; };
inline G4double GetInelasticXsc() { return fInelasticXsc; };
inline G4double GetElasticXsc() { return fElasticXsc; };
G4NucleonNuclearCrossSection& operator=
(const G4NucleonNuclearCrossSection &right) = delete;
G4NucleonNuclearCrossSection(const G4NucleonNuclearCrossSection&) = delete;
private:
void ComputeCrossSections(const G4ParticleDefinition*,
@@ -75,13 +81,9 @@ private:
G4ComponentBarNucleonNucleusXsc* fBarash;
const G4ParticleDefinition* theProton;
const G4ParticleDefinition* theNeutron;
G4double fTotalXsc;
G4double fInelasticXsc;
G4double fElasticXsc;
G4double fTotalXsc{0.0};
G4double fInelasticXsc{0.0};
G4double fElasticXsc{0.0};
};
inline
@@ -24,6 +24,15 @@
// ********************************************************************
//
// by J.P Wellisch, Sun Sep 15 2002.
//
// Revision by V.Ivanchenko 04.03.2024
//
// This code keep data for proton and neutron Barashenkov evaluation
// for the total and reaction (inelastic) cross sections.
// The elastic cross section is a difference sigma(el) = sigma(total) - sigma(inel).
// The low-energy limit 14 MeV, high energy limit 1 TeV. Below energy limit
// the cross sections at 14 MeV is used, above maximum energy a cross section
// at 1 TeV is given.
#ifndef G4PiData_h
#define G4PiData_h
@@ -40,12 +49,20 @@ class G4PiData : public std::vector<std::pair<G4double, std::pair<G4double, G4do
~G4PiData() = default;
G4bool AppliesTo(G4double kineticEnergy);
G4double ReactionXSection(G4double kineticEnergy);
G4double ElasticXSection(G4double kineticEnergy);
G4double TotalXSection(G4double kineticEnergy);
G4PiData& operator = (const G4PiData &right) = delete;
G4PiData(const G4PiData&) = delete;
private:
G4double fMinE{0.0};
G4double fTot0{0.0};
G4double fInel0{0.0};
G4double fMaxE{0.0};
G4double fTot1{0.0};
G4double fInel1{0.0};
};
#endif
@@ -38,7 +38,6 @@
#include "G4DynamicParticle.hh"
#include "G4ParticleDefinition.hh"
#include "globals.hh"
#include "G4Threading.hh"
class G4PhysicsTable;
@@ -48,7 +47,7 @@ public:
explicit G4UPiNuclearCrossSection();
~G4UPiNuclearCrossSection() override;
~G4UPiNuclearCrossSection() override = default;
G4bool IsElementApplicable(const G4DynamicParticle* aParticle,
G4int Z, const G4Material*) final;
@@ -92,15 +91,10 @@ private:
static G4PhysicsTable* piMinusElastic;
static G4PhysicsTable* piMinusInelastic;
G4double aPower;
G4double aPower{0.75};
G4double elow;
G4bool isMaster;
G4bool spline;
#ifdef G4MULTITHREADED
static G4Mutex pionUXSMutex;
#endif
G4bool spline{false};
};
inline G4double
@@ -178,7 +178,7 @@ public: //with description
protected:
G4int verboseLevel;
G4int verboseLevel{0};
G4String name;
@@ -186,10 +186,10 @@ private:
G4CrossSectionDataSetRegistry* registry;
G4double minKinEnergy;
G4double minKinEnergy{0.0};
G4double maxKinEnergy;
G4bool isForAllAtomsAndEnergies;
G4bool isForAllAtomsAndEnergies{false};
};
@@ -48,7 +48,6 @@ geant4_add_module(G4hadronic_xsect
G4HadronNucleonXsc.hh
G4HadronXSDataTable.hh
G4IonsShenCrossSection.hh
G4IsotopeList.hh
G4KokoulinMuonNuclearXS.hh
G4MuNeutrinoNucleusTotXsc.hh
G4NeutrinoElectronCcXsc.hh
@@ -54,11 +54,7 @@ G4double G4BGGNucleonElasticXS::theGlauberFacP[93] = {0.0};
G4double G4BGGNucleonElasticXS::theCoulombFacP[93] = {0.0};
G4double G4BGGNucleonElasticXS::theGlauberFacN[93] = {0.0};
G4double G4BGGNucleonElasticXS::theCoulombFacN[93] = {0.0};
G4int G4BGGNucleonElasticXS::theA[93] = {0};
#ifdef G4MULTITHREADED
G4Mutex G4BGGNucleonElasticXS::nucleonElasticXSMutex = G4MUTEX_INITIALIZER;
#endif
G4int G4BGGNucleonElasticXS::theA[93] = {0};
G4BGGNucleonElasticXS::G4BGGNucleonElasticXS(const G4ParticleDefinition* p)
: G4VCrossSectionDataSet("BarashenkovGlauberGribov")
@@ -66,14 +62,15 @@ G4BGGNucleonElasticXS::G4BGGNucleonElasticXS(const G4ParticleDefinition* p)
verboseLevel = 0;
fGlauberEnergy = 91.*GeV;
fLowEnergy = 14.0*MeV;
fNucleon = nullptr;
fGlauber = nullptr;
fHadron = nullptr;
fNucleon = new G4NucleonNuclearCrossSection();
fGlauber = new G4ComponentGGHadronNucleusXsc();
fHadron = new G4HadronNucleonXsc();
theProton= G4Proton::Proton();
theProton = G4Proton::Proton();
isProton = (theProton == p);
isMaster = false;
SetForAllAtomsAndEnergies(true);
if (0 == theA[0]) { Initialise(); }
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -126,7 +123,8 @@ G4BGGNucleonElasticXS::GetElementCrossSection(const G4DynamicParticle* dp,
cross = fNucleon->GetElasticCrossSection(dp, Z);
}
}
if(verboseLevel > 1) {
#ifdef G4VERBOSE
if (verboseLevel > 1) {
G4cout << "G4BGGNucleonElasticXS::GetElementCrossSection for "
<< dp->GetDefinition()->GetParticleName()
<< " Ekin(GeV)= " << dp->GetKineticEnergy()/CLHEP::GeV
@@ -134,6 +132,7 @@ G4BGGNucleonElasticXS::GetElementCrossSection(const G4DynamicParticle* dp,
<< " XS(b)= " << cross/barn
<< G4endl;
}
#endif
return cross;
}
@@ -141,7 +140,7 @@ G4BGGNucleonElasticXS::GetElementCrossSection(const G4DynamicParticle* dp,
G4double
G4BGGNucleonElasticXS::GetIsoCrossSection(const G4DynamicParticle* dp,
G4int Z, G4int A,
G4int, G4int A,
const G4Isotope*,
const G4Element*,
const G4Material*)
@@ -151,14 +150,16 @@ G4BGGNucleonElasticXS::GetIsoCrossSection(const G4DynamicParticle* dp,
dp->GetKineticEnergy());
G4double cross = A*fHadron->GetElasticHadronNucleonXsc();
if(verboseLevel > 1) {
#ifdef G4VERBOSE
if (verboseLevel > 1) {
G4cout << "G4BGGNucleonElasticXS::GetIsoCrossSection for "
<< dp->GetDefinition()->GetParticleName()
<< " Ekin(GeV)= " << dp->GetKineticEnergy()/CLHEP::GeV
<< " in nucleus Z= " << Z << " A= " << A
<< " in nucleus Z=1 A=" << A
<< " XS(b)= " << cross/barn
<< G4endl;
}
#endif
return cross;
}
@@ -166,7 +167,6 @@ G4BGGNucleonElasticXS::GetIsoCrossSection(const G4DynamicParticle* dp,
void G4BGGNucleonElasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
{
if(nullptr != fNucleon) { return; }
if(&p == theProton || &p == G4Neutron::Neutron()) {
isProton = (theProton == &p);
@@ -176,83 +176,59 @@ void G4BGGNucleonElasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
<< p.GetParticleName() << G4endl;
G4Exception("G4BGGNucleonElasticXS::BuildPhysicsTable", "had001",
FatalException, ed);
return;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4BGGNucleonElasticXS::Initialise()
{
theA[0] = theA[1] = 1;
G4ThreeVector mom(0.0,0.0,1.0);
G4DynamicParticle dp(theProton, mom, fGlauberEnergy);
G4NistManager* nist = G4NistManager::Instance();
G4double csup, csdn;
for (G4int iz=2; iz<93; ++iz) {
G4int A = G4lrint(nist->GetAtomicMassAmu(iz));
theA[iz] = A;
csup = fGlauber->GetElasticGlauberGribov(&dp, iz, A);
csdn = fNucleon->GetElasticCrossSection(&dp, iz);
theGlauberFacP[iz] = csdn/csup;
}
fNucleon = new G4NucleonNuclearCrossSection();
fGlauber = new G4ComponentGGHadronNucleusXsc();
fHadron = new G4HadronNucleonXsc();
dp.SetDefinition(G4Neutron::Neutron());
for (G4int iz=2; iz<93; ++iz) {
csup = fGlauber->GetElasticGlauberGribov(&dp, iz, theA[iz]);
csdn = fNucleon->GetElasticCrossSection(&dp, iz);
theGlauberFacN[iz] = csdn/csup;
fNucleon->BuildPhysicsTable(p);
if(0 == theA[0]) {
#ifdef G4MULTITHREADED
G4MUTEXLOCK(&nucleonElasticXSMutex);
if(0 == theA[0]) {
#endif
isMaster = true;
#ifdef G4MULTITHREADED
}
G4MUTEXUNLOCK(&nucleonElasticXSMutex);
#endif
} else {
return;
if (verboseLevel > 1) {
G4cout << "G4BGGNucleonElasticXS::Initialise Z=" << iz << " A=" << theA[iz]
<< " GFactorP=" << theGlauberFacP[iz]
<< " GFactorN=" << theGlauberFacN[iz] << G4endl;
}
}
if(isMaster && 0 == theA[0]) {
theA[0] = theA[1] = 1;
G4ThreeVector mom(0.0,0.0,1.0);
G4DynamicParticle dp(theProton, mom, fGlauberEnergy);
G4NistManager* nist = G4NistManager::Instance();
G4double csup, csdn;
if(verboseLevel > 0) {
G4cout << "### G4BGGNucleonElasticXS::Initialise for "
<< p.GetParticleName() << G4endl;
}
for(G4int iz=2; iz<93; ++iz) {
G4int A = G4lrint(nist->GetAtomicMassAmu(iz));
theA[iz] = A;
csup = fGlauber->GetElasticGlauberGribov(&dp, iz, A);
csdn = fNucleon->GetElasticCrossSection(&dp, iz);
theGlauberFacP[iz] = csdn/csup;
}
dp.SetDefinition(G4Neutron::Neutron());
for(G4int iz=2; iz<93; ++iz) {
csup = fGlauber->GetElasticGlauberGribov(&dp, iz, theA[iz]);
csdn = fNucleon->GetElasticCrossSection(&dp, iz);
theGlauberFacN[iz] = csdn/csup;
if(verboseLevel > 0) {
G4cout << "Z= " << iz << " A= " << theA[iz]
<< " GFactorP= " << theGlauberFacP[iz]
<< " GFactorN= " << theGlauberFacN[iz] << G4endl;
}
}
theCoulombFacP[0] = theCoulombFacP[1] =
theCoulombFacP[0] = theCoulombFacP[1] =
theCoulombFacN[0] = theCoulombFacN[1] = 1.0;
dp.SetDefinition(theProton);
dp.SetKineticEnergy(fLowEnergy);
for(G4int iz=2; iz<93; ++iz) {
theCoulombFacP[iz] = fNucleon->GetElasticCrossSection(&dp, iz)
/CoulombFactor(fLowEnergy, iz);
}
dp.SetDefinition(G4Neutron::Neutron());
for(G4int iz=2; iz<93; ++iz) {
theCoulombFacN[iz] = fNucleon->GetElasticCrossSection(&dp, iz)
/CoulombFactor(fLowEnergy, iz);
dp.SetDefinition(theProton);
dp.SetKineticEnergy(fLowEnergy);
for (G4int iz=2; iz<93; ++iz) {
theCoulombFacP[iz] = fNucleon->GetElasticCrossSection(&dp, iz)
/CoulombFactor(fLowEnergy, iz);
}
dp.SetDefinition(G4Neutron::Neutron());
for(G4int iz=2; iz<93; ++iz) {
theCoulombFacN[iz] = fNucleon->GetElasticCrossSection(&dp, iz)
/CoulombFactor(fLowEnergy, iz);
if(verboseLevel > 0) {
G4cout << "Z= " << iz << " A= " << theA[iz]
<< " CFactorP= " << theCoulombFacP[iz]
<< " CFactorN= " << theCoulombFacN[iz] << G4endl;
}
if (verboseLevel > 1) {
G4cout << "G4BGGNucleonElasticXS::Initialise Z=" << iz << " A=" << theA[iz]
<< " CFactorP=" << theCoulombFacP[iz]
<< " CFactorN=" << theCoulombFacN[iz] << G4endl;
}
}
}
@@ -261,11 +237,8 @@ void G4BGGNucleonElasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
G4double G4BGGNucleonElasticXS::CoulombFactor(G4double kinEnergy, G4int Z)
{
G4double res= 1.0;
if(isProton) {
res = G4NuclearRadii::CoulombFactor(Z, theA[Z], theProton, kinEnergy);
}
return res;
return (isProton) ?
G4NuclearRadii::CoulombFactor(Z, theA[Z], theProton, kinEnergy) : 1.0;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -55,37 +55,35 @@
#include "G4Exp.hh"
#include "G4NuclearRadii.hh"
#include "G4CrossSectionDataSetRegistry.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
const G4double llog10 = G4Log(10.);
namespace
{
const G4double llog10 = G4Log(10.);
}
G4double G4BGGNucleonInelasticXS::theGlauberFacP[93] = {0.0};
G4double G4BGGNucleonInelasticXS::theCoulombFacP[93] = {0.0};
G4double G4BGGNucleonInelasticXS::theGlauberFacN[93] = {0.0};
G4double G4BGGNucleonInelasticXS::theCoulombFacN[93] = {0.0};
G4int G4BGGNucleonInelasticXS::theA[93] = {0};
#ifdef G4MULTITHREADED
G4Mutex G4BGGNucleonInelasticXS::nucleonInelasticXSMutex = G4MUTEX_INITIALIZER;
#endif
G4int G4BGGNucleonInelasticXS::theA[93] = {0};
G4BGGNucleonInelasticXS::G4BGGNucleonInelasticXS(const G4ParticleDefinition* p)
: G4VCrossSectionDataSet("BarashenkovGlauberGribov")
{
verboseLevel = 0;
fGlauberEnergy = 91.*GeV;
fLowEnergy = 14.*MeV;
fGlauberEnergy = 91.*CLHEP::GeV;
fLowEnergy = 14.*CLHEP::MeV;
fNucleon = nullptr;
fGlauber = nullptr;
fHadron = nullptr;
fNucleon = new G4NucleonNuclearCrossSection();
fGlauber = new G4ComponentGGHadronNucleusXsc();
fHadron = new G4HadronNucleonXsc();
theProton= G4Proton::Proton();
isProton = (theProton == p);
isMaster = false;
SetForAllAtomsAndEnergies(true);
if (0 == theA[0]) { Initialise(); }
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -122,21 +120,22 @@ G4BGGNucleonInelasticXS::GetElementCrossSection(const G4DynamicParticle* dp,
G4double cross = 0.0;
G4double ekin = dp->GetKineticEnergy();
G4int Z = std::min(ZZ, 92);
if(1 == Z) {
if (1 == Z) {
cross = 1.0115*GetIsoCrossSection(dp,1,1);
} else {
if(ekin <= fLowEnergy) {
cross = (isProton) ? theCoulombFacP[Z] : theCoulombFacN[Z];
cross *= CoulombFactor(ekin, Z);
} else if(ekin > fGlauberEnergy) {
cross = (isProton) ? theGlauberFacP[Z] : theGlauberFacN[Z];
cross *= fGlauber->GetInelasticGlauberGribov(dp, Z, theA[Z]);
if (ekin <= fLowEnergy) {
cross = CoulombFactor(ekin, Z);
cross *= (isProton) ? theCoulombFacP[Z] : theCoulombFacN[Z];
} else if (ekin > fGlauberEnergy) {
cross = fGlauber->GetInelasticGlauberGribov(dp, Z, theA[Z]);
cross *= (isProton) ? theGlauberFacP[Z] : theGlauberFacN[Z];
} else {
cross = fNucleon->GetElementCrossSection(dp, Z);
}
}
if(verboseLevel > 1) {
#ifdef G4VERBOSE
if (verboseLevel > 1) {
G4cout << "G4BGGNucleonInelasticXS::GetCrossSection for "
<< dp->GetDefinition()->GetParticleName()
<< " Ekin(GeV)= " << dp->GetKineticEnergy()/CLHEP::GeV
@@ -144,6 +143,7 @@ G4BGGNucleonInelasticXS::GetElementCrossSection(const G4DynamicParticle* dp,
<< " XS(b)= " << cross/barn
<< G4endl;
}
#endif
return cross;
}
@@ -151,7 +151,7 @@ G4BGGNucleonInelasticXS::GetElementCrossSection(const G4DynamicParticle* dp,
G4double
G4BGGNucleonInelasticXS::GetIsoCrossSection(const G4DynamicParticle* dp,
G4int Z, G4int A,
G4int, G4int A,
const G4Isotope*,
const G4Element*,
const G4Material*)
@@ -161,14 +161,16 @@ G4BGGNucleonInelasticXS::GetIsoCrossSection(const G4DynamicParticle* dp,
dp->GetKineticEnergy());
G4double cross = A*fHadron->GetInelasticHadronNucleonXsc();
#ifdef G4VERBOSE
if(verboseLevel > 1) {
G4cout << "G4BGGNucleonInelasticXS::GetIsoCrossSection for "
<< dp->GetDefinition()->GetParticleName()
<< " Ekin(GeV)= " << dp->GetKineticEnergy()/CLHEP::GeV
<< " in nucleus Z= " << Z << " A= " << theA[Z]
<< " in nucleus Z=1 A=" << A
<< " XS(b)= " << cross/barn
<< G4endl;
}
#endif
return cross;
}
@@ -176,7 +178,6 @@ G4BGGNucleonInelasticXS::GetIsoCrossSection(const G4DynamicParticle* dp,
void G4BGGNucleonInelasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
{
if(nullptr != fNucleon) { return; }
if(&p == theProton || &p == G4Neutron::Neutron()) {
isProton = (theProton == &p);
} else {
@@ -187,79 +188,58 @@ void G4BGGNucleonInelasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
FatalException, ed);
return;
}
}
fNucleon = new G4NucleonNuclearCrossSection();
fGlauber = new G4ComponentGGHadronNucleusXsc();
fHadron = new G4HadronNucleonXsc();
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
fNucleon->BuildPhysicsTable(p);
void G4BGGNucleonInelasticXS::Initialise()
{
theA[0] = theA[1] = 1;
G4ThreeVector mom(0.0,0.0,1.0);
G4DynamicParticle dp(theProton, mom, fGlauberEnergy);
if(0 == theA[0]) {
#ifdef G4MULTITHREADED
G4MUTEXLOCK(&nucleonInelasticXSMutex);
if(0 == theA[0]) {
#endif
isMaster = true;
#ifdef G4MULTITHREADED
}
G4MUTEXUNLOCK(&nucleonInelasticXSMutex);
#endif
} else {
return;
G4NistManager* nist = G4NistManager::Instance();
G4double csup, csdn;
for (G4int iz=2; iz<93; ++iz) {
G4int A = G4lrint(nist->GetAtomicMassAmu(iz));
theA[iz] = A;
csup = fGlauber->GetInelasticGlauberGribov(&dp, iz, A);
csdn = fNucleon->GetElementCrossSection(&dp, iz);
theGlauberFacP[iz] = csdn/csup;
}
if(isMaster && 0 == theA[0]) {
dp.SetDefinition(G4Neutron::Neutron());
for (G4int iz=2; iz<93; ++iz) {
csup = fGlauber->GetInelasticGlauberGribov(&dp, iz, theA[iz]);
csdn = fNucleon->GetElementCrossSection(&dp, iz);
theGlauberFacN[iz] = csdn/csup;
theA[0] = theA[1] = 1;
G4ThreeVector mom(0.0,0.0,1.0);
G4DynamicParticle dp(theProton, mom, fGlauberEnergy);
G4NistManager* nist = G4NistManager::Instance();
G4double csup, csdn;
if(verboseLevel > 0) {
G4cout << "### G4BGGNucleonInelasticXS::Initialise for "
<< p.GetParticleName() << G4endl;
if(verboseLevel > 1) {
G4cout << "G4BGGNucleonInelasticXS::Initialise Z= " << iz << " A= " << theA[iz]
<< " GFactorP= " << theGlauberFacP[iz]
<< " GFactorN= " << theGlauberFacN[iz] << G4endl;
}
for(G4int iz=2; iz<93; ++iz) {
}
G4int A = G4lrint(nist->GetAtomicMassAmu(iz));
theA[iz] = A;
theCoulombFacP[1] = theCoulombFacN[1] = 1.0;
dp.SetDefinition(theProton);
dp.SetKineticEnergy(fLowEnergy);
for (G4int iz=2; iz<93; ++iz) {
theCoulombFacP[iz] = fNucleon->GetElementCrossSection(&dp, iz)
/CoulombFactor(fLowEnergy, iz);
}
dp.SetDefinition(G4Neutron::Neutron());
for (G4int iz=2; iz<93; ++iz) {
theCoulombFacN[iz] = fNucleon->GetElementCrossSection(&dp, iz)
/CoulombFactor(fLowEnergy, iz);
csup = fGlauber->GetInelasticGlauberGribov(&dp, iz, A);
csdn = fNucleon->GetElementCrossSection(&dp, iz);
theGlauberFacP[iz] = csdn/csup;
}
dp.SetDefinition(G4Neutron::Neutron());
for(G4int iz=2; iz<93; ++iz) {
csup = fGlauber->GetInelasticGlauberGribov(&dp, iz, theA[iz]);
csdn = fNucleon->GetElementCrossSection(&dp, iz);
theGlauberFacN[iz] = csdn/csup;
if(verboseLevel > 0) {
G4cout << "Z= " << iz << " A= " << theA[iz]
<< " GFactorP= " << theGlauberFacP[iz]
<< " GFactorN= " << theGlauberFacN[iz] << G4endl;
}
}
theCoulombFacP[1] = theCoulombFacN[1] = 1.0;
dp.SetDefinition(theProton);
dp.SetKineticEnergy(fLowEnergy);
for(G4int iz=2; iz<93; ++iz) {
theCoulombFacP[iz] = fNucleon->GetElementCrossSection(&dp, iz)
/CoulombFactor(fLowEnergy, iz);
}
dp.SetDefinition(G4Neutron::Neutron());
for(G4int iz=2; iz<93; ++iz) {
theCoulombFacN[iz] = fNucleon->GetElementCrossSection(&dp, iz)
/CoulombFactor(fLowEnergy, iz);
if(verboseLevel > 0) {
G4cout << "Z= " << iz << " A= " << theA[iz]
<< " CFactorP= " << theCoulombFacP[iz]
<< " CFactorN= " << theCoulombFacN[iz] << G4endl;
}
if (verboseLevel > 1) {
G4cout << "G4BGGNucleonInelasticXS::Initialise Z= " << iz << " A= " << theA[iz]
<< " CFactorP= " << theCoulombFacP[iz]
<< " CFactorN= " << theCoulombFacN[iz] << G4endl;
}
}
}
@@ -277,7 +257,7 @@ G4double G4BGGNucleonInelasticXS::CoulombFactor(G4double kinEnergy, G4int Z)
if(isProton) {
res = G4NuclearRadii::CoulombFactor(Z, theA[Z], theProton, kinEnergy);
res = G4NuclearRadii::CoulombFactor(Z, aa, theProton, kinEnergy);
// from G4ProtonInelasticCrossSection
if(res > 0.0) {
@@ -300,7 +280,7 @@ G4double G4BGGNucleonInelasticXS::CoulombFactor(G4double kinEnergy, G4int Z)
G4double firstexp = G4Exp(-p4*(elog + p5));
G4double secondexp = G4Exp(-p6*(elog + p7));
res = (1.+p3*firstexp/(1. + firstexp))/(1. + secondexp);
res = (1. + p3*firstexp/(1. + firstexp))/(1. + secondexp);
}
return res;
}
@@ -57,11 +57,7 @@ G4double G4BGGPionElasticXS::theGlauberFacPiPlus[93] = {0.0};
G4double G4BGGPionElasticXS::theCoulombFacPiPlus[93] = {0.0};
G4double G4BGGPionElasticXS::theGlauberFacPiMinus[93] = {0.0};
G4double G4BGGPionElasticXS::theCoulombFacPiMinus[93] = {0.0};
G4int G4BGGPionElasticXS::theA[93] = {0};
#ifdef G4MULTITHREADED
G4Mutex G4BGGPionElasticXS::pionElasticXSMutex = G4MUTEX_INITIALIZER;
#endif
G4int G4BGGPionElasticXS::theA[93] = {0};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -69,23 +65,24 @@ G4BGGPionElasticXS::G4BGGPionElasticXS(const G4ParticleDefinition* p)
: G4VCrossSectionDataSet("BarashenkovGlauberGribov")
{
verboseLevel = 0;
fGlauberEnergy = 91.*GeV;
fLowEnergy = 20.*MeV;
fLowestEnergy = 1.*MeV;
fGlauberEnergy = 91.*CLHEP::GeV;
fLowEnergy = 20.*CLHEP::MeV;
fLowestEnergy = 1.*CLHEP::MeV;
SetMinKinEnergy(0.0);
SetMaxKinEnergy( G4HadronicParameters::Instance()->GetMaxEnergy() );
fPion = nullptr;
fGlauber = nullptr;
fHadron = nullptr;
fPion = new G4UPiNuclearCrossSection();
fGlauber = new G4ComponentGGHadronNucleusXsc();
fHadron = new G4HadronNucleonXsc();
fG4pow = G4Pow::GetInstance();
fG4pow = G4Pow::GetInstance();
theProton= G4Proton::Proton();
thePiPlus= G4PionPlus::PionPlus();
theProton = G4Proton::Proton();
thePiPlus = G4PionPlus::PionPlus();
isPiplus = (p == thePiPlus);
isMaster = false;
SetForAllAtomsAndEnergies(true);
if (0 == theA[0]) { Initialise(); }
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -136,6 +133,7 @@ G4BGGPionElasticXS::GetElementCrossSection(const G4DynamicParticle* dp,
cross = fPion->GetElasticCrossSection(dp, Z, theA[Z]);
}
}
#ifdef G4VERBOSE
if(verboseLevel > 1) {
G4cout << "G4BGGPionElasticXS::GetElementCrossSection for "
<< dp->GetDefinition()->GetParticleName()
@@ -144,12 +142,15 @@ G4BGGPionElasticXS::GetElementCrossSection(const G4DynamicParticle* dp,
<< " XS(b)= " << cross/barn
<< G4endl;
}
#endif
return cross;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double
G4BGGPionElasticXS::GetIsoCrossSection(const G4DynamicParticle* dp,
G4int Z, G4int A,
G4int, G4int A,
const G4Isotope*,
const G4Element*,
const G4Material*)
@@ -159,14 +160,16 @@ G4BGGPionElasticXS::GetIsoCrossSection(const G4DynamicParticle* dp,
dp->GetKineticEnergy());
G4double cross = A*fHadron->GetElasticHadronNucleonXsc();
#ifdef G4VERBOSE
if(verboseLevel > 1) {
G4cout << "G4BGGPionElasticXS::GetIsoCrossSection for "
<< dp->GetDefinition()->GetParticleName()
<< " Ekin(GeV)= " << dp->GetKineticEnergy()
<< " in nucleus Z= " << Z << " A= " << A
<< " in nucleus Z=1 A=" << A
<< " XS(b)= " << cross/barn
<< G4endl;
}
#endif
return cross;
}
@@ -174,7 +177,6 @@ G4BGGPionElasticXS::GetIsoCrossSection(const G4DynamicParticle* dp,
void G4BGGPionElasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
{
if(fPion) { return; }
if(verboseLevel > 1) {
G4cout << "G4BGGPionElasticXS::BuildPhysicsTable for "
<< p.GetParticleName() << G4endl;
@@ -187,80 +189,61 @@ void G4BGGPionElasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
<< p.GetParticleName() << G4endl;
G4Exception("G4BGGPionElasticXS::BuildPhysicsTable", "had001",
FatalException, ed);
return;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4BGGPionElasticXS::Initialise()
{
theA[0] = theA[1] = 1;
G4ThreeVector mom(0.0,0.0,1.0);
G4DynamicParticle dp(thePiPlus, mom, fGlauberEnergy);
G4NistManager* nist = G4NistManager::Instance();
G4double csup, csdn;
for (G4int iz=2; iz<93; ++iz) {
G4int A = G4lrint(nist->GetAtomicMassAmu(iz));
theA[iz] = A;
csup = fGlauber->GetElasticGlauberGribov(&dp, iz, A);
csdn = fPion->GetElasticCrossSection(&dp, iz, A);
theGlauberFacPiPlus[iz] = csdn/csup;
}
fPion = new G4UPiNuclearCrossSection();
fGlauber = new G4ComponentGGHadronNucleusXsc();
fHadron = new G4HadronNucleonXsc();
dp.SetDefinition(G4PionMinus::PionMinus());
for (G4int iz=2; iz<93; ++iz) {
csup = fGlauber->GetElasticGlauberGribov(&dp, iz, theA[iz]);
csdn = fPion->GetElasticCrossSection(&dp, iz, theA[iz]);
theGlauberFacPiMinus[iz] = csdn/csup;
fPion->BuildPhysicsTable(p);
if(0 == theA[0]) {
#ifdef G4MULTITHREADED
G4MUTEXLOCK(&pionElasticXSMutex);
if(0 == theA[0]) {
#endif
isMaster = true;
#ifdef G4MULTITHREADED
if (verboseLevel > 1) {
G4cout << "Z= " << iz << " A= " << theA[iz]
<< " factorPiPlus= " << theGlauberFacPiPlus[iz]
<< " factorPiMinus= " << theGlauberFacPiMinus[iz]
<< G4endl;
}
G4MUTEXUNLOCK(&pionElasticXSMutex);
#endif
} else {
return;
}
theCoulombFacPiPlus[1] = 1.0;
theCoulombFacPiMinus[1]= 1.0;
dp.SetKineticEnergy(fLowEnergy);
dp.SetDefinition(thePiPlus);
for (G4int iz=2; iz<93; ++iz) {
theCoulombFacPiPlus[iz] = fPion->GetElasticCrossSection(&dp, iz, theA[iz])
/CoulombFactorPiPlus(fLowEnergy, iz);
}
dp.SetDefinition(G4PionMinus::PionMinus());
for(G4int iz=2; iz<93; ++iz) {
theCoulombFacPiMinus[iz] = fPion->GetElasticCrossSection(&dp, iz, theA[iz])
/FactorPiMinus(fLowEnergy);
if(isMaster && 0 == theA[0]) {
theA[0] = theA[1] = 1;
G4ThreeVector mom(0.0,0.0,1.0);
G4DynamicParticle dp(thePiPlus, mom, fGlauberEnergy);
G4NistManager* nist = G4NistManager::Instance();
G4double csup, csdn;
for(G4int iz=2; iz<93; ++iz) {
G4int A = G4lrint(nist->GetAtomicMassAmu(iz));
theA[iz] = A;
csup = fGlauber->GetElasticGlauberGribov(&dp, iz, A);
csdn = fPion->GetElasticCrossSection(&dp, iz, A);
theGlauberFacPiPlus[iz] = csdn/csup;
}
dp.SetDefinition(G4PionMinus::PionMinus());
for(G4int iz=2; iz<93; ++iz) {
csup = fGlauber->GetElasticGlauberGribov(&dp, iz, theA[iz]);
csdn = fPion->GetElasticCrossSection(&dp, iz, theA[iz]);
theGlauberFacPiMinus[iz] = csdn/csup;
if(verboseLevel > 0) {
G4cout << "Z= " << iz << " A= " << theA[iz]
<< " factorPiPlus= " << theGlauberFacPiPlus[iz]
<< " factorPiMinus= " << theGlauberFacPiMinus[iz]
<< G4endl;
}
}
theCoulombFacPiPlus[1] = 1.0;
theCoulombFacPiMinus[1]= 1.0;
dp.SetKineticEnergy(fLowEnergy);
dp.SetDefinition(thePiPlus);
for(G4int iz=2; iz<93; ++iz) {
theCoulombFacPiPlus[iz] = fPion->GetElasticCrossSection(&dp, iz, theA[iz])
/CoulombFactorPiPlus(fLowEnergy, iz);
}
dp.SetDefinition(G4PionMinus::PionMinus());
for(G4int iz=2; iz<93; ++iz) {
theCoulombFacPiMinus[iz] = fPion->GetElasticCrossSection(&dp, iz, theA[iz])
/FactorPiMinus(fLowEnergy);
if(verboseLevel > 0) {
G4cout << "Z= " << iz << " A= " << theA[iz]
<< " CoulombFactorPiPlus= " << theCoulombFacPiPlus[iz]
<< " CoulombFactorPiMinus= " << theCoulombFacPiMinus[iz]
<< G4endl;
}
if(verboseLevel > 1) {
G4cout << "Z= " << iz << " A= " << theA[iz]
<< " CoulombFactorPiPlus= " << theCoulombFacPiPlus[iz]
<< " CoulombFactorPiMinus= " << theCoulombFacPiMinus[iz]
<< G4endl;
}
}
}
@@ -50,7 +50,6 @@
#include "G4PionMinus.hh"
#include "G4NistManager.hh"
#include "G4Pow.hh"
#include "G4HadronicParameters.hh"
G4double G4BGGPionInelasticXS::theGlauberFacPiPlus[93] = {0.0};
@@ -59,31 +58,28 @@ G4double G4BGGPionInelasticXS::theLowEPiPlus[93] = {0.0};
G4double G4BGGPionInelasticXS::theLowEPiMinus[93] = {0.0};
G4int G4BGGPionInelasticXS::theA[93] = {0};
#ifdef G4MULTITHREADED
G4Mutex G4BGGPionInelasticXS::pionInelasticXSMutex = G4MUTEX_INITIALIZER;
#endif
G4BGGPionInelasticXS::G4BGGPionInelasticXS(const G4ParticleDefinition* p)
: G4VCrossSectionDataSet("BarashenkovGlauberGribov")
{
verboseLevel = 0;
fGlauberEnergy = 91.*CLHEP::GeV;
fLowEnergy = 20.*CLHEP::MeV;
fLowestEnergy = 1.*CLHEP::MeV;
fGlauberEnergy = 91.*CLHEP::GeV;
fLowEnergy = 20.*CLHEP::MeV;
fLowestEnergy = 1.*CLHEP::MeV;
SetMinKinEnergy(0.0);
SetMaxKinEnergy( G4HadronicParameters::Instance()->GetMaxEnergy() );
fPion = nullptr;
fGlauber = nullptr;
fHadron = nullptr;
fPion = new G4UPiNuclearCrossSection();
fGlauber = new G4ComponentGGHadronNucleusXsc();
fHadron = new G4HadronNucleonXsc();
fG4pow = G4Pow::GetInstance();
theProton = G4Proton::Proton();
thePiPlus = G4PionPlus::PionPlus();
isPiplus = (p == thePiPlus);
isMaster = false;
isPiplus = (p == thePiPlus);
SetForAllAtomsAndEnergies(true);
if (0 == theA[0]) { Initialise(); }
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -135,6 +131,7 @@ G4BGGPionInelasticXS::GetElementCrossSection(const G4DynamicParticle* dp,
} else {
cross = fPion->GetInelasticCrossSection(dp, Z, theA[Z]);
}
#ifdef G4VERBOSE
if(verboseLevel > 1) {
G4cout << "G4BGGPionInelasticXS::GetCrossSection for "
<< dp->GetDefinition()->GetParticleName()
@@ -143,6 +140,7 @@ G4BGGPionInelasticXS::GetElementCrossSection(const G4DynamicParticle* dp,
<< " XS(b)= " << cross/barn
<< G4endl;
}
#endif
return cross;
}
@@ -150,7 +148,7 @@ G4BGGPionInelasticXS::GetElementCrossSection(const G4DynamicParticle* dp,
G4double
G4BGGPionInelasticXS::GetIsoCrossSection(const G4DynamicParticle* dp,
G4int Z, G4int A,
G4int, G4int A,
const G4Isotope*,
const G4Element*,
const G4Material*)
@@ -160,14 +158,16 @@ G4BGGPionInelasticXS::GetIsoCrossSection(const G4DynamicParticle* dp,
dp->GetKineticEnergy());
G4double cross = A*fHadron->GetInelasticHadronNucleonXsc();
#ifdef G4VERBOSE
if(verboseLevel > 1) {
G4cout << "G4BGGPionInelasticXS::GetCrossSection for "
<< dp->GetDefinition()->GetParticleName()
<< " Ekin(GeV)= " << dp->GetKineticEnergy()
<< " in nucleus Z= " << Z << " A= " << A
<< " in nucleus Z=1 A=" << A
<< " XS(b)= " << cross/barn
<< G4endl;
}
#endif
return cross;
}
@@ -175,7 +175,6 @@ G4BGGPionInelasticXS::GetIsoCrossSection(const G4DynamicParticle* dp,
void G4BGGPionInelasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
{
if(fPion) { return; }
if(verboseLevel > 1) {
G4cout << "G4BGGPionInelasticXS::BuildPhysicsTable for "
<< p.GetParticleName() << G4endl;
@@ -188,86 +187,61 @@ void G4BGGPionInelasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
<< p.GetParticleName() << G4endl;
G4Exception("G4BGGPionInelasticXS::BuildPhysicsTable", "had001",
FatalException, ed);
return;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4BGGPionInelasticXS::Initialise()
{
theA[0] = theA[1] = 1;
G4ThreeVector mom(0.0,0.0,1.0);
G4DynamicParticle dp(thePiPlus, mom, fGlauberEnergy);
G4NistManager* nist = G4NistManager::Instance();
G4double csup, csdn;
for (G4int iz=2; iz<93; ++iz) {
G4int A = G4lrint(nist->GetAtomicMassAmu(iz));
theA[iz] = A;
csup = fGlauber->GetInelasticGlauberGribov(&dp, iz, A);
csdn = fPion->GetInelasticCrossSection(&dp, iz, A);
theGlauberFacPiPlus[iz] = csdn/csup;
}
fPion = new G4UPiNuclearCrossSection();
fGlauber = new G4ComponentGGHadronNucleusXsc();
fHadron = new G4HadronNucleonXsc();
dp.SetDefinition(G4PionMinus::PionMinus());
for (G4int iz=2; iz<93; ++iz) {
csup = fGlauber->GetInelasticGlauberGribov(&dp, iz, theA[iz]);
csdn = fPion->GetInelasticCrossSection(&dp, iz, theA[iz]);
theGlauberFacPiMinus[iz] = csdn/csup;
fPion->BuildPhysicsTable(p);
if(0 == theA[0]) {
#ifdef G4MULTITHREADED
G4MUTEXLOCK(&pionInelasticXSMutex);
if(0 == theA[0]) {
#endif
isMaster = true;
#ifdef G4MULTITHREADED
if(verboseLevel > 1) {
G4cout << "Z= " << iz << " A= " << theA[iz]
<< " factorPiPlus= " << theGlauberFacPiPlus[iz]
<< " factorPiMinus= " << theGlauberFacPiMinus[iz]
<< G4endl;
}
G4MUTEXUNLOCK(&pionInelasticXSMutex);
#endif
} else {
return;
}
if(isMaster && 0 == theA[0]) {
theLowEPiPlus[1] = theLowEPiMinus[1]= 1.0;
dp.SetDefinition(thePiPlus);
dp.SetKineticEnergy(fLowEnergy);
for (G4int iz=2; iz<93; ++iz) {
theLowEPiPlus[iz] = fPion->GetInelasticCrossSection(&dp, iz, theA[iz])
/CoulombFactorPiPlus(fLowEnergy, iz);
}
theA[0] = theA[1] = 1;
G4ThreeVector mom(0.0,0.0,1.0);
G4DynamicParticle dp(thePiPlus, mom, fGlauberEnergy);
G4NistManager* nist = G4NistManager::Instance();
G4double csup, csdn;
if(verboseLevel > 0) {
G4cout << "### G4BGGPionInelasticXS::Initialise for "
<< p.GetParticleName()
<< " isPiplus: " << isPiplus
<< G4endl;
}
for(G4int iz=2; iz<93; ++iz) {
G4int A = G4lrint(nist->GetAtomicMassAmu(iz));
theA[iz] = A;
csup = fGlauber->GetInelasticGlauberGribov(&dp, iz, A);
csdn = fPion->GetInelasticCrossSection(&dp, iz, A);
theGlauberFacPiPlus[iz] = csdn/csup;
}
dp.SetDefinition(G4PionMinus::PionMinus());
for(G4int iz=2; iz<93; ++iz) {
csup = fGlauber->GetInelasticGlauberGribov(&dp, iz, theA[iz]);
csdn = fPion->GetInelasticCrossSection(&dp, iz, theA[iz]);
theGlauberFacPiMinus[iz] = csdn/csup;
if(verboseLevel > 0) {
G4cout << "Z= " << iz << " A= " << theA[iz]
<< " factorPiPlus= " << theGlauberFacPiPlus[iz]
<< " factorPiMinus= " << theGlauberFacPiMinus[iz]
<< G4endl;
}
}
theLowEPiPlus[1] = theLowEPiMinus[1]= 1.0;
dp.SetDefinition(thePiPlus);
dp.SetKineticEnergy(fLowEnergy);
for(G4int iz=2; iz<93; ++iz) {
theLowEPiPlus[iz] = fPion->GetInelasticCrossSection(&dp, iz, theA[iz])
/CoulombFactorPiPlus(fLowEnergy, iz);
}
dp.SetDefinition(G4PionMinus::PionMinus());
for(G4int iz=2; iz<93; ++iz) {
theLowEPiMinus[iz] = fPion->GetInelasticCrossSection(&dp, iz, theA[iz])
/FactorPiMinus(fLowEnergy);
dp.SetDefinition(G4PionMinus::PionMinus());
for (G4int iz=2; iz<93; ++iz) {
theLowEPiMinus[iz] = fPion->GetInelasticCrossSection(&dp, iz, theA[iz])
/FactorPiMinus(fLowEnergy);
if(verboseLevel > 0) {
G4cout << "Z= " << iz << " A= " << theA[iz]
<< " LowEtorPiPlus= " << theLowEPiPlus[iz]
<< " LowEtorPiMinus= " << theLowEPiMinus[iz]
<< G4endl;
}
if (verboseLevel > 1) {
G4cout << "Z= " << iz << " A= " << theA[iz]
<< " LowEtorPiPlus= " << theLowEPiPlus[iz]
<< " LowEtorPiMinus= " << theLowEPiMinus[iz]
<< G4endl;
}
}
}
@@ -38,42 +38,24 @@
#include "G4Proton.hh"
#include "G4Pow.hh"
#include "G4BarashenkovData.hh"
#include "G4NistManager.hh"
#include "G4IsotopeList.hh"
#include "G4HadronXSDataTable.hh"
///////////////////////////////////////////////////////////////////////////////
G4double G4ComponentBarNucleonNucleusXsc::theA[93] = {0.0};
G4double G4ComponentBarNucleonNucleusXsc::A75[93] = {0.0};
G4double G4ComponentBarNucleonNucleusXsc::A75[93] = {0.0};
G4int G4ComponentBarNucleonNucleusXsc::theZ[] =
{2,4,6,7,8,11,13,14,20,26,29,42,48,50,74,82,92};
std::vector<G4PiData*>* G4ComponentBarNucleonNucleusXsc::thePData = nullptr;
std::vector<G4PiData*>* G4ComponentBarNucleonNucleusXsc::theNData = nullptr;
#ifdef G4MULTITHREADED
G4Mutex G4ComponentBarNucleonNucleusXsc::barNNXSMutex = G4MUTEX_INITIALIZER;
#endif
G4ComponentBarNucleonNucleusXsc::G4ComponentBarNucleonNucleusXsc()
: G4VComponentCrossSection("BarashenkovNucleonNucleusXsc"),
fTotalXsc(0.0), fInelasticXsc(0.0), fElasticXsc(0.0), isMaster(false)
: G4VComponentCrossSection("BarashenkovNucleonNucleusXsc")
{
theNeutron = G4Neutron::Neutron();
theProton = G4Proton::Proton();
}
///////////////////////////////////////////////////////////////////////////////
G4ComponentBarNucleonNucleusXsc::~G4ComponentBarNucleonNucleusXsc()
{
if(isMaster && nullptr != thePData) {
for(G4int i=0; i<NZ; ++i) {
delete (*thePData)[i];
delete (*theNData)[i];
}
delete thePData;
delete theNData;
thePData = nullptr;
theNData = nullptr;
if (nullptr == thePData) {
LoadData();
}
}
@@ -176,8 +158,8 @@ Interpolate(G4int Z1, G4int Z2, G4int Z, G4double x1, G4double x2) const
// for tabulated data, cross section scales with A^(2/3)
G4double r1 = x1* A75[Z] / A75[Z1];
G4double r2 = x2* A75[Z] / A75[Z2];
G4double alp1 = (theA[Z] - theA[Z1]);
G4double alp2 = (theA[Z2] - theA[Z]);
G4double alp1 = (aeff[Z] - aeff[Z1]);
G4double alp2 = (aeff[Z2] - aeff[Z]);
G4double result = (r1*alp2 + r2*alp1)/(alp1 + alp2);
// G4cout << "x1/2, z1/2 z" <<x1<<" "<<x2<<" "<<Z1<<" "<<Z2<<" "<<Z<<G4endl;
// G4cout << "res1/2 " << r1 <<" " << r2 <<" " << result<< G4endl;
@@ -198,31 +180,15 @@ void G4ComponentBarNucleonNucleusXsc::Description(std::ostream& outFile) const
/////////////////////////////////////////////////////////////////////////////
void
G4ComponentBarNucleonNucleusXsc::BuildPhysicsTable(const G4ParticleDefinition&)
{
if(nullptr != theNData) { return; }
#ifdef G4MULTITHREADED
G4MUTEXLOCK(&barNNXSMutex);
if(!theNData) {
#endif
isMaster = true;
#ifdef G4MULTITHREADED
}
G4MUTEXUNLOCK(&barNNXSMutex);
#endif
if(isMaster) { LoadData(); }
}
/////////////////////////////////////////////////////////////////////////////
void G4ComponentBarNucleonNucleusXsc::LoadData()
{
theNData = new std::vector<G4PiData*>;
thePData = new std::vector<G4PiData*>;
theNData->resize(NZ, nullptr);
thePData->resize(NZ, nullptr);
auto ptr = G4HadronXSDataTable::Instance();
ptr->AddPiData(theNData);
ptr->AddPiData(thePData);
// He, Be, C
(*theNData)[0] = new G4PiData(he_m_t, he_m_in, e1, 44);
@@ -281,12 +247,10 @@ void G4ComponentBarNucleonNucleusXsc::LoadData()
(*theNData)[16] = new G4PiData(u_m_t, u_m_in, e6, 46);
(*thePData)[16] = new G4PiData(u_m_t, u_p_in, e6, 46);
G4NistManager* nist = G4NistManager::Instance();
A75[0] = theA[0] = 1.0;
A75[0] = 1.0;
G4Pow* g4pow = G4Pow::GetInstance();
for(G4int i=1; i<93; ++i) {
theA[i] = nist->GetAtomicMassAmu(i);
A75[i] = g4pow->A23(theA[i]); // interpolate by square ~ A^(2/3)
A75[i] = g4pow->A23(aeff[i]); // interpolate by square ~ A^(2/3)
}
}
@@ -39,12 +39,13 @@
#include "G4NuclearRadii.hh"
#include "G4Pow.hh"
static const G4double inve = 1./CLHEP::eplus;
namespace
{
const G4double inve = 1./CLHEP::eplus;
}
G4ComponentGGNuclNuclXsc::G4ComponentGGNuclNuclXsc()
: G4VComponentCrossSection("Glauber-Gribov Nucl-nucl"),
fTotalXsc(0.0), fElasticXsc(0.0), fInelasticXsc(0.0), fProductionXsc(0.0),
fDiffractionXsc(0.0), fEnergy(0.0), fParticle(nullptr), fZ(0), fA(0)
: G4VComponentCrossSection("Glauber-Gribov Nucl-nucl")
{
theProton = G4Proton::Proton();
theNeutron = G4Neutron::Neutron();
@@ -171,7 +172,7 @@ void G4ComponentGGNuclNuclXsc::ComputeCrossSections(
fZ = Z;
fA = A;
fEnergy = kinEnergy;
G4Pow* pG4Pow=G4Pow::GetInstance();
G4Pow* pG4Pow = G4Pow::GetInstance();
G4int pZ = G4lrint(aParticle->GetPDGCharge()*inve);
G4int pA = aParticle->GetBaryonNumber();
@@ -201,7 +202,8 @@ void G4ComponentGGNuclNuclXsc::ComputeCrossSections(
G4double tR = G4NuclearRadii::Radius(Z, A);
G4double pR = G4NuclearRadii::Radius(pZ, pA);
if(pHN) pR *= std::sqrt( pG4Pow->Z23( pA - pL ) + cHN*pG4Pow->Z23( pL ) )/pG4Pow->Z13(pA);
if(pHN)
pR *= std::sqrt( pG4Pow->Z23( pA - pL ) + cHN*pG4Pow->Z23( pL ) )/pG4Pow->Z13(pA);
G4double cB = ComputeCoulombBarier(aParticle, kinEnergy, Z, A, pR, tR);
@@ -214,10 +216,6 @@ void G4ComponentGGNuclNuclXsc::ComputeCrossSections(
sigma += (pZ*tN+pN*Z)*fHNXsc->HadronNucleonXscNS(theNeutron, theProton, pTkin);
G4double npInXsc = fHNXsc->GetInelasticHadronNucleonXsc();
// G4cout<<"ppInXsc = "<<ppInXsc/millibarn<<"; npInXsc = "<<npInXsc/millibarn<<G4endl;
// G4cout<<"npTotXsc = "<<fHNXsc->GetTotalHadronNucleonXsc()/millibarn<<"; npElXsc = "
// <<fHNXsc->GetElasticHadronNucleonXsc()/millibarn<<G4endl;
G4double nucleusSquare = cofTotal*CLHEP::pi*( pR*pR + tR*tR ); // basically 2piRR
G4double ratio= sigma/nucleusSquare;
@@ -234,11 +232,7 @@ void G4ComponentGGNuclNuclXsc::ComputeCrossSections(
}
else
{
fInelasticXsc = 0.;
fTotalXsc = 0.;
fElasticXsc = 0.;
fProductionXsc = 0.;
fDiffractionXsc= 0.;
fInelasticXsc = fTotalXsc = fElasticXsc = fProductionXsc = fDiffractionXsc = 0.;
}
}
@@ -256,14 +250,21 @@ G4double G4ComponentGGNuclNuclXsc::ComputeCoulombBarier(
G4double totEcm = std::sqrt(pM*pM + tM*tM + 2.*pElab*tM);
G4double totTcm = totEcm - pM -tM;
static const G4double qfact = CLHEP::fine_structure_const*CLHEP::hbarc;
G4double bC = qfact*pZ*Z*0.5/(pR + tR);
// 0.5 defines shape of Cross section correction
// at cB = totTcm it become zero
static const G4double qfact = 0.5*CLHEP::elm_coupling;
G4double bC = qfact*pZ*Z/(pR + tR);
G4double ratio = (totTcm <= bC ) ? 0. : 1. - bC/totTcm;
// G4cout<<"G4ComponentGGNuclNuclXsc::ComputeCoulombBarier= "<<ratio
// <<"; pTkin(GeV)= " <<pTkin/GeV<<";
// " pPlab = "<<pPlab/GeV<<"; bC = "<<bC/GeV<<"; pTcm = "
// <<pTcm/GeV<<G4endl;
G4double ratio = (totTcm <= bC) ? 0. : 1. - bC/totTcm;
#ifdef G4VERBOSE
if (GetVerboseLevel() > 1) {
G4cout << "G4ComponentGGNuclNuclXsc::ComputeCoulombBarier(..)=" <<ratio
<< "; pTkin(GeV)=" << pTkin/CLHEP::MeV
<< " totTcm= " << totTcm/CLHEP::MeV<< "; bC=" << bC/CLHEP::MeV
<< G4endl;
}
#endif
return ratio;
}
@@ -87,22 +87,18 @@ G4CrossSectionDataSetRegistry::~G4CrossSectionDataSetRegistry()
void G4CrossSectionDataSetRegistry::Clean()
{
size_t n = xSections.size();
for (size_t i=0; i<n; ++i) {
std::size_t n = xSections.size();
for (std::size_t i=0; i<n; ++i) {
G4VCrossSectionDataSet* p = xSections[i];
if(p) {
//std::cout << "Clean x-section #" << i << std::endl;
//std::cout << " " << p->GetName() << std::endl;
if(nullptr != p) {
delete p;
xSections[i] = nullptr;
}
}
n = xComponents.size();
for (size_t i=0; i<n; ++i) {
G4VComponentCrossSection* p = xComponents[i];
if(p) {
//std::cout << "Clean component #" << i << std::endl;
//std::cout << " " << p->GetName() << std::endl;
for (std::size_t i=0; i<n; ++i) {
auto p = xComponents[i];
if(nullptr != p) {
delete p;
xComponents[i] = nullptr;
}
@@ -112,22 +108,18 @@ void G4CrossSectionDataSetRegistry::Clean()
void G4CrossSectionDataSetRegistry::Register(G4VCrossSectionDataSet* p)
{
if(nullptr == p) { return; }
for (auto xsec : xSections) {
for (auto & xsec : xSections) {
if(xsec == p) { return; }
}
//G4cout << "Register x-section #" << xSections.size()
// << " " << p->GetName() << " " << p << G4endl;
xSections.push_back(p);
}
void G4CrossSectionDataSetRegistry::DeRegister(G4VCrossSectionDataSet* p)
{
if(nullptr == p) { return; }
size_t n = xSections.size();
for (size_t i=0; i<n; ++i) {
std::size_t n = xSections.size();
for (std::size_t i=0; i<n; ++i) {
if(xSections[i] == p) {
//std::cout << "DeRegister x-section #" << i
// << " " << p->GetName() << " " << p << std::endl;
xSections[i] = nullptr;
return;
}
@@ -136,23 +128,19 @@ void G4CrossSectionDataSetRegistry::DeRegister(G4VCrossSectionDataSet* p)
void G4CrossSectionDataSetRegistry::Register(G4VComponentCrossSection* p)
{
if(!p) { return; }
for (auto xsec : xComponents) {
if(nullptr == p) { return; }
for (auto & xsec : xComponents) {
if(xsec == p) { return; }
}
//G4cout << "Register component #" << xComponents.size()
//<< " " << p->GetName() << G4endl;
xComponents.push_back(p);
}
void G4CrossSectionDataSetRegistry::DeRegister(G4VComponentCrossSection* p)
{
if(!p) { return; }
size_t n = xComponents.size();
for (size_t i=0; i<n; ++i) {
if(nullptr == p) { return; }
std::size_t n = xComponents.size();
for (std::size_t i=0; i<n; ++i) {
if(xComponents[i] == p) {
//std::cout << "DeRegister component #" << i << std::endl;
//std::cout << " " << p->GetName() << std::endl;
xComponents[i] = nullptr;
return;
}
@@ -162,12 +150,10 @@ void G4CrossSectionDataSetRegistry::DeRegister(G4VComponentCrossSection* p)
void
G4CrossSectionDataSetRegistry::DeleteComponent(G4VComponentCrossSection* p)
{
if(!p) { return; }
size_t n = xComponents.size();
for (size_t i=0; i<n; ++i) {
if(nullptr == p) { return; }
std::size_t n = xComponents.size();
for (std::size_t i=0; i<n; ++i) {
if(xComponents[i] == p) {
//std::cout << "Delete component #" << i << std::endl;
//std::cout << " " << p->GetName() << std::endl;
delete p;
return;
}
@@ -178,8 +164,8 @@ G4VCrossSectionDataSet*
G4CrossSectionDataSetRegistry::GetCrossSectionDataSet(const G4String& name,
G4bool warning)
{
for (auto xsec : xSections) {
if(xsec && xsec->GetName() == name) { return xsec; }
for (auto & xsec : xSections) {
if(nullptr != xsec && xsec->GetName() == name) { return xsec; }
}
// check if factory exists...
//
@@ -199,8 +185,8 @@ G4CrossSectionDataSetRegistry::GetCrossSectionDataSet(const G4String& name,
G4VComponentCrossSection*
G4CrossSectionDataSetRegistry::GetComponentCrossSection(const G4String& name)
{
for (auto xsec : xComponents) {
if(xsec && xsec->GetName() == name) { return xsec; }
for (auto & xsec : xComponents) {
if(nullptr != xsec && xsec->GetName() == name) { return xsec; }
}
G4VComponentCrossSection* ptr = nullptr;
return ptr;
@@ -49,25 +49,28 @@
#include "G4KaonZeroShort.hh"
#include "G4KaonZeroLong.hh"
static const G4double invGeV = 1.0/CLHEP::GeV;
static const G4double invGeV2 = 1.0/(CLHEP::GeV*CLHEP::GeV);
// PDG fit constants
static const G4double minLogP = 3.5; // min of (lnP-minLogP)^2
static const G4double cofLogE = .0557; // elastic (lnP-minLogP)^2
static const G4double cofLogT = .3; // total (lnP-minLogP)^2
static const G4double pMin = .1; // fast LE calculation
static const G4double pMax = 1000.; // fast HE calculation
static const G4double ekinmin = 0.1*CLHEP::MeV; // protection against zero ekin
static const G4double ekinmaxQB = 100*CLHEP::MeV; // max kinetic energy for Coulomb barrier
namespace
{
const G4double invGeV = 1.0/CLHEP::GeV;
const G4double invGeV2 = 1.0/(CLHEP::GeV*CLHEP::GeV);
// PDG fit constants
const G4double minLogP = 3.5; // min of (lnP-minLogP)^2
const G4double cofLogE = .0557; // elastic (lnP-minLogP)^2
const G4double cofLogT = .3; // total (lnP-minLogP)^2
const G4double pMin = .1; // fast LE calculation
const G4double pMax = 1000.; // fast HE calculation
const G4double ekinmin = 0.1*CLHEP::MeV; // protection against zero ekin
const G4double ekinmaxQB = 100*CLHEP::MeV; // max kinetic energy for Coulomb barrier
}
G4HadronNucleonXsc::G4HadronNucleonXsc()
: fTotalXsc(0.0), fElasticXsc(0.0), fInelasticXsc(0.0)
{
// basic hadrons
theProton = G4Proton::Proton();
theNeutron = G4Neutron::Neutron();
thePiPlus = G4PionPlus::PionPlus();
// strange
// basic strange mesons
theKPlus = G4KaonPlus::KaonPlus();
theKMinus = G4KaonMinus::KaonMinus();
theK0S = G4KaonZeroShort::KaonZeroShort();
@@ -76,9 +79,6 @@ G4HadronNucleonXsc::G4HadronNucleonXsc()
g4calc = G4Pow::GetInstance();
}
G4HadronNucleonXsc::~G4HadronNucleonXsc()
{}
void G4HadronNucleonXsc::CrossSectionDescription(std::ostream& outFile) const
{
outFile << "G4HadronNucleonXsc calculates the total, inelastic and elastic\n"
@@ -28,7 +28,7 @@
//
// GEANT4 Class file
//
// Description: Data structure for cross sections per materials
// Description: Data structure for registration of static cross sections components
//
// Author: V.Ivanchenko 31.05.2018
//
@@ -40,126 +40,62 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "G4HadronXSDataTable.hh"
#include "G4PhysicsLogVector.hh"
#include "G4Material.hh"
#include "G4MaterialTable.hh"
#include "G4DynamicParticle.hh"
#include "G4CrossSectionDataStore.hh"
G4HadronXSDataTable* G4HadronXSDataTable::sInstance = nullptr;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4HadElementSelector::G4HadElementSelector(G4DynamicParticle* dp,
G4CrossSectionDataStore* xs,
const G4Material* mat,
G4int bins, G4double emin,
G4double emax, G4bool)
{
std::size_t n = mat->GetNumberOfElements();
nElmMinusOne = G4int(n - 1);
theElementVector = mat->GetElementVector();
if(nElmMinusOne > 0) {
G4PhysicsVector* first = nullptr;
xSections.resize(n, first);
first = new G4PhysicsLogVector(emin,emax,bins,false);
xSections[0] = first;
for(std::size_t i=1; i<n; ++i) {
xSections[i] = new G4PhysicsVector(*first);
}
std::vector<G4double> temp;
temp.resize(n, 0.0);
for(G4int j=0; j<=bins; ++j) {
G4double cross = 0.0;
G4double e = first->Energy(j);
dp->SetKineticEnergy(e);
for(std::size_t i=0; i<n; ++i) {
cross += xs->GetCrossSection(dp, (*theElementVector)[i], mat);
temp[i] = cross;
}
G4double fact = (cross > 0.0) ? 1.0/cross : 0.0;
for(std::size_t i=0; i<n; ++i) {
G4double y = (i<n-1) ? temp[i]*fact : 1.0;
xSections[i]->PutValue(j, y);
}
}
G4HadronXSDataTable* G4HadronXSDataTable::Instance() {
if ( sInstance == nullptr ) {
static G4HadronXSDataTable theObject;
sInstance = &theObject;
}
return sInstance;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4HadElementSelector::~G4HadElementSelector()
{
if(nElmMinusOne > 0) {
for(G4int i=0; i<=nElmMinusOne; ++i) { delete xSections[i]; }
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4HadElementSelector::Dump()
G4HadronXSDataTable::G4HadronXSDataTable()
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4HadronXSDataTable::G4HadronXSDataTable() : nMaterials(0)
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4HadronXSDataTable::Initialise(G4DynamicParticle* dp,
G4CrossSectionDataStore* xs,
G4int bins, G4double emin, G4double emax,
G4bool spline)
{
std::size_t nn = G4Material::GetNumberOfMaterials();
if(nn > nMaterials) {
if(0 == nMaterials) {
xsData.reserve(nn);
elmSelectors.reserve(nn);
}
G4PhysicsLogVector* first = nullptr;
G4int sbins = std::max(10, bins/5);
const G4MaterialTable* mtable = G4Material::GetMaterialTable();
for(std::size_t i=nMaterials; i<nn; ++i) {
const G4Material* mat = (*mtable)[i];
G4PhysicsVector* v = nullptr;
G4HadElementSelector* es = nullptr;
// create real vector only for complex materials
if(mat->GetNumberOfElements() > 1) {
if(nullptr == first) {
first = new G4PhysicsLogVector(emin, emax, bins, spline);
v = first;
} else {
v = new G4PhysicsVector(*first);
}
for(G4int j=0; j<=bins; ++j) {
G4double e = first->Energy(j);
dp->SetKineticEnergy(e);
G4double cros = xs->ComputeCrossSection(dp, mat);
v->PutValue(j, cros);
}
if(spline) v->FillSecondDerivatives();
elmSelectors[i] = new G4HadElementSelector(dp, xs, mat, sbins, emin, emax, spline);
}
xsData.push_back(v);
elmSelectors.push_back(es);
}
nMaterials = nn;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4HadronXSDataTable::~G4HadronXSDataTable()
{
for(std::size_t i=0; i<nMaterials; ++i) {
delete xsData[i];
delete elmSelectors[i];
for (auto & ptr : fPiData) {
delete ptr;
}
for (auto & ptr : fTable) {
ptr->clearAndDestroy();
delete ptr;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4HadronXSDataTable::Dump()
{}
void G4HadronXSDataTable::AddPiData(std::vector<G4PiData*>* ptr)
{
if (nullptr == ptr || ptr->empty()) { return; }
for (auto & p : *ptr) {
G4bool ok = true;
for (auto & d : fPiData) {
if (p == d) {
ok = false;
break;
}
}
if (ok) { fPiData.push_back(p); }
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4HadronXSDataTable::AddTable(G4PhysicsTable* ptr)
{
if (nullptr != ptr) {
for (auto & p : fTable) { if (p == ptr) { return; } }
fTable.push_back(ptr);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -60,11 +60,12 @@ static std::once_flag applyOnce;
namespace
{
G4Mutex neutronCaptureXSMutex = G4MUTEX_INITIALIZER;
const G4int MAXZCAPTURE = 92;
}
G4NeutronCaptureXS::G4NeutronCaptureXS()
: G4VCrossSectionDataSet(Default_Name()),
emax(20*CLHEP::MeV), elimit(1.0e-10*CLHEP::eV)
emax(20*CLHEP::MeV), elimit(1.0e-5*CLHEP::eV)
{
verboseLevel = 0;
if (verboseLevel > 0) {
@@ -73,7 +74,7 @@ G4NeutronCaptureXS::G4NeutronCaptureXS()
}
logElimit = G4Log(elimit);
if (nullptr == data) {
data = new G4ElementData(MAXZCAPTURE);
data = new G4ElementData(MAXZCAPTURE+1);
data->SetName("nCapture");
FindDirectoryPath();
}
@@ -130,16 +131,20 @@ G4NeutronCaptureXS::ComputeCrossSectionPerElement(G4double ekin, G4double loge,
}
G4double
G4NeutronCaptureXS::ElementCrossSection(G4double ekin, G4double loge, G4int ZZ)
G4NeutronCaptureXS::ElementCrossSection(G4double eKin, G4double logE, G4int ZZ)
{
G4int Z = std::min(ZZ, MAXZCAPTURE-1);
G4double logEkin = loge;
if (ekin < elimit) { ekin = elimit; logEkin = logElimit; }
G4int Z = std::min(ZZ, MAXZCAPTURE);
G4double ekin = eKin;
G4double logEkin = logE;
if (ekin < elimit) {
ekin = elimit;
logEkin = logElimit;
}
auto pv = GetPhysicsVector(Z);
const G4double e1 = pv->Energy(1);
G4double xs = (ekin >= e1) ? pv->LogVectorValue(ekin, logEkin)
: (*pv)[1]*std::sqrt(e1/ekin);
const G4double e0 = pv->Energy(0);
G4double xs = (ekin >= e0) ? pv->LogVectorValue(ekin, logEkin)
: (*pv)[0]*std::sqrt(e0/ekin);
#ifdef G4VERBOSE
if (verboseLevel > 1){
@@ -177,7 +182,7 @@ G4double G4NeutronCaptureXS::IsoCrossSection(G4double eKin, G4double logE,
G4double xs = 0.0;
if (eKin > emax) { return xs; }
G4int Z = std::min(ZZ, MAXZCAPTURE-1);
G4int Z = std::min(ZZ, MAXZCAPTURE);
G4double ekin = eKin;
G4double logEkin = logE;
if (ekin < elimit) {
@@ -188,12 +193,13 @@ G4double G4NeutronCaptureXS::IsoCrossSection(G4double eKin, G4double logE,
auto pv = GetPhysicsVector(Z);
if (pv == nullptr) { return xs; }
// use isotope x-section if possible
if (data->GetNumberOfComponents(Z) > 0) {
G4PhysicsVector* pviso = data->GetComponentDataByID(Z, A);
if(pviso != nullptr) {
const G4double e1 = pviso->Energy(1);
xs = (ekin >= e1) ? pviso->LogVectorValue(ekin, logEkin)
: (*pviso)[1]*std::sqrt(e1/ekin);
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
@@ -205,9 +211,9 @@ G4double G4NeutronCaptureXS::IsoCrossSection(G4double eKin, G4double logE,
}
}
// isotope data are not available or applicable
const G4double e1 = pv->Energy(1);
xs = (ekin >= e1) ? pv->LogVectorValue(ekin, logEkin)
: (*pv)[1]*std::sqrt(e1/ekin);
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
@@ -238,7 +244,7 @@ G4NeutronCaptureXS::SelectIsotope(const G4Element* anElement,
// is there isotope wise cross section?
G4int j;
if (Z >= MAXZCAPTURE || 0 == data->GetNumberOfComponents(Z)) {
if (Z > MAXZCAPTURE || 0 == data->GetNumberOfComponents(Z)) {
for (j = 0; j<nIso; ++j) {
sum += abundVector[j];
if(q <= sum) {
@@ -292,7 +298,7 @@ G4NeutronCaptureXS::BuildPhysicsTable(const G4ParticleDefinition& p)
G4AutoLock l(&neutronCaptureXSMutex);
// Access to elements
for ( auto const & elm : *table ) {
G4int Z = std::max( 1, std::min( elm->GetZasInt(), MAXZCAPTURE-1) );
G4int Z = std::max( 1, std::min( elm->GetZasInt(), MAXZCAPTURE) );
if ( nullptr == data->GetElementData(Z) ) { Initialise(Z); }
}
l.unlock();
@@ -67,13 +67,15 @@ namespace
G4NeutronInelasticXS::G4NeutronInelasticXS()
: G4VCrossSectionDataSet(Default_Name()),
neutron(G4Neutron::Neutron()),
elimit(20*CLHEP::MeV)
elimit(20*CLHEP::MeV),
lowElimit(1.0e-5*CLHEP::eV)
{
verboseLevel = 0;
if (verboseLevel > 0){
G4cout << "G4NeutronInelasticXS::G4NeutronInelasticXS Initialise for Z < "
<< MAXZINEL << G4endl;
<< MAXZINEL << G4endl;
}
loglowElimit = G4Log(lowElimit);
if (nullptr == data) {
data = new G4ElementData(MAXZINEL);
data->SetName("nInelastic");
@@ -83,6 +85,7 @@ G4NeutronInelasticXS::G4NeutronInelasticXS()
G4CrossSectionDataSetRegistry::Instance()->GetComponentCrossSection("Glauber-Gribov");
if(ggXsection == nullptr)
ggXsection = new G4ComponentGGHadronNucleusXsc();
SetForAllAtomsAndEnergies(true);
}
@@ -97,22 +100,22 @@ void G4NeutronInelasticXS::CrossSectionDescription(std::ostream& outFile) const
G4bool
G4NeutronInelasticXS::IsElementApplicable(const G4DynamicParticle*,
G4int, const G4Material*)
G4int, const G4Material*)
{
return true;
}
G4bool
G4NeutronInelasticXS::IsIsoApplicable(const G4DynamicParticle*,
G4int, G4int,
const G4Element*, const G4Material*)
G4int, G4int,
const G4Element*, const G4Material*)
{
return true;
}
G4double
G4NeutronInelasticXS::GetElementCrossSection(const G4DynamicParticle* aParticle,
G4int Z, const G4Material*)
G4int Z, const G4Material*)
{
return ElementCrossSection(aParticle->GetKineticEnergy(),
aParticle->GetLogKineticEnergy(), Z);
@@ -120,29 +123,44 @@ G4NeutronInelasticXS::GetElementCrossSection(const G4DynamicParticle* aParticle,
G4double
G4NeutronInelasticXS::ComputeCrossSectionPerElement(G4double ekin, G4double loge,
const G4ParticleDefinition*,
const G4Element* elm,
const G4Material*)
const G4ParticleDefinition*,
const G4Element* elm,
const G4Material*)
{
return ElementCrossSection(ekin, loge, elm->GetZasInt());
}
G4double
G4NeutronInelasticXS::ElementCrossSection(G4double ekin, G4double loge, G4int ZZ)
G4NeutronInelasticXS::ElementCrossSection(G4double eKin, G4double logE, G4int ZZ)
{
G4int Z = (ZZ >= MAXZINEL) ? MAXZINEL - 1 : ZZ;
G4int Z = std::min(ZZ, MAXZINEL-1);
G4double ekin = eKin;
G4double loge = logE;
if (ekin < lowElimit) {
ekin = lowElimit;
loge = loglowElimit;
}
// pv should exist
auto pv = GetPhysicsVector(Z);
G4double xs = (ekin <= pv->GetMaxEnergy()) ? pv->LogVectorValue(ekin, loge)
: coeff[Z]*ggXsection->GetInelasticElementCrossSection(neutron, ekin,
Z, aeff[Z]);
const G4double e0 = pv->Energy(0);
G4double xs;
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]);
}
#ifdef G4VERBOSE
if(verboseLevel > 1) {
G4cout << "G4NeutronInelasticXS::ElementCrossSection Z= " << Z
<< " Ekin(MeV)= " << ekin/CLHEP::MeV
<< ", ElmXSinel(b)= " << xs/CLHEP::barn
<< G4endl;
<< ", ElmXSinel(b)= " << xs/CLHEP::barn
<< G4endl;
}
#endif
return xs;
@@ -150,51 +168,62 @@ G4NeutronInelasticXS::ElementCrossSection(G4double ekin, G4double loge, G4int ZZ
G4double
G4NeutronInelasticXS::ComputeIsoCrossSection(G4double ekin, G4double loge,
const G4ParticleDefinition*,
G4int Z, G4int A,
const G4Isotope*, const G4Element*,
const G4Material*)
const G4ParticleDefinition*,
G4int Z, G4int A,
const G4Isotope*, const G4Element*,
const G4Material*)
{
return IsoCrossSection(ekin, loge, Z, A);
}
G4double
G4NeutronInelasticXS::GetIsoCrossSection(const G4DynamicParticle* aParticle,
G4int Z, G4int A,
const G4Isotope*, const G4Element*,
const G4Material*)
G4int Z, G4int A,
const G4Isotope*, const G4Element*,
const G4Material*)
{
return IsoCrossSection(aParticle->GetKineticEnergy(),
aParticle->GetLogKineticEnergy(), Z, A);
}
G4double
G4NeutronInelasticXS::IsoCrossSection(G4double ekin, G4double logekin,
G4NeutronInelasticXS::IsoCrossSection(G4double eKin, G4double logE,
G4int ZZ, G4int A)
{
G4double xs = 0.0;
G4int Z = (ZZ >= MAXZINEL) ? MAXZINEL - 1 : ZZ;
G4int Z = std::min(ZZ, MAXZINEL-1);
G4double ekin = eKin;
G4double loge = logE;
if (ekin < lowElimit) {
ekin = lowElimit;
loge = loglowElimit;
}
auto pv = GetPhysicsVector(Z);
/*
G4cout << "G4NeutronInelasticXS::IsoCrossSection Z= "
<< Z << " A= " << A << G4endl;
G4cout << " Amin= " << amin[Z] << " Amax= " << amax[Z]
<< " E(MeV)= " << ekin << " Ncomp="
<< data->GetNumberOfComponents(Z) << G4endl;
<< data->GetNumberOfComponents(Z) << G4endl;
*/
// compute isotope cross section if applicable
// use isotope cross section if applicable
if (ekin <= elimit && data->GetNumberOfComponents(Z) > 0) {
auto pviso = data->GetComponentDataByID(Z, A);
if (nullptr != pviso) {
xs = pviso->LogVectorValue(ekin, logekin);
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); }
}
#ifdef G4VERBOSE
if(verboseLevel > 1) {
G4cout << "G4NeutronInelasticXS::IsoXS: Ekin(MeV)= "
G4cout << "G4NeutronInelasticXS::IsoXS: Ekin(MeV)= "
<< ekin/CLHEP::MeV
<< " xs(b)= " << xs/CLHEP::barn
<< " Z= " << Z << " A= " << A << G4endl;
<< " xs(b)= " << xs/CLHEP::barn
<< " Z= " << Z << " A= " << A << G4endl;
}
#endif
return xs;
@@ -202,15 +231,24 @@ G4NeutronInelasticXS::IsoCrossSection(G4double ekin, G4double logekin,
}
// use element x-section
xs = (ekin <= pv->GetMaxEnergy()) ? pv->LogVectorValue(ekin, logekin)
: coeff[Z]*ggXsection->GetInelasticElementCrossSection(neutron, ekin,
Z, aeff[Z]);
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]);
}
xs *= A/aeff[Z];
#ifdef G4VERBOSE
if(verboseLevel > 1) {
G4cout << "G4NeutronInelasticXS::IsoXS: Z= " << Z << " A= " << A
<< " Ekin(MeV)= " << ekin/CLHEP::MeV
<< ", ElmXS(b)= " << xs/CLHEP::barn << G4endl;
<< " Ekin(MeV)= " << ekin/CLHEP::MeV
<< ", ElmXS(b)= " << xs/CLHEP::barn << G4endl;
}
#endif
return xs;
@@ -219,7 +257,7 @@ G4NeutronInelasticXS::IsoCrossSection(G4double ekin, G4double logekin,
const G4Isotope* G4NeutronInelasticXS::SelectIsotope(
const G4Element* anElement, G4double kinEnergy, G4double logE)
{
G4int nIso = (G4int)anElement->GetNumberOfIsotopes();
std::size_t nIso = anElement->GetNumberOfIsotopes();
const G4Isotope* iso = anElement->GetIsotope(0);
if(1 == nIso) { return iso; }
@@ -230,35 +268,35 @@ const G4Isotope* G4NeutronInelasticXS::SelectIsotope(
const G4double* abundVector = anElement->GetRelativeAbundanceVector();
G4double q = G4UniformRand();
G4double sum = 0.0;
G4int j;
std::size_t j;
// isotope wise cross section not available
if (Z >= MAXZINEL || 0 == data->GetNumberOfComponents(Z)) {
for (j=0; j<nIso; ++j) {
sum += abundVector[j];
if(q <= sum) {
iso = anElement->GetIsotope(j);
break;
iso = anElement->GetIsotope((G4int)j);
break;
}
}
return iso;
}
// use isotope cross sections
G4int nn = (G4int)temp.size();
auto nn = temp.size();
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(j)->GetN());
anElement->GetIsotope((G4int)j)->GetN());
temp[j] = sum;
}
sum *= q;
for (j = 0; j<nIso; ++j) {
if (temp[j] >= sum) {
iso = anElement->GetIsotope(j);
iso = anElement->GetIsotope((G4int)j);
break;
}
}
@@ -270,14 +308,14 @@ G4NeutronInelasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
{
if (verboseLevel > 0) {
G4cout << "G4NeutronInelasticXS::BuildPhysicsTable for "
<< p.GetParticleName() << G4endl;
<< p.GetParticleName() << G4endl;
}
if (p.GetParticleName() != "neutron") {
G4ExceptionDescription ed;
ed << p.GetParticleName() << " is a wrong particle type -"
<< " only neutron is allowed";
G4Exception("G4NeutronInelasticXS::BuildPhysicsTable(..)","had012",
FatalException, ed, "");
FatalException, ed, "");
return;
}
// it is possible re-initialisation for the new run
@@ -334,8 +372,8 @@ void G4NeutronInelasticXS::Initialise(G4int Z)
data->InitialiseForElement(Z, v);
if (verboseLevel > 1) {
G4cout << "G4NeutronInelasticXS::Initialise for Z= " << Z
<< " A= " << aeff[Z] << " Amin= " << amin[Z]
<< " Amax= " << amax[Z] << G4endl;
<< " A= " << aeff[Z] << " Amin= " << amin[Z]
<< " Amax= " << amax[Z] << G4endl;
}
// upload isotope data
G4bool noComp = true;
@@ -346,12 +384,12 @@ void G4NeutronInelasticXS::Initialise(G4int Z)
ost1 << gDataDirectory << Z << "_" << A;
G4PhysicsVector* v1 = RetrieveVector(ost1, false);
if (nullptr != v1) {
if (noComp) {
G4int nmax = amax[Z] - A + 1;
data->InitialiseForComponent(Z, nmax);
noComp = false;
}
data->AddComponent(Z, A, v1);
if (noComp) {
G4int nmax = amax[Z] - A + 1;
data->InitialiseForComponent(Z, nmax);
noComp = false;
}
data->AddComponent(Z, A, v1);
}
}
}
@@ -362,7 +400,7 @@ void G4NeutronInelasticXS::Initialise(G4int Z)
G4double sig1 = (*v)[v->GetVectorLength()-1];
G4double ehigh= v->GetMaxEnergy();
G4double sig2 = ggXsection->GetInelasticElementCrossSection(neutron,
ehigh, Z, aeff[Z]);
ehigh, Z, aeff[Z]);
coeff[Z] = (sig2 > 0.) ? sig1/sig2 : 1.0;
}
@@ -375,23 +413,23 @@ G4NeutronInelasticXS::RetrieveVector(std::ostringstream& ost, G4bool warn)
if(warn) {
G4ExceptionDescription ed;
ed << "Data file <" << ost.str().c_str()
<< "> is not opened!";
<< "> is not opened!";
G4Exception("G4NeutronInelasticXS::RetrieveVector(..)","had014",
FatalException, ed, "Check G4PARTICLEXSDATA");
FatalException, ed, "Check G4PARTICLEXSDATA");
}
} else {
if(verboseLevel > 1) {
G4cout << "File " << ost.str()
<< " is opened by G4NeutronInelasticXS" << G4endl;
<< " is opened by G4NeutronInelasticXS" << 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!";
<< "> is not retrieved!";
G4Exception("G4NeutronInelasticXS::RetrieveVector(..)","had015",
FatalException, ed, "Check G4PARTICLEXSDATA");
FatalException, ed, "Check G4PARTICLEXSDATA");
}
}
return v;
@@ -35,27 +35,16 @@
#include "G4NucleonNuclearCrossSection.hh"
#include "G4DynamicParticle.hh"
#include "G4ParticleDefinition.hh"
#include "G4Neutron.hh"
#include "G4Proton.hh"
#include "G4ComponentBarNucleonNucleusXsc.hh"
///////////////////////////////////////////////////////////////////////////////
G4NucleonNuclearCrossSection::G4NucleonNuclearCrossSection()
: G4VCrossSectionDataSet(Default_Name()),
fTotalXsc(0.0), fInelasticXsc(0.0), fElasticXsc(0.0)
: G4VCrossSectionDataSet(Default_Name())
{
theNeutron = G4Neutron::Neutron();
theProton = G4Proton::Proton();
fBarash = new G4ComponentBarNucleonNucleusXsc();
}
///////////////////////////////////////////////////////////////////////////////
//
G4NucleonNuclearCrossSection::~G4NucleonNuclearCrossSection()
{}
////////////////////////////////////////////////////////////////////////////
G4bool G4NucleonNuclearCrossSection::IsElementApplicable(
@@ -87,13 +76,6 @@ void G4NucleonNuclearCrossSection::ComputeCrossSections(
////////////////////////////////////////////////////////////////////////////
void G4NucleonNuclearCrossSection::BuildPhysicsTable(const G4ParticleDefinition& part)
{
fBarash->BuildPhysicsTable(part);
}
////////////////////////////////////////////////////////////////////////////
void
G4NucleonNuclearCrossSection::CrossSectionDescription(std::ostream& outFile) const
{
@@ -35,9 +35,7 @@
G4PiData::G4PiData(const G4double * aT, const G4double * aIn,
const G4double * anE, G4int nP)
{
G4int i=0;
for( i = 0; i < nP; i++ )
for(G4int i = 0; i < nP; ++i )
{
std::pair<G4double, G4double> x;
x.first=aT[i]*millibarn;
@@ -46,23 +44,27 @@ G4PiData::G4PiData(const G4double * aT, const G4double * aIn,
aP.first=anE[i]*GeV;
aP.second=x;
push_back(aP);
if (i == 0) {
fMinE = aP.first;
fTot0 = x.first;
fInel0 = x.second;
} else if (i+1 == nP) {
fMaxE = aP.first;
fTot1 = x.first;
fInel1 = x.second;
}
}
}
////////////////////////////////////////////////////////////////////////
G4bool G4PiData::AppliesTo(G4double kineticEnergy)
{
return (kineticEnergy<=back().first);
}
//////////////////////////////////////////////////////////////////////////
G4double G4PiData::ReactionXSection(G4double kineticEnergy)
{
G4double result = 0;
if (kineticEnergy <= fMinE) { return fInel0; }
if (kineticEnergy >= fMaxE) { return fInel1; }
G4PiData::iterator it=begin();
while(it!=end()&&kineticEnergy>(*it).first) {it++;} /* Loop checking, 08.01.2016, W. Pokorski */
while(it!=end()&&kineticEnergy>(*it).first) {++it;} /* Loop checking, 08.01.2016, W. Pokorski */
if(it==end())
{
G4ExceptionDescription ed;
@@ -76,15 +78,16 @@ G4double G4PiData::ReactionXSection(G4double kineticEnergy)
x1=(*(it-1)).second.second;
e2=(*(it)).first;
x2=(*(it)).second.second;
result = std::max(0., x1 + (kineticEnergy-e1)*(x2-x1)/(e2-e1));
return result;
return std::max(0., x1 + (kineticEnergy-e1)*(x2-x1)/(e2-e1));
}
////////////////////////////////////////////////////////////////////////////
G4double G4PiData::ElasticXSection(G4double kineticEnergy)
{
G4double result = 0;
if (kineticEnergy <= fMinE) { return fTot0 - fInel0; }
if (kineticEnergy >= fMaxE) { return fTot1 - fInel1; }
G4PiData::iterator it=begin();
while(it!=end()&&kineticEnergy>(*it).first) {it++;} /* Loop checking, 08.01.2016, W. Pokorski */
if(it==end())
@@ -100,15 +103,16 @@ G4double G4PiData::ElasticXSection(G4double kineticEnergy)
x1=(*(it-1)).second.first - (*(it-1)).second.second;
e2=(*(it)).first;
x2=(*(it)).second.first - (*(it)).second.second;
result = std::max(0., x1 + (kineticEnergy-e1)*(x2-x1)/(e2-e1));
return result;
return std::max(0., x1 + (kineticEnergy-e1)*(x2-x1)/(e2-e1));
}
////////////////////////////////////////////////////////////////////////////
G4double G4PiData::TotalXSection(G4double kineticEnergy)
{
G4double result = 0;
if (kineticEnergy <= fMinE) { return fTot0; }
if (kineticEnergy >= fMaxE) { return fTot1; }
G4PiData::iterator it=begin();
while(it!=end()&&kineticEnergy>(*it).first) {it++;} /* Loop checking, 08.01.2016, W. Pokorski */
if(it==end())
@@ -124,6 +128,5 @@ G4double G4PiData::TotalXSection(G4double kineticEnergy)
x1=(*(it-1)).second.first;
e2=(*(it)).first;
x2=(*(it)).second.first;
result = std::max(0., x1 + (kineticEnergy-e1)*(x2-x1)/(e2-e1));
return result;
return std::max(0., x1 + (kineticEnergy-e1)*(x2-x1)/(e2-e1));
}
@@ -42,6 +42,7 @@
#include "G4PionPlus.hh"
#include "G4PhysicsTable.hh"
#include "G4NistManager.hh"
#include "G4HadronXSDataTable.hh"
G4int G4UPiNuclearCrossSection::theZ[NZ] =
{2,4,6,7,8,11,13,20,26,29,42,48,50,74,82,92};
@@ -54,47 +55,14 @@ G4PhysicsTable* G4UPiNuclearCrossSection::piPlusInelastic = nullptr;
G4PhysicsTable* G4UPiNuclearCrossSection::piMinusElastic = nullptr;
G4PhysicsTable* G4UPiNuclearCrossSection::piMinusInelastic = nullptr;
#ifdef G4MULTITHREADED
G4Mutex G4UPiNuclearCrossSection::pionUXSMutex = G4MUTEX_INITIALIZER;
#endif
G4UPiNuclearCrossSection::G4UPiNuclearCrossSection()
: G4VCrossSectionDataSet("G4UPiNuclearCrossSection")
{
isMaster = false;
spline = false;
piPlus = G4PionPlus::PionPlus();
piPlus = G4PionPlus::PionPlus();
piMinus = G4PionMinus::PionMinus();
elow = 20.0*CLHEP::MeV;
aPower = 0.75;
elow = 20.0*CLHEP::MeV;
}
G4UPiNuclearCrossSection::~G4UPiNuclearCrossSection()
{
if(isMaster) {
if(piPlusElastic) {
piPlusElastic->clearAndDestroy();
delete piPlusElastic;
piPlusElastic = nullptr;
}
if(piPlusInelastic) {
piPlusInelastic->clearAndDestroy();
delete piPlusInelastic;
piPlusInelastic = nullptr;
}
if(piMinusElastic) {
piMinusElastic->clearAndDestroy();
delete piMinusElastic;
piMinusElastic = nullptr;
}
if(piMinusInelastic) {
piMinusInelastic->clearAndDestroy();
delete piMinusInelastic;
piMinusInelastic = nullptr;
}
}
if (idxZ[0] == 0) { LoadData(); }
}
G4bool
@@ -111,7 +79,7 @@ G4double G4UPiNuclearCrossSection::Interpolate(
G4double ekin = std::max(e, elow);
G4int iz = std::min(Z, 92);
G4int idx = idxZ[iz];
size_t jdx = (size_t)(std::max(ekin - elow, 0.0)*0.06);
std::size_t jdx = (std::size_t)(std::max(ekin - elow, 0.0)*0.06);
//G4cout << "Interpolate: Z= " << iz << " A= " << A << " idx= " << idx
// << " jdx= " << jdx << " Ekin= " << ekin << G4endl;
if(idx < 0 || 2 == iz) {
@@ -138,15 +106,15 @@ void G4UPiNuclearCrossSection::AddDataSet(const G4String& p,
{
G4PhysicsFreeVector* pvin = new G4PhysicsFreeVector(n,e[0]*GeV,e[n-1]*GeV,spline);
G4PhysicsFreeVector* pvel = new G4PhysicsFreeVector(n,e[0]*GeV,e[n-1]*GeV,spline);
for(G4int i=0; i<n; ++i) {
pvin->PutValues(i,e[i]*GeV,in[i]*millibarn);
pvel->PutValues(i,e[i]*GeV,std::max(0.0,(tot[i]-in[i])*millibarn));
for (G4int i=0; i<n; ++i) {
pvin->PutValues(i, e[i]*CLHEP::GeV, in[i]*CLHEP::millibarn);
pvel->PutValues(i, e[i]*CLHEP::GeV, std::max(0.0,(tot[i]-in[i])*CLHEP::millibarn));
}
if(spline) {
if (spline) {
pvin->FillSecondDerivatives();
pvel->FillSecondDerivatives();
}
if(p == "pi+") {
if (p == "pi+") {
piPlusInelastic->push_back(pvin);
piPlusElastic->push_back(pvel);
} else {
@@ -172,39 +140,26 @@ void G4UPiNuclearCrossSection::DumpPhysicsTable(const G4ParticleDefinition& p)
void G4UPiNuclearCrossSection::BuildPhysicsTable(const G4ParticleDefinition& p)
{
//G4cout << "G4UPiNuclearCrossSection::BuildPhysicsTable for "
// << p.GetParticleName() << " " << piPlusElastic << G4endl;
if(piPlusElastic) { return; }
if(&p != piPlus && &p != piMinus) {
G4ExceptionDescription ed;
ed << "This cross section is applicable only to pions and not to "
<< p.GetParticleName() << G4endl;
G4Exception("G4UPiNuclearCrossSection::BuildPhysicsTable", "had001",
FatalException, ed);
return;
}
}
if(!piPlusElastic) {
#ifdef G4MULTITHREADED
G4MUTEXLOCK(&pionUXSMutex);
if(!piPlusElastic) {
#endif
isMaster = true;
#ifdef G4MULTITHREADED
}
G4MUTEXUNLOCK(&pionUXSMutex);
#endif
}
if(!isMaster) { return; }
void G4UPiNuclearCrossSection::LoadData()
{
idxZ[0] = 1;
idxZ[1] = idxZ[2] = 0;
G4NistManager* nist = G4NistManager::Instance();
G4Pow* g4pow = G4Pow::GetInstance();
for(G4int i=0; i<NZ; ++i) {
theA[i] = nist->GetAtomicMassAmu(theZ[i]);
}
for(G4int i=1; i<93; ++i) {
APower[i] = g4pow->powA(nist->GetAtomicMassAmu(i),aPower);
APower[i] = g4pow->powA(nist->GetAtomicMassAmu(i), aPower);
}
G4int idx = 1;
for(G4int i=3; i<93; ++i) {
@@ -220,13 +175,12 @@ void G4UPiNuclearCrossSection::BuildPhysicsTable(const G4ParticleDefinition& p)
piPlusInelastic = new G4PhysicsTable();
piMinusElastic = new G4PhysicsTable();
piMinusInelastic = new G4PhysicsTable();
auto ptr = G4HadronXSDataTable::Instance();
ptr->AddTable(piPlusElastic);
ptr->AddTable(piPlusInelastic);
ptr->AddTable(piMinusElastic);
ptr->AddTable(piMinusInelastic);
LoadData();
//G4cout << "### Initialisation done " << G4endl;
}
void G4UPiNuclearCrossSection::LoadData()
{
static const G4double e1[38] = {
0.02, 0.04, 0.06, 0.08, 0.1, 0.12, 0.13, 0.14, 0.15, 0.16,
0.17, 0.18, 0.19, 0.2, 0.22,0.24, 0.26, 0.28, 0.3, 0.35,
@@ -47,9 +47,8 @@
#include "G4HadronicParameters.hh"
G4VCrossSectionDataSet::G4VCrossSectionDataSet(const G4String& nam) :
verboseLevel(0),name(nam),minKinEnergy(0.0),
maxKinEnergy(G4HadronicParameters::Instance()->GetMaxEnergy()),
isForAllAtomsAndEnergies(false)
name(nam),
maxKinEnergy(G4HadronicParameters::Instance()->GetMaxEnergy())
{
registry = G4CrossSectionDataSetRegistry::Instance();
registry->Register(this);
+5 -2
View File
@@ -6,10 +6,13 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2024-05-27 Vladimir Ivanchenko (hadr-man-V11-02-01)
- G4HadronicProcessStore - fixed handling of rare processes: printout,
cross section maximum search, and deletion end of run.
## 2023-12-09 Vladimir Ivanchenko (hadr-man-V11-01-09)
## 2023-12-09 Vladimir Ivanchenko (hadr-man-V11-02-00)
- G4HadronicProcess - explicitly define cross section type per particle type,
this should improve CPU performance for hadronic showers for ~1%
this should CPU performance for few %
## 2023-11-18 I. Hrivnacova (hadr-man-V11-01-08)
- G4HadronicProcess, G4HadXSHelper - fixed memory leak at exit
@@ -477,8 +477,8 @@ void G4HadronicProcessStore::RegisterExtraProcess(G4VProcess* proc)
for(G4int i=0; i<n_extra; ++i) {
if(extraProcess[i] == proc) { return; }
}
G4HadronicProcess* hproc = static_cast<G4HadronicProcess*>(proc);
if(hproc) {
G4HadronicProcess* hproc = dynamic_cast<G4HadronicProcess*>(proc);
if (nullptr != hproc) {
for(G4int i=0; i<n_proc; ++i) {
if(process[i] == hproc) { return; }
}
@@ -6,6 +6,21 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2024-04-29 Jose Luis Rodriguez Sanchez (hadr-abla-V11-02-04)
- Added the dissipation parameter for heavy hypernuclei
## 2024-04-19 Jose Luis Rodriguez Sanchez (hadr-abla-V11-02-03)
- Cleaning up the classes doing it more general
## 2024-04-07 Jose Luis Rodriguez Sanchez (hadr-abla-V11-02-02)
- Cleaning up the class G4AblaDataDefs.hh, removed unused data structures
## 2024-03-29 Jose Luis Rodriguez Sanchez (hadr-abla-V11-02-01)
- Changed int, double and bool to G4 format and cleaning up of ABLA classes
## 2024-03-28 Jose Luis Rodriguez Sanchez (hadr-abla-V11-02-00)
- Added pragma once for compilation and array extension for super-heavy nuclei
## 2023-03-24 Alberto Ribon (hadr-abla-V11-01-00)
- G4AblaInterface : implemented method ApplyYourself to allow the coupling
between Binary Cascade (BIC) and Abla, i.e. using BIC for the cascade and
@@ -24,28 +24,20 @@
// ********************************************************************
//
// ABLAXX statistical de-excitation model
// Jose Luis Rodriguez, GSI (translation from ABLA07 and contact person)
// Jose Luis Rodriguez, UDC (translation from ABLA07 and contact person)
// Pekka Kaitaniemi, HIP (initial translation of ablav3p)
// Aleksandra Kelic, GSI (ABLA07 code)
// Davide Mancusi, CEA (contact person INCL)
// Aatos Heikkinen, HIP (project coordination)
//
#define ABLAXX_IN_GEANT4_MODE 1
#pragma once
#include "globals.hh"
#include <memory>
#ifndef G4Abla_hh
#define G4Abla_hh 1
#ifdef ABLAXX_IN_GEANT4_MODE
#include "globals.hh"
#else
#include "G4INCLGeant4Compat.hh"
#include "G4INCLConfig.hh"
#endif
#include "G4AblaRandom.hh"
#include "G4AblaDataDefs.hh"
#include "G4AblaRandom.hh"
/**
* Class containing ABLA++ de-excitation code.
@@ -55,22 +47,20 @@ class G4Abla {
public:
/**
* This constructor is used by standalone test driver and the Geant4 interface.
* This constructor is used by standalone test driver and the Geant4
* interface.
*
* @param aHazard random seeds
* @param aVolant data structure for ABLA output
* @param aVarNtp data structure for transfering ABLA output to Geant4 interface
* @param aVarNtp data structure for transfering ABLA output to Geant4
* interface
*/
#ifdef ABLAXX_IN_GEANT4_MODE
G4Abla(G4Volant *aVolant, G4VarNtp *aVarntp);
#else
G4Abla(G4INCL::Config *config, G4Volant *aVolant, G4VarNtp *aVarntp);
#endif
G4Abla(G4VarNtp *aVarntp);
/**
* Basic destructor.
*/
~G4Abla();
~G4Abla() = default;
/// \brief Dummy copy constructor
G4Abla(G4Abla const &other);
@@ -83,26 +73,23 @@ public:
*/
void setVerboseLevel(G4int level);
/**
* Get the internal output data structure pointer.
*/
G4Volant* getVolant() {
return volant;
}
/**
* Main interface to the de-excitation code.
*
* @param nucleusA mass number of the nucleus
* @param nucleusZ charge number of the nucleus
* @param excitationEnergy excitation energy of the nucleus
* @param angularMomentum angular momentum of the nucleus (produced as output by INCL4)
* @param angularMomentum angular momentum of the nucleus (produced as output
* by INCL4)
* @param momX momentum x-component
* @param momY momentum y-component
* @param momZ momentum z-component
* @param eventnumber number of the event
*/
void DeexcitationAblaxx(G4int nucleusA, G4int nucleusZ, G4double excitationEnergy, G4double angularMomentum, G4double momX, G4double momY, G4double momZ, G4int eventnumber);
void DeexcitationAblaxx(G4int nucleusA, G4int nucleusZ,
G4double excitationEnergy, G4double angularMomentum,
G4double momX, G4double momY, G4double momZ,
G4int eventnumber);
/**
* Main interface to the de-excitation code for hyper-nuclei.
@@ -110,14 +97,18 @@ public:
* @param nucleusA mass number of the nucleus
* @param nucleusZ charge number of the nucleus
* @param excitationEnergy excitation energy of the nucleus
* @param angularMomentum angular momentum of the nucleus (produced as output by INCL)
* @param angularMomentum angular momentum of the nucleus (produced as output
* by INCL)
* @param momX momentum x-component
* @param momY momentum y-component
* @param momZ momentum z-component
* @param eventnumber number of the event
* @param nucleusS is the strange number
*/
void DeexcitationAblaxx(G4int nucleusA, G4int nucleusZ, G4double excitationEnergy, G4double angularMomentum, G4double momX, G4double momY, G4double momZ, G4int eventnumber, G4int nucleusS);
void DeexcitationAblaxx(G4int nucleusA, G4int nucleusZ,
G4double excitationEnergy, G4double angularMomentum,
G4double momX, G4double momY, G4double momZ,
G4int eventnumber, G4int nucleusS);
// Evaporation
public:
@@ -135,18 +126,19 @@ public:
void SetParametersG4(G4int z, G4int a);
/**
* Coefficient of collective enhancement including damping
* Input: z,a,bet,sig,u
* Output: qr - collective enhancement factor
* See junghans et al., nucl. phys. a 629 (1998) 635
* Coefficient of collective enhancement including damping
* Input: z,a,bet,sig,u
* Output: qr - collective enhancement factor
* See junghans et al., nucl. phys. a 629 (1998) 635
* @param z charge number
* @param a mass number
* @param bet beta deformation
* @param sig perpendicular spin cut-off factor
* @param u Energy
* @return Coefficient of collective enhancement
* @return Coefficient of collective enhancement
*/
void qrot(G4double z, G4double a, G4double bet, G4double sig, G4double u, G4double *qr);
void qrot(G4double z, G4double a, G4double bet, G4double sig, G4double u,
G4double *qr);
/**
* Model de la goutte liquide de c. f. weizsacker.
@@ -167,202 +159,263 @@ public:
/**
* Calculation of fissility parameter
*/
G4double fissility(G4int a, G4int z, G4int ny, G4double sn, G4double slam, G4int optxfis);
G4double fissility(G4int a, G4int z, G4int ny, G4double sn, G4double slam,
G4int optxfis);
/**
* Main evaporation routine.
*/
void evapora(G4double zprf, G4double aprf, G4double *ee_par, G4double jprf,
G4double *zf_par, G4double *af_par, G4double *mtota_par,
G4double *vleva_par, G4double *vxeva_par, G4double *vyeva_par,
G4int *ff_par, G4int *fimf_par, G4double *fzimf, G4double *faimf, G4double *tkeimf_par,G4double *jprfout,G4int *inttype_par, G4int *inum_par,G4double EV_TEMP[200][6],G4int *iev_tab_temp_par, G4int *nblam0);
void evapora(G4double zprf, G4double aprf, G4double *ee_par, G4double jprf,
G4double *zf_par, G4double *af_par, G4double *mtota_par,
G4double *vleva_par, G4double *vxeva_par, G4double *vyeva_par,
G4int *ff_par, G4int *fimf_par, G4double *fzimf, G4double *faimf,
G4double *tkeimf_par, G4double *jprfout, G4int *inttype_par,
G4int *inum_par, G4double EV_TEMP[indexpart][6],
G4int *iev_tab_temp_par, G4int *nblam0);
/**
* Calculation of particle emission probabilities.
*/
void direct(G4double zprf, G4double a, G4double ee, G4double jprf, G4double *probp_par, G4double *probd_par, G4double *probt_par, G4double *probn_par, G4double *probhe_par, G4double *proba_par, G4double *probg_par,G4double *probimf_par,G4double *probf_par,G4double *problamb0_par, G4double *ptotl_par, G4double *sn_par, G4double *sbp_par, G4double *sbd_par, G4double *sbt_par, G4double *sbhe_par, G4double *sba_par,G4double *slamb0_par, G4double *ecn_par, G4double *ecp_par, G4double *ecd_par, G4double *ect_par,G4double *eche_par,G4double *eca_par, G4double *ecg_par, G4double *eclamb0_par, G4double *bp_par, G4double *bd_par, G4double *bt_par, G4double *bhe_par, G4double *ba_par,G4double *sp_par,G4double *sd_par,G4double *st_par,G4double *she_par,G4double *sa_par, G4double *ef_par,G4double *ts1_par, G4int, G4int inum, G4int itest, G4int *sortie, G4double *tcn,G4double *jprfn_par, G4double *jprfp_par, G4double *jprfd_par, G4double *jprft_par, G4double *jprfhe_par, G4double *jprfa_par, G4double *jprflamb0_par, G4double *tsum_par, G4int NbLam0);
void direct(G4double zprf, G4double a, G4double ee, G4double jprf,
G4double *probp_par, G4double *probd_par, G4double *probt_par,
G4double *probn_par, G4double *probhe_par, G4double *proba_par,
G4double *probg_par, G4double *probimf_par, G4double *probf_par,
G4double *problamb0_par, G4double *ptotl_par, G4double *sn_par,
G4double *sbp_par, G4double *sbd_par, G4double *sbt_par,
G4double *sbhe_par, G4double *sba_par, G4double *slamb0_par,
G4double *ecn_par, G4double *ecp_par, G4double *ecd_par,
G4double *ect_par, G4double *eche_par, G4double *eca_par,
G4double *ecg_par, G4double *eclamb0_par, G4double *bp_par,
G4double *bd_par, G4double *bt_par, G4double *bhe_par,
G4double *ba_par, G4double *sp_par, G4double *sd_par,
G4double *st_par, G4double *she_par, G4double *sa_par,
G4double *ef_par, G4double *ts1_par, G4int, G4int inum,
G4int itest, G4int *sortie, G4double *tcn, G4double *jprfn_par,
G4double *jprfp_par, G4double *jprfd_par, G4double *jprft_par,
G4double *jprfhe_par, G4double *jprfa_par,
G4double *jprflamb0_par, G4double *tsum_par, G4int NbLam0);
/**
* Calculation of fission and the particle emission probabilities after fission.
* Calculation of fission and the particle emission probabilities after
* fission.
*/
void fission(G4double AF,G4double ZF,G4double EE,G4double JPRF,
G4double *VX1_FISSION,G4double *VY1_FISSION,G4double *VZ1_FISSION,
G4double *VX2_FISSION,G4double *VY2_FISSION,G4double *VZ2_FISSION,
G4int *ZFP1,G4int *AFP1,G4int *SFP1,G4int *ZFP2,G4int *AFP2,G4int *SFP2,G4int *imode,
G4double *VX_EVA_SC, G4double *VY_EVA_SC, G4double *VZ_EVA_SC,
G4double EV_TEMP[200][6],G4int *IEV_TAB_FIS,G4int *NbLam0);
void fission(G4double AF, G4double ZF, G4double EE, G4double JPRF,
G4double *VX1_FISSION, G4double *VY1_FISSION,
G4double *VZ1_FISSION, G4double *VX2_FISSION,
G4double *VY2_FISSION, G4double *VZ2_FISSION, G4int *ZFP1,
G4int *AFP1, G4int *SFP1, G4int *ZFP2, G4int *AFP2, G4int *SFP2,
G4int *imode, G4double *VX_EVA_SC, G4double *VY_EVA_SC,
G4double *VZ_EVA_SC, G4double EV_TEMP[indexpart][6],
G4int *IEV_TAB_FIS, G4int *NbLam0);
/**
* Calculation of lorentz's boost
*/
void lorentz_boost(G4double VXRIN,G4double VYRIN,G4double VZRIN,G4double VXIN,G4double VYIN,G4double VZIN,G4double *VXOUT,G4double *VYOUT,G4double *VZOUT);
void lorentz_boost(G4double VXRIN, G4double VYRIN, G4double VZRIN,
G4double VXIN, G4double VYIN, G4double VZIN,
G4double *VXOUT, G4double *VYOUT, G4double *VZOUT);
/**
* Calculation of unstable nuclei
*/
void unstable_nuclei(G4int AFP,G4int ZFP,G4int *AFPNEW,G4int *ZFPNEW,G4int &IOUNSTABLE,G4double VX,G4double VY,G4double VZ,G4double *VP1X,G4double *VP1Y,G4double *VP1Z,G4double BU_TAB_TEMP[200][6],G4int *ILOOP);
void unstable_nuclei(G4int AFP, G4int ZFP, G4int *AFPNEW, G4int *ZFPNEW,
G4int &IOUNSTABLE, G4double VX, G4double VY, G4double VZ,
G4double *VP1X, G4double *VP1Y, G4double *VP1Z,
G4double BU_TAB_TEMP[indexpart][6], G4int *ILOOP);
/**
* Calculation of unstable nuclei tke
*/
void unstable_tke(G4double AIN,G4double ZIN,G4double ANEW,G4double ZNEW,G4double VXIN,G4double VYIN,G4double VZIN,G4double *V1X,G4double *V1Y,G4double *V1Z,G4double *V2X,G4double *V2Y,G4double *V2Z);
void unstable_tke(G4double AIN, G4double ZIN, G4double ANEW, G4double ZNEW,
G4double VXIN, G4double VYIN, G4double VZIN, G4double *V1X,
G4double *V1Y, G4double *V1Z, G4double *V2X, G4double *V2Y,
G4double *V2Z);
/**
* Calculation of tke for breakup fragments
*/
void tke_bu(G4double Z,G4double A,G4double ZALL,G4double AAL,G4double *VX,G4double *VY,G4double *VZ);
void tke_bu(G4double Z, G4double A, G4double ZALL, G4double AAL, G4double *VX,
G4double *VY, G4double *VZ);
/**
* Calculation of the angular momentum of breakup fragments
* according to Goldhaber model
*/
void AMOMENT(G4double AABRA,G4double APRF,G4int IMULTIFR,G4double *PX,G4double *PY,G4double *PZ);
void AMOMENT(G4double AABRA, G4double APRF, G4int IMULTIFR, G4double *PX,
G4double *PY, G4double *PZ);
/**
* Calculation of particle emission barriers.
*/
void barrs(G4int Z1,G4int A1,G4int Z2,G4int A2,G4double *sBARR,G4double *sOMEGA);
void barrs(G4int Z1, G4int A1, G4int Z2, G4int A2, G4double *sBARR,
G4double *sOMEGA);
/**
* Calculation of particle emission between the saddle and scission point.
*/
void evap_postsaddle(G4double A, G4double Z, G4double E_scission_pre, G4double *E_scission_post, G4double *A_scission, G4double *Z_scission,
G4double &vx_eva,G4double &vy_eva,G4double &vz_eva,G4int *NbLam0_par);
void evap_postsaddle(G4double A, G4double Z, G4double E_scission_pre,
G4double *E_scission_post, G4double *A_scission,
G4double *Z_scission, G4double &vx_eva, G4double &vy_eva,
G4double &vz_eva, G4int *NbLam0_par);
/**
* Calculation of imfs.
*/
void imf(G4double ACN,G4double ZCN,G4double TEMP,G4double EE,G4double *ZIMF,G4double *AIMF,G4double *BIMF,G4double *SBIMF,G4double *TIMF,G4double JPRF);
void imf(G4double ACN, G4double ZCN, G4double TEMP, G4double EE,
G4double *ZIMF, G4double *AIMF, G4double *BIMF, G4double *SBIMF,
G4double *TIMF, G4double JPRF);
/**
* Calculation of omega at saddle point.
*/
void fomega_sp(G4double AF,G4double Y,G4double *MFCD,G4double *sOMEGA,G4double *sHOMEGA);
void fomega_sp(G4double AF, G4double Y, G4double *MFCD, G4double *sOMEGA,
G4double *sHOMEGA);
/**
* Calculation of omega at ground state.
*/
void fomega_gs(G4double AF,G4double ZF,G4double *K1,G4double *sOMEGA,G4double *sHOMEGA);
void fomega_gs(G4double AF, G4double ZF, G4double *K1, G4double *sOMEGA,
G4double *sHOMEGA);
/**
* Calculation of tunnelling effect in fission.
*/
G4double tunnelling(G4double A,G4double ZPRF,G4double Y,G4double EE,G4double EF,G4double TEMP,G4double DENSG,G4double DENSF,G4double ENH_FACT);
G4double tunnelling(G4double A, G4double ZPRF, G4double Y, G4double EE,
G4double EF, G4double TEMP, G4double DENSG,
G4double DENSF, G4double ENH_FACT);
/**
* Calculation of fission width at the saddle point according to B&W.
*/
void fission_width(G4double ZPRF,G4double A,G4double EE,G4double BS,G4double BK,G4double EF,G4double Y,G4double *GF,G4double *TEMP,G4double JPR,G4int IEROT,G4int FF_ALLOWED,G4int OPTCOL,G4int OPTSHP,G4double DENSG);
void fission_width(G4double ZPRF, G4double A, G4double EE, G4double BS,
G4double BK, G4double EF, G4double Y, G4double *GF,
G4double *TEMP, G4double JPR, G4int IEROT,
G4int FF_ALLOWED, G4int OPTCOL, G4int OPTSHP,
G4double DENSG);
/**
* Calculation of unbound nuclei.
*/
void unbound(G4double SN,G4double SP,G4double SD,G4double ST,G4double SHE,G4double SA,G4double BP,G4double BD,G4double BT,G4double BHE,G4double BA,G4double *PROBF,G4double *PROBN,G4double *PROBP,G4double *PROBD,G4double *PROBT,G4double *PROBHE,G4double *PROBA,G4double *PROBIMF,G4double *PROBG,G4double *ECN,G4double *ECP,G4double *ECD,G4double *ECT,G4double *ECHE,G4double *ECA);
void unbound(G4double SN, G4double SP, G4double SD, G4double ST, G4double SHE,
G4double SA, G4double BP, G4double BD, G4double BT, G4double BHE,
G4double BA, G4double *PROBF, G4double *PROBN, G4double *PROBP,
G4double *PROBD, G4double *PROBT, G4double *PROBHE,
G4double *PROBA, G4double *PROBIMF, G4double *PROBG,
G4double *ECN, G4double *ECP, G4double *ECD, G4double *ECT,
G4double *ECHE, G4double *ECA);
/**
* Calculation of the fission distribution.
*/
void fissionDistri(G4double &a,G4double &z,G4double &e,
G4double &a1,G4double &z1,G4double &e1,G4double &v1,
G4double &a2,G4double &z2,G4double &e2,G4double &v2,
G4double &vx_eva_sc,G4double &vy_eva_sc,
G4double &vz_eva_sc,G4int *NbLam0_par);
void fissionDistri(G4double &a, G4double &z, G4double &e, G4double &a1,
G4double &z1, G4double &e1, G4double &v1, G4double &a2,
G4double &z2, G4double &e2, G4double &v2,
G4double &vx_eva_sc, G4double &vy_eva_sc,
G4double &vz_eva_sc, G4int *NbLam0_par);
/**
* Calculation of even-odd effects in fission.
*/
void even_odd(G4double r_origin,G4double r_even_odd,G4int &i_out);
void even_odd(G4double r_origin, G4double r_even_odd, G4int &i_out);
/**
* Functions for the fission model.
*/
G4double umass(G4double z,G4double n,G4double beta);
G4double ecoul(G4double z1,G4double n1,G4double beta1,G4double z2,G4double n2,G4double beta2,G4double d);
G4double Uwash(G4double E, G4double Ecrit,G4double Freduction,G4double gamma);
G4double frldm(G4double z,G4double n,G4double beta);
G4double eflmac_profi(G4double a,G4double z);
G4double umass(G4double z, G4double n, G4double beta);
G4double ecoul(G4double z1, G4double n1, G4double beta1, G4double z2,
G4double n2, G4double beta2, G4double d);
G4double Uwash(G4double E, G4double Ecrit, G4double Freduction,
G4double gamma);
G4double frldm(G4double z, G4double n, G4double beta);
G4double eflmac_profi(G4double a, G4double z);
G4double gausshaz(G4int k, G4double xmoy, G4double sig);
G4double haz(G4int k);
/**
* Level density parameters.
*/
void densniv(G4double a, G4double z, G4double ee, G4double ef, G4double *dens, G4double bshell, G4double bs, G4double bk,
G4double *temp, G4int optshp, G4int optcol, G4double defbet, G4double *ecor, G4double jprf, G4int ifis,G4double *qr);
void densniv(G4double a, G4double z, G4double ee, G4double ef, G4double *dens,
G4double bshell, G4double bs, G4double bk, G4double *temp,
G4int optshp, G4int optcol, G4double defbet, G4double *ecor,
G4double jprf, G4int ifis, G4double *qr);
/**
* Calculation of the fission probability modified by transient time effects.
*/
void part_fiss(G4double BET,G4double GP,G4double GF,G4double Y,G4double TAUF,G4double TS1,G4double TSUM,G4int *CHOICE,G4double ZF,G4double AF,G4double FT,G4double *T_LAPSE,G4double *GF_LOC);
void part_fiss(G4double BET, G4double GP, G4double GF, G4double Y,
G4double TAUF, G4double TS1, G4double TSUM, G4int *CHOICE,
G4double ZF, G4double AF, G4double FT, G4double *T_LAPSE,
G4double *GF_LOC);
G4double func_trans(G4double TIME,G4double ZF,G4double AF,G4double BET,G4double Y,G4double FT,G4double T_0);
G4double func_trans(G4double TIME, G4double ZF, G4double AF, G4double BET,
G4double Y, G4double FT, G4double T_0);
/**
* This subroutine calculates the ordinary legendre polynomials of
* order 0 to n-1 of argument x and stores them in the vector pl.
* They are calculated by recursion relation from the first two
* polynomials.
* Written by A.J.Sierk LANL t-9 February, 1984
* This subroutine calculates the ordinary legendre polynomials of
* order 0 to n-1 of argument x and stores them in the vector pl.
* They are calculated by recursion relation from the first two
* polynomials.
* Written by A.J.Sierk LANL t-9 February, 1984
*/
void lpoly(G4double x, G4int n, G4double pl[]);
/**
* This function will calculate the liquid-drop nuclear mass for spheri
* configuration according to the preprint NUCLEAR GROUND-STATE
* configuration according to the preprint NUCLEAR GROUND-STATE
* MASSES and DEFORMATIONS by P. Mo"ller et al. from August 16, 1993 p.
* All constants are taken from this publication for consistency.
* All constants are taken from this publication for consistency.
*/
G4double eflmac(G4int ia, G4int iz, G4int flag, G4int optshp);
/**
* Procedure for calculating the pairing correction to the binding
* Procedure for calculating the pairing correction to the binding
* energy of a specific nucleus.
*/
void appariem(G4double a, G4double z, G4double *del);
/**
* PROCEDURE FOR CALCULATING THE PARITY OF THE NUMBER N.
* RETURNS -1 IF N IS ODD AND +1 IF N IS EVEN
* PROCEDURE FOR CALCULATING THE PARITY OF THE NUMBER N.
* RETURNS -1 IF N IS ODD AND +1 IF N IS EVEN
*/
void parite(G4double n, G4double *par);
/**
* RISE TIME IN WHICH THE FISSION WIDTH HAS REACHED
* RISE TIME IN WHICH THE FISSION WIDTH HAS REACHED
* 90 PERCENT OF ITS FINAL VALUE
*/
G4double tau(G4double bet, G4double homega, G4double ef, G4double t);
/**
* KRAMERS FAKTOR - REDUCTION OF THE FISSION PROBABILITY
* INDEPENDENT OF EXCITATION ENERGY
* KRAMERS FAKTOR - REDUCTION OF THE FISSION PROBABILITY
* INDEPENDENT OF EXCITATION ENERGY
*/
G4double cram(G4double bet, G4double homega);
/**
* CALCULATION OF THE SURFACE BS OR CURVATURE BK OF A NUCLEUS
* RELATIVE TO THE SPHERICAL CONFIGURATION
* BASED ON MYERS, DROPLET MODEL FOR ARBITRARY SHAPES
* CALCULATION OF THE SURFACE BS OR CURVATURE BK OF A NUCLEUS
* RELATIVE TO THE SPHERICAL CONFIGURATION
* BASED ON MYERS, DROPLET MODEL FOR ARBITRARY SHAPES
*/
G4double bipol(G4int iflag, G4double y);
/**
* THIS SUBROUTINE RETURNS THE BARRIER HEIGHT BFIS, THE
* GROUND-STATE ENERGY SEGS, IN MEV, AND THE ANGULAR MOMENTUM
* AT WHICH THE FISSION BARRIER DISAPPEARS, LMAX, IN UNITS OF
* H-BAR, WHEN CALLED WITH INTEGER AGUMENTS IZ, THE ATOMIC
* NUMBER, IA, THE ATOMIC MASS NUMBER, AND IL, THE ANGULAR
* MOMENTUM IN UNITS OF H-BAR. (PLANCK'S CONSTANT DIVIDED BY
* 2*PI).
* THIS SUBROUTINE RETURNS THE BARRIER HEIGHT BFIS, THE
* GROUND-STATE ENERGY SEGS, IN MEV, AND THE ANGULAR MOMENTUM
* AT WHICH THE FISSION BARRIER DISAPPEARS, LMAX, IN UNITS OF
* H-BAR, WHEN CALLED WITH INTEGER AGUMENTS IZ, THE ATOMIC
* NUMBER, IA, THE ATOMIC MASS NUMBER, AND IL, THE ANGULAR
* MOMENTUM IN UNITS OF H-BAR. (PLANCK'S CONSTANT DIVIDED BY
* 2*PI).
*/
void barfit(G4int iz, G4int ia, G4int il, G4double *sbfis, G4double *segs, G4double *selmax);
void barfit(G4int iz, G4int ia, G4int il, G4double *sbfis, G4double *segs,
G4double *selmax);
/**
* Calculation of decay widths for light particles.
*/
G4double width(G4double AMOTHER,G4double ZMOTHER,G4double APART,G4double ZPART,G4double TEMP,G4double B1,G4double SB1,G4double EXC);
G4double width(G4double AMOTHER, G4double ZMOTHER, G4double APART,
G4double ZPART, G4double TEMP, G4double B1, G4double SB1,
G4double EXC);
/**
* Calculation of penetration factors for light charged particles.
@@ -372,12 +425,13 @@ void unbound(G4double SN,G4double SP,G4double SD,G4double ST,G4double SHE,G4dou
/**
* Calculation of mean value of orbital angular momentum.
*/
void lorb(G4double AMOTHER,G4double ADAUGHTER,G4double LMOTHER,G4double EEFINAL,G4double *LORBITAL,G4double *SIGMA_LORBITAL);
void lorb(G4double AMOTHER, G4double ADAUGHTER, G4double LMOTHER,
G4double EEFINAL, G4double *LORBITAL, G4double *SIGMA_LORBITAL);
/**
* Calculation of BS and BK for the nuclear-level density.
*/
void bsbkbc(G4double A,G4double Z,G4double *BS,G4double *BK,G4double *BC);
void bsbkbc(G4double A, G4double Z, G4double *BS, G4double *BK, G4double *BC);
/**
* Special functions used for the emission of particles.
@@ -386,9 +440,9 @@ void unbound(G4double SN,G4double SP,G4double SD,G4double ST,G4double SHE,G4dou
G4double gammp(G4double a, G4double x);
void gcf(G4double *gammcf,G4double a,G4double x,G4double gln);
void gcf(G4double *gammcf, G4double a, G4double x, G4double gln);
void gser(G4double *gamser,G4double a,G4double x,G4double gln);
void gser(G4double *gamser, G4double a, G4double x, G4double gln);
G4double fvmaxhaz(G4double T);
@@ -401,7 +455,7 @@ void unbound(G4double SN,G4double SP,G4double SD,G4double ST,G4double SHE,G4dou
/**
* LOGARITHM OF THE GAMM FUNCTION
*/
*/
G4double gammln(G4double xx);
/**
@@ -428,12 +482,7 @@ void unbound(G4double SN,G4double SP,G4double SD,G4double ST,G4double SHE,G4dou
* Random generator according to the
powerfunction y = x**(lambda) in the range from xmin to xmax
*/
G4int IPOWERLIMHAZ(G4double lambda,G4int xmin,G4int xmax);
/**
*
*/
G4double pace2(G4double a, G4double z);
G4int IPOWERLIMHAZ(G4double lambda, G4int xmin, G4int xmax);
/**
*
@@ -448,7 +497,7 @@ void unbound(G4double SN,G4double SP,G4double SD,G4double ST,G4double SHE,G4dou
/**
* Fill the data array for INCL
*/
void FillData(G4int IMULTBU,G4int IEV_TAB);
void FillData(G4int IMULTBU, G4int IEV_TAB);
/**
* Separation energies of lambda
@@ -458,9 +507,9 @@ void unbound(G4double SN,G4double SP,G4double SD,G4double ST,G4double SHE,G4dou
/**
* Separation energies of for other particles for hypernuclei
*/
G4double getdeltabinding(G4double a,G4int nblamb);
G4double getdeltabinding(G4double a, G4int nblamb);
G4double gethyperbinding(G4double A, G4double Z, G4int ny);
public:
// Utils
G4int min(G4int a, G4int b);
@@ -478,33 +527,22 @@ public:
G4int idnint(G4double value);
G4double utilabs(G4double a);
G4double dmin1(G4double a, G4double b, G4double c);
G4Ec2sub* getFrldmTable() {
return ec2sub;
}
private:
G4int verboseLevel;
G4int ilast;
G4double T_freeze_out_in;
G4int IEV_TAB_SSC;
G4double BU_TAB[200][12],EV_TAB[200][6],EV_TAB_SSC[200][6];
G4double BU_TAB[indexpart][12], EV_TAB[indexpart][6], EV_TAB_SSC[indexpart][6];
G4int gammaemission;
G4double T_freeze_out;
G4Pace *pace;
G4Ald *ald;
G4Eenuc *eenuc;
G4Ec2sub *ec2sub;
G4Ecld *ecld;
G4Mexp *masses;
G4Fb *fb;
G4Fiss *fiss;
G4Opt *opt;
G4Volant *volant;
std::unique_ptr<G4Ald> ald;
std::unique_ptr<G4Ec2sub> ec2sub;
std::unique_ptr<G4Ecld> ecld;
std::unique_ptr<G4Mexp> masses;
std::unique_ptr<G4Fb> fb;
std::unique_ptr<G4Fiss> fiss;
std::unique_ptr<G4Opt> opt;
G4VarNtp *varntp;
G4int Ainit,Zinit,Sinit;
#ifndef ABLAXX_IN_GEANT4_MODE
G4INCL::Config *theConfig;
#endif
G4int Ainit, Zinit, Sinit;
};
#endif
@@ -24,161 +24,108 @@
// ********************************************************************
//
// ABLAXX statistical de-excitation model
// Jose Luis Rodriguez, GSI (translation from ABLA07 and contact person)
// Jose Luis Rodriguez, UDC (translation from ABLA07 and contact person)
// Pekka Kaitaniemi, HIP (initial translation of ablav3p)
// Aleksandra Kelic, GSI (ABLA07 code)
// Davide Mancusi, CEA (contact person INCL)
// Aatos Heikkinen, HIP (project coordination)
//
#define ABLAXX_IN_GEANT4_MODE 1
#pragma once
#include "globals.hh"
// Data structures needed by ABLA evaporation code.
#ifndef G4AblaDataDefs_hh
#define G4AblaDataDefs_hh 1
#ifdef ABLAXX_IN_GEANT4_MODE
#include "globals.hh"
#else
#include "G4INCLGeant4Compat.hh"
#endif
#include <cmath>
#include <vector>
// ABLA
class G4Nevent {
public:
G4Nevent() {};
~G4Nevent() {};
G4int ii;
};
constexpr const G4int nrows = 180;
constexpr const G4int zcols = 122;
// ABLA
#define PACESIZEROWS 500
#define PACESIZECOLS 500
/**
* Masses.
*/
constexpr const G4int lpcols = 13;
constexpr const G4int lprows = 154;
class G4Pace {
constexpr const G4int nrowsbeta = 251;
constexpr const G4int zcolsbeta = 137;
public:
G4Pace() {};
constexpr const G4int indexpart = 300;
~G4Pace() {};
G4double dm[PACESIZEROWS][PACESIZECOLS];
};
#define MASSIZEROWS 154
#define MASSIZECOLS 13
// Data structures needed by ABLA evaporation code
class G4Mexp {
public:
G4Mexp() {};
G4Mexp(){};
~G4Mexp() {};
G4double massexp[MASSIZEROWS][MASSIZECOLS];
G4double bind[MASSIZEROWS][MASSIZECOLS];
G4int mexpiop[MASSIZEROWS][MASSIZECOLS];
virtual ~G4Mexp() = default;
G4double massexp[lprows][lpcols] = {{0.}};
G4double bind[lprows][lpcols] = {{0.}};
G4int mexpiop[lprows][lpcols] = {{0}};
};
#define EC2SUBROWS 154
#define EC2SUBCOLS 99
/**
*
*/
class G4Ec2sub {
public:
G4Ec2sub() {};
G4Ec2sub(){};
~G4Ec2sub() {};
virtual ~G4Ec2sub() = default;
G4double ecnz[EC2SUBROWS][EC2SUBCOLS];
/**
* Dump the contents of the ecnz data table.
*/
void dump() {
for(G4int i = 0; i < EC2SUBROWS; i++) {
for(G4int j = 0; j < EC2SUBCOLS; j++) {
//G4cout << ecnz[i][j] << " ";
}
// G4cout << G4endl;
}
}
G4double ecnz[nrows][zcols] = {{0.}};
};
class G4Ald {
public:
/**
*
*/
G4Ald()
:av(0.0), as(0.0), ak(0.0), optafan(0.0)
{};
~G4Ald() {};
G4double av,as,ak,optafan;
G4Ald() : av(0.0), as(0.0), ak(0.0), optafan(0.0){};
virtual ~G4Ald() = default;
G4double av, as, ak, optafan = 0.;
};
#define ECLDROWS 154
#define ECLDCOLS 99
#define ECLDROWSbeta 251
#define ECLDCOLSbeta 137
/**
* Shell corrections and deformations.
*/
**/
class G4Ecld {
public:
G4Ecld() {};
~G4Ecld() {};
G4Ecld(){};
virtual ~G4Ecld() = default;
/**
* Ground state shell correction frldm for a spherical ground state.
*/
G4double ecgnz[ECLDROWS][ECLDCOLS];
G4double ecgnz[nrows][zcols] = {{0.}};
/**
* Shell correction for the saddle point (now: == 0).
*/
G4double ecfnz[ECLDROWS][ECLDCOLS];
G4double ecfnz[nrows][zcols] = {{0.}};
/**
* Difference between deformed ground state and ldm value.
*/
G4double vgsld[ECLDROWS][ECLDCOLS];
G4double vgsld[nrows][zcols] = {{0.}};
/**
* Alpha ground state deformation (this is not beta2!)
* beta2 = std::sqrt(5/(4pi)) * alpha
* Alpha ground state deformation (this is not beta2!)
* beta2 = std::sqrt(5/(4pi)) * alpha
*/
G4double alpha[ECLDROWS][ECLDCOLS];
G4double alpha[nrows][zcols] = {{0.}};
/**
* RMS function for lcp emission barriers
*/
G4double rms[ECLDROWS][ECLDCOLS];
G4double rms[nrows][zcols] = {{0.}};
/**
* Beta2 deformations
*/
G4double beta2[ECLDROWSbeta][ECLDCOLSbeta];
G4double beta2[nrowsbeta][zcolsbeta] = {{0.}};
/**
* Beta4 deformations
*/
G4double beta4[ECLDROWSbeta][ECLDCOLSbeta];
G4double beta4[nrowsbeta][zcolsbeta] = {{0.}};
};
class G4Fiss {
@@ -188,29 +135,26 @@ class G4Fiss {
public:
G4Fiss()
:bet(0.0), ifis(0.0), ucr(0.0), dcr(0.0), optshp(0), optxfis(0), optct(0), optcol(0),
at(0), zt(0)
{};
~G4Fiss() {};
G4double bet,ifis,ucr,dcr;
G4int optshp, optxfis,optct,optcol,at,zt;
: bet(0.0), bethyp(0.0), ifis(0.0), ucr(0.0), dcr(0.0), optshp(0), optxfis(0),
optct(0), optcol(0), at(0), zt(0){};
virtual ~G4Fiss() = default;
G4double bet, bethyp, ifis, ucr, dcr;
G4int optshp, optxfis, optct, optcol, at, zt;
};
#define FBROWS 101
#define FBCOLS 161
/**
* Fission barriers.
*/
class G4Fb {
public:
G4Fb() {};
~G4Fb() {;}
// G4double efa[FBROWS][FBCOLS];
G4double efa[FBCOLS][FBROWS];
G4Fb(){};
virtual ~G4Fb() = default;
G4double efa[nrows][zcols] = {{0.}};
};
/**
@@ -220,370 +164,32 @@ public:
class G4Opt {
public:
G4Opt()
:optemd(0), optcha(0), optshpimf(0), optimfallowed(0), nblan0(0)
{};
~G4Opt() {};
G4Opt() : optemd(0), optcha(0), optshpimf(0), optimfallowed(0), nblan0(0){};
G4int optemd,optcha,optshpimf,optimfallowed,nblan0;
virtual ~G4Opt() = default;
G4int optemd, optcha, optshpimf, optimfallowed, nblan0;
};
#define EENUCSIZE 2002
#define XHESIZE 50
class G4Eenuc {
public:
G4Eenuc() {
for(G4int i = 0; i < EENUCSIZE; ++i) {
she[i] = 0.0;
}
for(G4int i = 0; i < XHESIZE; ++i) {
for(G4int j = 0; j < EENUCSIZE; ++j) {
xhe[i][j] = 0.0;
}
}
};
~G4Eenuc() {};
G4double she[EENUCSIZE],xhe[XHESIZE][EENUCSIZE];
};
//#define VOLANTSIZE 200
#define VOLANTSIZE 301
/**
* Evaporation and fission output data.
*/
class G4Volant {
public:
G4Volant()
{
clear();
}
~G4Volant() {};
void clear()
{
for(G4int i = 0; i < VOLANTSIZE; i++) {
copied[i] = false;
acv[i] = 0;
zpcv[i] = 0;
pcv[i] = 0;
xcv[i] = 0;
ycv[i] = 0;
zcv[i] = 0;
iv = 0;
}
}
G4double getTotalMass()
{
G4double total = 0.0;
for(G4int i = 0; i <= iv; i++) {
total += acv[i];
}
return total;
}
void dump()
{
/*
G4double totA = 0.0, totZ = 0.0, totP = 0.0;
// G4cout <<"i \t ACV \t ZPCV \t PCV" << G4endl;
for(G4int i = 0; i <= iv; i++) {
if(i == 0 && acv[i] != 0) {
// G4cout <<"G4Volant: Particle stored at index " << i << G4endl;
}
totA += acv[i];
totZ += zpcv[i];
totP += pcv[i];
// G4cout << "volant" << i << "\t" << acv[i] << " \t " << zpcv[i] << " \t " << pcv[i] << G4endl;
}
// G4cout <<"Particle count index (iv) = " << iv << G4endl;
// G4cout <<"ABLA Total: A = " << totA << " Z = " << totZ << " momentum = " << totP << G4endl;
*/
}
G4double acv[VOLANTSIZE],zpcv[VOLANTSIZE],pcv[VOLANTSIZE],xcv[VOLANTSIZE];
G4double ycv[VOLANTSIZE],zcv[VOLANTSIZE];
G4bool copied[VOLANTSIZE];
G4int iv;
};
#define VARNTPSIZE 301
class G4VarNtp {
public:
G4VarNtp() {
clear();
};
G4VarNtp() { clear(); };
~G4VarNtp() {};
virtual ~G4VarNtp() = default;
/**
* Clear and initialize all variables and arrays.
*/
void clear() {
particleIndex = 0;
projType = 0;
projEnergy = 0.0;
targetA = 0;
targetZ = 0;
masp = 0.0; mzsp = 0.0; exsp = 0.0; mrem = 0.0;
// To be deleted?
spectatorA = 0;
spectatorZ = 0;
spectatorEx = 0.0;
spectatorM = 0.0;
spectatorT = 0.0;
spectatorP1 = 0.0;
spectatorP2 = 0.0;
spectatorP3 = 0.0;
massini = 0;
mzini = 0;
exini = 0;
pcorem = 0;
mcorem = 0;
pxrem = 0;
pyrem = 0;
pzrem = 0;
erecrem = 0;
mulncasc = 0;
mulnevap = 0;
mulntot = 0;
bimpact = 0.0;
jremn = 0;
kfis = 0;
estfis = 0;
izfis = 0;
iafis = 0;
ntrack = 0;
needsFermiBreakup = false;
for(G4int i = 0; i < VARNTPSIZE; i++) {
itypcasc[i] = 0;
avv[i] = 0;
zvv[i] = 0;
svv[i] = 0;
enerj[i] = 0.0;
pxlab[i] = 0.0;
pylab[i] = 0.0;
pzlab[i] = 0.0;
full[i] = false;
}
kfis = 0;
itypcasc.clear();
avv.clear();
zvv.clear();
svv.clear();
enerj.clear();
pxlab.clear();
pylab.clear();
pzlab.clear();
}
/**
* Add a particle to the INCL/ABLA final output.
*/
void addParticle(G4double A, G4double Z, G4double E, G4double P, G4double theta, G4double phi) {
if(full[particleIndex]) {
// G4cout <<"A = " << Z << " Z = " << Z << G4endl;
} else {
avv[particleIndex] = (int) A;
zvv[particleIndex] = (int) Z;
enerj[particleIndex] = E;
plab[particleIndex] = P;
tetlab[particleIndex] = theta;
philab[particleIndex] = phi;
full[particleIndex] = true;
ntrack = particleIndex + 1;
particleIndex++;
}
}
/**
* Baryon number conservation check.
*/
G4int getTotalBaryonNumber() {
G4int baryonNumber = 0;
for(G4int i = 0; i < ntrack; i++) {
if(avv[i] > 0) {
baryonNumber += avv[i];
}
}
return baryonNumber;
}
/**
* Return total energy.
*/
G4double getTotalEnergy() {
G4double energy = 0.0;
for(G4int i = 0; i < ntrack; i++) {
energy += std::sqrt(std::pow(plab[i], 2) + std::pow(getMass(i), 2)); // E^2 = p^2 + m^2
}
return energy;
}
/**
* Return total three momentum.
*/
G4double getTotalThreeMomentum() {
G4double momentum = 0;
for(G4int i = 0; i < ntrack; i++) {
momentum += plab[i];
}
return momentum;
}
G4double getMomentumSum() {
G4double momentum = 0;
for(G4int i = 0; i < ntrack; i++) {
momentum += plab[i];
}
return momentum;
}
G4double getMass(G4int particle) {
const G4double protonMass = 938.272;
const G4double neutronMass = 939.565;
const G4double pionMass = 139.57;
G4double mass = 0.0;
if(avv[particle] == 1 && zvv[particle] == 1) mass = protonMass;
if(avv[particle] == 1 && zvv[particle] == 0) mass = neutronMass;
if(avv[particle] == -1) mass = pionMass;
if(avv[particle] > 1)
mass = avv[particle] * protonMass + zvv[particle] * neutronMass;
return mass;
}
/**
* Dump debugging output.
*/
void dump()
{
/*
G4int nProton = 0, nNeutron = 0;
G4int nPiPlus = 0, nPiZero = 0, nPiMinus = 0;
G4int nH2 = 0, nHe3 = 0, nAlpha = 0;
G4int nGamma=0;
G4int nFragments = 0;
G4int nParticles = 0;
for(G4int i = 0; i < ntrack; i++) {
nParticles++;
if(avv[i] == 1 && zvv[i] == 1) nProton++; // Count multiplicities
if(avv[i] == 1 && zvv[i] == 0) nNeutron++;
if(avv[i] == 0 && zvv[i] == 0) nGamma++;
if(avv[i] == -1 && zvv[i] == 1) nPiPlus++;
if(avv[i] == -1 && zvv[i] == 0) nPiZero++;
if(avv[i] == -1 && zvv[i] == -1) nPiMinus++;
if(avv[i] == 2 && zvv[i] == 1) nH2++;
if(avv[i] == 3 && zvv[i] == 2) nHe3++;
if(avv[i] == 4 && zvv[i] == 2) nAlpha++;
if( zvv[i] > 2) nFragments++;
}
*/
}
/**
* Projectile type.
*/
G4int projType;
/**
* Projectile energy.
*/
G4double projEnergy;
/**
* Target mass number.
*/
G4int targetA;
/**
* Target charge number.
*/
G4int targetZ;
/**
* Projectile spectator A, Z, Eex;
*/
G4double masp, mzsp, exsp, mrem;
/**
* Spectator nucleus mass number for light ion projectile support.
*/
G4int spectatorA;
/**
* Spectator nucleus charge number for light ion projectile support.
*/
G4int spectatorZ;
/**
* Spectator nucleus excitation energy for light ion projectile support.
*/
G4double spectatorEx;
/**
* Spectator nucleus mass.
*/
G4double spectatorM;
/**
* Spectator nucleus kinetic energy.
*/
G4double spectatorT;
/**
* Spectator nucleus momentum x-component.
*/
G4double spectatorP1;
/**
* Spectator nucleus momentum y-component.
*/
G4double spectatorP2;
/**
* Spectator nucleus momentum z-component.
*/
G4double spectatorP3;
/**
* A of the remnant.
*/
G4double massini;
/**
* Z of the remnant.
*/
G4double mzini;
/**
* Excitation energy.
*/
G4double exini;
G4double pcorem, mcorem, pxrem, pyrem, pzrem, erecrem;
/**
* Cascade n multip.
*/
G4int mulncasc;
/**
* Evaporation n multip.
*/
G4int mulnevap;
/**
* Total n multip.
*/
G4int mulntot;
/**
* Impact parameter.
*/
G4double bimpact;
/**
* Remnant Intrinsic Spin.
*/
G4int jremn;
/**
* Fission 1/0=Y/N.
*/
@@ -609,13 +215,6 @@ public:
*/
G4int ntrack;
/**
* The state of the index:
* true = reserved
* false = free
*/
G4bool full[VARNTPSIZE];
/**
* Does this nucleus require Fermi break-up treatment? Only
* applicable when used together with Geant4.
@@ -627,49 +226,44 @@ public:
/**
* emitted in cascade (0) or evaporation (1).
*/
G4int itypcasc[VARNTPSIZE];
std::vector<G4int> itypcasc;
/**
* A (-1 for pions).
*/
G4int avv[VARNTPSIZE];
std::vector<G4int> avv;
/**
* Z
*/
G4int zvv[VARNTPSIZE];
std::vector<G4int> zvv;
/**
* S (-1 for lambda_0).
*/
G4int svv[VARNTPSIZE];
std::vector<G4int> svv;
/**
* Kinetic energy.
*/
G4double enerj[VARNTPSIZE];
std::vector<G4double> enerj;
/**
* Momentum.
*/
G4double plab[VARNTPSIZE];
G4double pxlab[VARNTPSIZE];
G4double pylab[VARNTPSIZE];
G4double pzlab[VARNTPSIZE];
std::vector<G4double> plab;
std::vector<G4double> pxlab;
std::vector<G4double> pylab;
std::vector<G4double> pzlab;
/**
* Theta angle.
*/
G4double tetlab[VARNTPSIZE];
std::vector<G4double> tetlab;
/**
* Phi angle.
*/
G4double philab[VARNTPSIZE];
std::vector<G4double> philab;
private:
G4int particleIndex;
};
#endif
@@ -24,20 +24,17 @@
// ********************************************************************
//
// ABLAXX statistical de-excitation model
// Jose Luis Rodriguez, GSI (translation from ABLA07 and contact person)
// Jose Luis Rodriguez, UDC (translation from ABLA07 and contact person)
// Pekka Kaitaniemi, HIP (initial translation of ablav3p)
// Aleksandra Kelic, GSI (ABLA07 code)
// Davide Mancusi, CEA (contact person INCL)
// Aatos Heikkinen, HIP (project coordination)
//
#define ABLAXX_IN_GEANT4_MODE 1
#include "globals.hh"
#ifndef G4AblaDataFile_hh
#define G4AblaDataFile_hh 1
#pragma once
#include "G4AblaVirtualData.hh"
#include "globals.hh"
/**
* Read ABLA data from files.
@@ -45,23 +42,14 @@
class G4AblaDataFile : public G4AblaVirtualData {
public:
#ifdef ABLAXX_IN_GEANT4_MODE
G4AblaDataFile();
#else
G4AblaDataFile(G4INCL::Config *);
#endif
~G4AblaDataFile();
virtual ~G4AblaDataFile() = default;
/**
* Read all data from files.
*/
bool readData();
G4bool readData();
private:
G4int verboseLevel;
#ifndef ABLAXX_IN_GEANT4_MODE
G4INCL::Config *theConfig;
#endif
};
#endif
@@ -24,63 +24,59 @@
// ********************************************************************
//
// ABLAXX statistical de-excitation model
// Jose Luis Rodriguez, GSI (translation from ABLA07 and contact person)
// Jose Luis Rodriguez, UDC (translation from ABLA07 and contact person)
// Pekka Kaitaniemi, HIP (initial translation of ablav3p)
// Aleksandra Kelic, GSI (ABLA07 code)
// Davide Mancusi, CEA (contact person INCL)
// Aatos Heikkinen, HIP (project coordination)
//
#ifndef G4AblaInterface_hh
#define G4AblaInterface_hh 1
#pragma once
#include "globals.hh"
#include "G4VPreCompoundModel.hh"
#include "G4ReactionProduct.hh"
#include "G4Abla.hh"
#include "G4Fragment.hh"
#include "G4HadFinalState.hh"
#include "G4HadProjectile.hh"
#include "G4Nucleus.hh"
#include "G4Abla.hh"
#include "G4ReactionProduct.hh"
#include "G4VPreCompoundModel.hh"
class G4ExcitationHandler;
class G4HadFinalState;
class G4AblaInterface : public G4VPreCompoundModel
{
public:
G4AblaInterface(G4ExcitationHandler* ptr = nullptr);
class G4AblaInterface : public G4VPreCompoundModel {
public:
G4AblaInterface(G4ExcitationHandler *ptr = nullptr);
virtual ~G4AblaInterface();
virtual G4ReactionProductVector* DeExcite(G4Fragment& aFragment);
virtual G4ReactionProductVector *DeExcite(G4Fragment &aFragment);
virtual G4HadFinalState* ApplyYourself(G4HadProjectile const&, G4Nucleus&) final;
virtual G4HadFinalState *ApplyYourself(G4HadProjectile const &,
G4Nucleus &) final;
virtual void BuildPhysicsTable(const G4ParticleDefinition&) final;
virtual void BuildPhysicsTable(const G4ParticleDefinition &) final;
virtual void InitialiseModel() final;
virtual void ModelDescription(std::ostream& outFile) const;
virtual void ModelDescription(std::ostream &outFile) const;
virtual void DeExciteModelDescription(std::ostream& outFile) const;
virtual void DeExciteModelDescription(std::ostream &outFile) const;
private:
private:
G4HadFinalState applyYourselfResult;
G4VarNtp* ablaResult;
G4Volant* volant;
G4Abla* theABLAModel;
G4VarNtp *ablaResult;
G4Abla *theABLAModel;
G4long eventNumber;
G4int secID; // Creator model ID for the secondaries created by ABLA
G4int secID; // Creator model ID for the secondaries created by ABLA
G4bool isInitialised;
/// \brief Convert an Abla particle to a G4DynamicParticle
G4ReactionProduct* toG4Particle(G4int A, G4int Z, G4int S, G4double kinE,
G4double px, G4double py, G4double pz) const;
G4ReactionProduct *toG4Particle(G4int A, G4int Z, G4int S, G4double kinE,
G4double px, G4double py, G4double pz) const;
/// \brief Convert A, Z and S to a G4ParticleDefinition
G4ParticleDefinition* toG4ParticleDefinition(G4int A, G4int Z, G4int S) const;
G4ParticleDefinition *toG4ParticleDefinition(G4int A, G4int Z, G4int S) const;
};
#endif
@@ -24,21 +24,17 @@
// ********************************************************************
//
// ABLAXX statistical de-excitation model
// Jose Luis Rodriguez, GSI (translation from ABLA07 and contact person)
// Jose Luis Rodriguez, UDC (translation from ABLA07 and contact person)
// Pekka Kaitaniemi, HIP (initial translation of ablav3p)
// Aleksandra Kelic, GSI (ABLA07 code)
// Davide Mancusi, CEA (contact person INCL)
// Aatos Heikkinen, HIP (project coordination)
//
#define ABLAXX_IN_GEANT4_MODE 1
#pragma once
#include "globals.hh"
#ifndef G4ABLARANDOM_HH
#define G4ABLARANDOM_HH
namespace G4AblaRandom {
double flat();
G4double flat();
}
#endif
@@ -24,27 +24,17 @@
// ********************************************************************
//
// ABLAXX statistical de-excitation model
// Jose Luis Rodriguez, GSI (translation from ABLA07 and contact person)
// Jose Luis Rodriguez, UDC (translation from ABLA07 and contact person)
// Pekka Kaitaniemi, HIP (initial translation of ablav3p)
// Aleksandra Kelic, GSI (ABLA07 code)
// Davide Mancusi, CEA (contact person INCL)
// Aatos Heikkinen, HIP (project coordination)
//
#define ABLAXX_IN_GEANT4_MODE 1
#pragma once
#include "globals.hh"
#ifndef G4AblaVirtualData_hh
#define G4AblaVirtualData_hh 1
#ifdef ABLAXX_IN_GEANT4_MODE
#include "globals.hh"
#else
#include "G4INCLGeant4Compat.hh"
#include "G4INCLConfig.hh"
#endif
/**
* An interface to data used by ABLA. This interface allows
* us to abstract the actual source of data. Currently the data is
@@ -54,16 +44,12 @@
class G4AblaVirtualData {
protected:
/**
* Constructor, destructor
*/
#ifdef ABLAXX_IN_GEANT4_MODE
G4AblaVirtualData();
#else
G4AblaVirtualData(G4INCL::Config *);
#endif
virtual ~G4AblaVirtualData();
virtual ~G4AblaVirtualData() = default;
public:
/**
@@ -81,11 +67,6 @@ public:
*/
G4bool setVgsld(G4int A, G4int Z, G4double value);
/**
* Set the value of Pace2.
*/
G4bool setPace2(G4int A, G4int Z, G4double value);
/**
* Set the value of RMS.
*/
@@ -111,7 +92,6 @@ public:
*/
G4bool setBeta4(G4int A, G4int Z, G4double value);
/**
* Get the value of Alpha.
*/
@@ -127,12 +107,7 @@ public:
*/
G4double getVgsld(G4int A, G4int Z);
/**
* Get the value of Pace2.
*/
G4double getPace2(G4int A, G4int Z);
/**
/*
* Get the value of RMS.
*/
G4double getRms(G4int A, G4int Z);
@@ -157,40 +132,21 @@ public:
*/
G4double getBeta4(G4int A, G4int Z);
G4int getAlphaRows();
G4int getAlphaCols();
G4int getPaceRows();
G4int getPaceCols();
virtual G4bool readData() = 0;
private:
static const G4int sRows = 180;
static const G4int sCols = 122;
static const G4int alphaRows = 154;
static const G4int alphaCols = 99;
static const G4int paceRows = 500;
static const G4int paceCols = 500;
static const G4int rmsRows = 154;
static const G4int rmsCols = 99;
static const G4int betaRows = 251;
static const G4int betaRows = sCols + sRows;
static const G4int betaCols = 137;
static const G4int massRows = 154;
static const G4int massCols = 13;
G4double alpha[alphaRows][alphaCols];
G4double ecnz[alphaRows][alphaCols];
G4double vgsld[alphaRows][alphaCols];
G4double pace2[paceRows][paceCols];
G4double rms[rmsRows][rmsCols];
G4double mexp[massRows][massCols];
G4int mexpid[massRows][massCols];
G4double alpha[sRows][sCols];
G4double ecnz[sRows][sCols];
G4double vgsld[sRows][sCols];
G4double rms[sRows][sCols];
G4double mexp[sRows][sCols];
G4int mexpid[sRows][sCols];
G4double beta2[betaRows][betaCols];
G4double beta4[betaRows][betaCols];
};
#endif
@@ -19,7 +19,6 @@ geant4_add_module(G4hadronic_abla
geant4_module_link_libraries(G4hadronic_abla
PUBLIC
G4globman
G4hadronic_inclxx_utils
G4hadronic_mgt
G4hadronic_util
PRIVATE
File diff suppressed because it is too large Load Diff
@@ -24,207 +24,170 @@
// ********************************************************************
//
// ABLAXX statistical de-excitation model
// Jose Luis Rodriguez, GSI (translation from ABLA07 and contact person)
// Jose Luis Rodriguez, UDC (translation from ABLA07 and contact person)
// Pekka Kaitaniemi, HIP (initial translation of ablav3p)
// Aleksandra Kelic, GSI (ABLA07 code)
// Davide Mancusi, CEA (contact person INCL)
// Aatos Heikkinen, HIP (project coordination)
//
#define ABLAXX_IN_GEANT4_MODE 1
#include "globals.hh"
#include "G4AblaDataFile.hh"
#ifdef ABLAXX_IN_GEANT4_MODE
#include "G4AblaDataDefs.hh"
#include "globals.hh"
#else
#include "G4INCLGeant4Compat.hh"
#endif
#include <fstream>
#include <cmath>
#include <iostream>
#include <cstdlib>
#include <fstream>
#include <iostream>
#ifdef ABLAXX_IN_GEANT4_MODE
G4AblaDataFile::G4AblaDataFile() {
#else
G4AblaDataFile::G4AblaDataFile(G4INCL::Config *config)
: G4AblaVirtualData(config) {
theConfig = config;
#endif
verboseLevel = 0;
}
G4AblaDataFile::~G4AblaDataFile()
{
}
G4AblaDataFile::G4AblaDataFile() { verboseLevel = 0; }
/**
* Read all data from files.
*/
bool G4AblaDataFile::readData()
G4bool G4AblaDataFile::readData()
{
#ifdef ABLAXX_IN_GEANT4_MODE
if(!G4FindDataDir("G4ABLADATA")) {
// throw G4HadronicException(__FILE__, __LINE__, "ERROR: Data
// missing. Set environment variable G4ABLA3.0 to point to the
// directory containing data files needed by INCL and ABLA
// models.");
// G4String errorMessage1 = "ERROR: Data missing. Set environment variable G4ABLADATA\n";
// G4String errorMessage2 = "\t to point to the directory containing data files needed\n";
// G4String errorMessage3 = "\t by INCL and ABLA models.\n";
// G4String errorMessage = errorMessage1 + errorMessage2 + errorMessage3;
// G4Exception(errorMessage);
G4ExceptionDescription ed;
ed << " Data missing: set environment variable G4ABLADATA\n"
<< " to point to the directory containing data files needed\n"
<< " by the ABLA model" << G4endl;
G4Exception("G4AblaDataFile::readData()","ABLA_001",
FatalException, ed);
}
G4String dataPath(G4FindDataDir("G4ABLADATA"));
#else
G4String dataPath(theConfig->getABLAXXDataFilePath().c_str());
#endif
G4String flAlphaFile(dataPath + "/flalpha.dat");
G4String frldmFile( dataPath + "/frldm.dat");
G4String vgsldFile( dataPath + "/vgsld.dat");
G4String pace2File( dataPath + "/pace2.dat");
G4String rmsFile( dataPath + "/rms.dat");
G4String defoFile( dataPath + "/defo.dat");
G4String massFile( dataPath + "/mass2003.dat");
if(verboseLevel > 1) {
// G4cout <<"Data path = " << dataPath << G4endl;
// G4cout <<"FlAlphaFile = " << flAlphaFile << G4endl;
// G4cout <<"FrldmFile = " << frldmFile << G4endl;
// G4cout <<"VgsldFile = " << vgsldFile << G4endl;
// G4cout <<"Pace2File = " << pace2File << G4endl;
}
std::ifstream flalphain(flAlphaFile.c_str());
std::ifstream frldmin(frldmFile.c_str());
std::ifstream vgsldin(vgsldFile.c_str());
std::ifstream pace2in(pace2File.c_str());
std::ifstream rmsin(rmsFile.c_str());
std::ifstream defoin(defoFile.c_str());
std::ifstream massin(massFile.c_str());
std::filebuf *buf1 = flalphain.rdbuf();
std::filebuf *buf2 = frldmin.rdbuf();
std::filebuf *buf3 = vgsldin.rdbuf();
std::filebuf *buf4 = pace2in.rdbuf();
std::filebuf *buf5 = rmsin.rdbuf();
std::filebuf *buf6 = defoin.rdbuf();
std::filebuf *buf7 = massin.rdbuf();
if (!((buf1->is_open()) && (buf2->is_open()) && (buf3->is_open()) && (buf4->is_open()) && (buf5->is_open()) && (buf6->is_open()) && (buf7->is_open()))) {
#ifdef ABLAXX_IN_GEANT4_MODE
G4ExceptionDescription ed;
ed << "Data missing: could not find ABLA data file in " << dataPath
<< "defined by environment variable G4ABLADATA" << G4endl;
G4Exception("G4AblaDataFile::readData()", "ABLA", FatalException, ed);
#else
std::cerr << "Error opening file." << std::endl;
#endif
}
G4double fflalpha, ffrldm, fvgsld, fpace2, frms;
int fj,fk,a2,a3,a4;
G4double fbeta2,fbeta4;
G4double a7;
const G4int rows = 99;
const G4int cols = 154;
const G4int rowsbeta = 137;
const G4int colsbeta = 251;
const G4int rowsmass = 13;
const G4int colsmass = 154;
const G4int massnumbers = 263;
for(int i = 0; i < rows; i++) {
for(int j = 0; j < cols; j++) {
setAlpha(j, i, 0.0);
setEcnz( j, i, 0.0);
setVgsld(j, i, 0.0);
setRms(j, i, 0.0);
if (!G4FindDataDir("G4ABLADATA"))
{
G4ExceptionDescription ed;
ed << " Data missing: set environment variable G4ABLADATA\n"
<< " to point to the directory containing data files needed\n"
<< " by the ABLA model" << G4endl;
G4Exception("G4AblaDataFile::readData()", "ABLA_001", FatalException, ed);
}
}
for(int i = 0; i < rows; i++) {
for(int j = 0; j < cols; j++) {
flalphain >> fflalpha;
frldmin >> ffrldm;
vgsldin >> fvgsld;
rmsin >> frms;
setAlpha(j, i, fflalpha);
setEcnz( j, i, ffrldm);
setVgsld(j, i, fvgsld);
setRms(j, i, frms);
G4String dataPath(G4FindDataDir("G4ABLADATA"));
G4String flAlphaFile(dataPath + "/flalpha.dat");
G4String frldmFile(dataPath + "/frldm.dat");
G4String vgsldFile(dataPath + "/vgsld.dat");
G4String rmsFile(dataPath + "/rms.dat");
G4String defoFile(dataPath + "/defo.dat");
G4String massFile(dataPath + "/mass2020.dat");
if (verboseLevel > 1)
{
// G4cout <<"Data path = " << dataPath << G4endl;
// G4cout <<"FlAlphaFile = " << flAlphaFile << G4endl;
// G4cout <<"FrldmFile = " << frldmFile << G4endl;
// G4cout <<"VgsldFile = " << vgsldFile << G4endl;
}
}
std::ifstream flalphain(flAlphaFile.c_str());
std::ifstream frldmin(frldmFile.c_str());
std::ifstream vgsldin(vgsldFile.c_str());
std::ifstream rmsin(rmsFile.c_str());
std::ifstream defoin(defoFile.c_str());
std::ifstream massin(massFile.c_str());
for(int i = 0; i < rowsbeta; i++) {
for(int j = 0; j < colsbeta; j++) {
setBeta2(j, i, 0.0);
setBeta4(j, i, 0.0);
if (!massin.is_open())
{
massFile = dataPath + "/mass2016.dat";
massin.close();
massin.open(massFile.c_str());
std::cout << "Mass evaluation file mass2020.dat not found, current file: " << massFile.c_str() << std::endl;
if (!massin.is_open())
{
massFile = dataPath + "/mass2003.dat";
massin.close();
massin.open(massFile.c_str());
std::cout << "Mass evaluation file mass2016.dat not found, current file: " << massFile.c_str() << std::endl;
}
}
}
for(int i = 0; i < 8983; i++) {
defoin >> fj >> fk >> fbeta2 >> fbeta4;
setBeta2(fk, fj, fbeta2);
setBeta4(fk, fj, fbeta4);
}
for(int i = 0; i < rowsmass; i++) {
for(int j = 0; j < colsmass; j++) {
setMexp(j, i, 0.0);
setMexpID(j,i,0);
std::filebuf* buf1 = flalphain.rdbuf();
std::filebuf* buf2 = frldmin.rdbuf();
std::filebuf* buf3 = vgsldin.rdbuf();
std::filebuf* buf4 = rmsin.rdbuf();
std::filebuf* buf5 = defoin.rdbuf();
std::filebuf* buf6 = massin.rdbuf();
if (!((buf1->is_open()) && (buf2->is_open()) && (buf3->is_open()) && (buf4->is_open()) && (buf5->is_open()) &&
(buf6->is_open())))
{
G4ExceptionDescription ed;
ed << "Data missing: could not find ABLA data file in " << dataPath
<< "defined by environment variable G4ABLADATA" << G4endl;
G4Exception("G4AblaDataFile::readData()", "ABLA", FatalException, ed);
}
}
massin >> a2 >> a3 >> a4 >> a7 ;
while(!massin.eof()){
//
if(a3<13.){
setMexpID(a2,a3,1);
setMexp(a2,a3,938.7829835*a3+939.5653301*a2-1.*a4*a7/1000.);
}
massin >> a2 >> a3 >> a4 >> a7 ;
}
flalphain.close();
frldmin.close();
vgsldin.close();
rmsin.close();
defoin.close();
massin.close();
G4double fflalpha, ffrldm, fvgsld, frms;
G4int fj = 0, fk = 0, a2, a3, a4;
G4double fbeta2, fbeta4;
G4double a7;
const G4int rows = 99;
const G4int cols = 154;
const G4int rowsbeta = 137;
const G4int colsbeta = 251;
G4String str1, str2, str3;
for(int i = 0; i < 500; i++) {
for(int j = 0; j < 500; j++) {
setPace2(i, j, 0.0);
for (G4int i = 0; i < zcols; i++)
{
for (G4int j = 0; j < nrows; j++)
{
setAlpha(j, i, 0.0);
setEcnz(j, i, 0.0);
setVgsld(j, i, 0.0);
setRms(j, i, 0.0);
}
}
}
int A = 0, Zbegin = 0, Zend = 0;
for(int i = 0; i < massnumbers; i++) {
pace2in >> str1 >> A >> str2 >> Zbegin >> str3 >> Zend;
if(Zbegin >= 0 && Zbegin < getPaceCols() &&
A >= 0 && A < getPaceRows()) {
for(int j = Zbegin; j <= Zend; j++) {
pace2in >> fpace2;
setPace2(A, j, fpace2);
}
}
}
pace2in.close();
if(std::abs(getPace2(A, Zend) - 114516.10) > 1e-6) {
std::cerr << "ERROR: Problem in parsing datafile " + pace2File << std::endl;
return false;
}
return true;
for (G4int i = 0; i < rows; i++)
{
for (G4int j = 0; j < cols; j++)
{
flalphain >> fflalpha;
frldmin >> ffrldm;
vgsldin >> fvgsld;
rmsin >> frms;
setAlpha(j, i, fflalpha);
setEcnz(j, i, ffrldm);
setVgsld(j, i, fvgsld);
setRms(j, i, frms);
}
}
for (G4int i = 0; i < rowsbeta; i++)
{
for (G4int j = 0; j < colsbeta; j++)
{
setBeta2(j, i, 0.0);
setBeta4(j, i, 0.0);
}
}
defoin >> fj >> fk >> fbeta2 >> fbeta4;
while (!defoin.eof())
{
setBeta2(fk, fj, fbeta2);
setBeta4(fk, fj, fbeta4);
defoin >> fj >> fk >> fbeta2 >> fbeta4;
}
for (G4int i = 0; i < zcols; i++)
{
for (G4int j = 0; j < nrows; j++)
{
setMexp(j, i, 0.0);
setMexpID(j, i, 0);
}
}
massin >> a2 >> a3 >> a4 >> a7;
while (!massin.eof())
{
//
if (a3 < lpcols)
{
setMexpID(a2, a3, 1);
setMexp(a2, a3, 938.7829835 * a3 + 939.5653301 * a2 - 1. * a4 * a7 / 1000.);
}
massin >> a2 >> a3 >> a4 >> a7;
}
flalphain.close();
frldmin.close();
vgsldin.close();
rmsin.close();
defoin.close();
massin.close();
return true;
}
@@ -24,7 +24,7 @@
// ********************************************************************
//
// ABLAXX statistical de-excitation model
// Jose Luis Rodriguez, GSI (translation from ABLA07 and contact person)
// Jose Luis Rodriguez, UDC (translation from ABLA07 and contact person)
// Pekka Kaitaniemi, HIP (initial translation of ablav3p)
// Aleksandra Kelic, GSI (ABLA07 code)
// Davide Mancusi, CEA (contact person INCL)
@@ -32,239 +32,255 @@
//
#include "globals.hh"
#include <iostream>
#include <cmath>
#include <iostream>
#include "G4AblaInterface.hh"
#include "G4ParticleDefinition.hh"
#include "G4ReactionProductVector.hh"
#include "G4ReactionProduct.hh"
#include "G4DoubleHyperDoubleNeutron.hh"
#include "G4DoubleHyperH4.hh"
#include "G4DynamicParticle.hh"
#include "G4ExcitationHandler.hh"
#include "G4HyperAlpha.hh"
#include "G4HyperH4.hh"
#include "G4HyperHe5.hh"
#include "G4HyperTriton.hh"
#include "G4IonTable.hh"
#include "G4SystemOfUnits.hh"
#include "G4ParticleDefinition.hh"
#include "G4PhysicalConstants.hh"
#include "G4PhysicsModelCatalog.hh"
#include "G4ExcitationHandler.hh"
#include "G4HyperTriton.hh"
#include "G4HyperH4.hh"
#include "G4HyperAlpha.hh"
#include "G4DoubleHyperH4.hh"
#include "G4DoubleHyperDoubleNeutron.hh"
#include "G4HyperHe5.hh"
#include "G4ReactionProduct.hh"
#include "G4ReactionProductVector.hh"
#include "G4SystemOfUnits.hh"
G4AblaInterface::G4AblaInterface(G4ExcitationHandler* ptr) :
G4VPreCompoundModel(ptr, "ABLAXX"),
ablaResult(new G4VarNtp),
volant(new G4Volant),
theABLAModel(new G4Abla(volant, ablaResult)),
eventNumber(0),
secID(-1),
isInitialised(false)
G4AblaInterface::G4AblaInterface(G4ExcitationHandler* ptr)
: G4VPreCompoundModel(ptr, "ABLAXX")
, ablaResult(new G4VarNtp)
, theABLAModel(new G4Abla(ablaResult))
, eventNumber(0)
, secID(-1)
, isInitialised(false)
{
secID = G4PhysicsModelCatalog::GetModelID("model_" + GetModelName());
// G4cout << "### NEW PrecompoundModel " << this << G4endl;
if (!ptr) SetExcitationHandler(new G4ExcitationHandler);
InitialiseModel();
G4cout << G4endl << "G4AblaInterface::InitialiseModel() was right." << G4endl;
secID = G4PhysicsModelCatalog::GetModelID("model_" + GetModelName());
// G4cout << "### NEW PrecompoundModel " << this << G4endl;
if (!ptr)
SetExcitationHandler(new G4ExcitationHandler);
InitialiseModel();
G4cout << G4endl << "G4AblaInterface::InitialiseModel() was right." << G4endl;
}
G4AblaInterface::~G4AblaInterface()
{
applyYourselfResult.Clear();
delete volant;
delete ablaResult;
delete theABLAModel;
delete GetExcitationHandler();
applyYourselfResult.Clear();
delete ablaResult;
delete theABLAModel;
delete GetExcitationHandler();
}
void G4AblaInterface::BuildPhysicsTable(const G4ParticleDefinition&)
{
InitialiseModel();
}
void G4AblaInterface::BuildPhysicsTable(const G4ParticleDefinition&) { InitialiseModel(); }
void G4AblaInterface::InitialiseModel()
{
if (isInitialised) return;
isInitialised = true;
theABLAModel->initEvapora();
theABLAModel->SetParameters();
GetExcitationHandler()->Initialise();
if (isInitialised)
return;
isInitialised = true;
theABLAModel->initEvapora();
theABLAModel->SetParameters();
GetExcitationHandler()->Initialise();
}
G4HadFinalState* G4AblaInterface::ApplyYourself(const G4HadProjectile & thePrimary,
G4Nucleus & theNucleus)
{
// This method is adapted from G4PreCompoundModel::ApplyYourself,
// and it is used only by Binary Cascade (BIC) when the latter is coupled with Abla
// for nuclear de-excitation.
// This method allows BIC+ABLA to be used also for proton and neutron projectile
// with kinetic energies below 45 MeV, by creating a "compound" nucleus made
// by the system "target nucleus + projectile", before calling the DeExcite
// method.
const G4ParticleDefinition* primary = thePrimary.GetDefinition();
if ( primary != G4Neutron::Definition() && primary != G4Proton::Definition() ) {
G4ExceptionDescription ed;
ed << "G4AblaModel is used for ";
if ( primary ) ed << primary->GetParticleName();
G4Exception( "G4AblaInterface::ApplyYourself()", "had040", FatalException, ed, "" );
return nullptr;
}
G4int Zp = 0;
G4int Ap = 1;
if ( primary == G4Proton::Definition() ) Zp = 1;
G4double timePrimary = thePrimary.GetGlobalTime();
G4int A = theNucleus.GetA_asInt();
G4int Z = theNucleus.GetZ_asInt();
G4LorentzVector p = thePrimary.Get4Momentum();
G4double mass = G4NucleiProperties::GetNuclearMass(A, Z);
p += G4LorentzVector( 0.0, 0.0, 0.0, mass );
G4Fragment anInitialState(A + Ap, Z + Zp, p);
anInitialState.SetNumberOfExcitedParticle(1, Zp);
anInitialState.SetNumberOfHoles(1, Zp);
anInitialState.SetCreationTime( thePrimary.GetGlobalTime() );
anInitialState.SetCreatorModelID( secID );
G4ReactionProductVector* deExciteResult = DeExcite( anInitialState );
applyYourselfResult.Clear();
applyYourselfResult.SetStatusChange( stopAndKill );
for ( auto const & prod : *deExciteResult ) {
G4DynamicParticle * aNewDP =
new G4DynamicParticle( prod->GetDefinition(), prod->GetTotalEnergy(), prod->GetMomentum() );
G4HadSecondary aNew = G4HadSecondary( aNewDP );
G4double time = std::max( prod->GetFormationTime(), 0.0 );
aNew.SetTime( timePrimary + time );
aNew.SetCreatorModelID( prod->GetCreatorModelID() );
delete prod;
applyYourselfResult.AddSecondary( aNew );
}
delete deExciteResult;
return &applyYourselfResult;
}
G4ReactionProductVector *G4AblaInterface::DeExcite(G4Fragment& aFragment) {
if (!isInitialised) InitialiseModel();
volant->clear();
ablaResult->clear();
const G4int ARem = aFragment.GetA_asInt();
const G4int ZRem = aFragment.GetZ_asInt();
const G4int SRem = -aFragment.GetNumberOfLambdas(); // Strangeness = - (Number of lambdas)
const G4double eStarRem = aFragment.GetExcitationEnergy() / MeV;
const G4double jRem = aFragment.GetAngularMomentum().mag() / hbar_Planck;
const G4LorentzVector& pRem = aFragment.GetMomentum();
const G4double pxRem = pRem.x() / MeV;
const G4double pyRem = pRem.y() / MeV;
const G4double pzRem = pRem.z() / MeV;
++eventNumber;
theABLAModel->DeexcitationAblaxx(ARem, ZRem, eStarRem, jRem, pxRem, pyRem,
pzRem, (G4int)eventNumber, SRem);
G4ReactionProductVector* result = new G4ReactionProductVector;
for(G4int j = 0; j < ablaResult->ntrack; ++j)
{ // Copy ABLA result to the EventInfo
G4ReactionProduct* product =
toG4Particle(ablaResult->avv[j], ablaResult->zvv[j], ablaResult->svv[j],
ablaResult->enerj[j], ablaResult->pxlab[j],
ablaResult->pylab[j], ablaResult->pzlab[j]);
if(product)
G4HadFinalState* G4AblaInterface::ApplyYourself(const G4HadProjectile& thePrimary, G4Nucleus& theNucleus)
{
// This method is adapted from G4PreCompoundModel::ApplyYourself,
// and it is used only by Binary Cascade (BIC) when the latter is coupled with
// Abla for nuclear de-excitation. This method allows BIC+ABLA to be used also
// for proton and neutron projectile with kinetic energies below 45 MeV, by
// creating a "compound" nucleus made by the system "target nucleus +
// projectile", before calling the DeExcite method.
const G4ParticleDefinition* primary = thePrimary.GetDefinition();
if (primary != G4Neutron::Definition() && primary != G4Proton::Definition())
{
product->SetCreatorModelID(secID);
result->push_back(product);
G4ExceptionDescription ed;
ed << "G4AblaModel is used for ";
if (primary)
ed << primary->GetParticleName();
G4Exception("G4AblaInterface::ApplyYourself()", "had040", FatalException, ed, "");
return nullptr;
}
}
return result;
G4int Zp = 0;
G4int Ap = 1;
if (primary == G4Proton::Definition())
Zp = 1;
G4double timePrimary = thePrimary.GetGlobalTime();
G4int A = theNucleus.GetA_asInt();
G4int Z = theNucleus.GetZ_asInt();
G4LorentzVector p = thePrimary.Get4Momentum();
G4double mass = G4NucleiProperties::GetNuclearMass(A, Z);
p += G4LorentzVector(0.0, 0.0, 0.0, mass);
G4Fragment anInitialState(A + Ap, Z + Zp, p);
anInitialState.SetNumberOfExcitedParticle(1, Zp);
anInitialState.SetNumberOfHoles(1, Zp);
anInitialState.SetCreationTime(thePrimary.GetGlobalTime());
anInitialState.SetCreatorModelID(secID);
G4ReactionProductVector* deExciteResult = DeExcite(anInitialState);
applyYourselfResult.Clear();
applyYourselfResult.SetStatusChange(stopAndKill);
for (auto const& prod : *deExciteResult)
{
G4DynamicParticle* aNewDP =
new G4DynamicParticle(prod->GetDefinition(), prod->GetTotalEnergy(), prod->GetMomentum());
G4HadSecondary aNew = G4HadSecondary(aNewDP);
G4double time = std::max(prod->GetFormationTime(), 0.0);
aNew.SetTime(timePrimary + time);
aNew.SetCreatorModelID(prod->GetCreatorModelID());
delete prod;
applyYourselfResult.AddSecondary(aNew);
}
delete deExciteResult;
return &applyYourselfResult;
}
G4ParticleDefinition *G4AblaInterface::toG4ParticleDefinition(G4int A, G4int Z, G4int S) const {
if (A == 1 && Z == 1 && S == 0 ) return G4Proton::Proton();
else if(A == 1 && Z == 0 && S == 0 ) return G4Neutron::Neutron();
else if(A == 1 && Z == 0 && S == -1) return G4Lambda::Lambda();
else if(A == -1 && Z == 1 && S == 0 ) return G4PionPlus::PionPlus();
else if(A == -1 && Z == -1 && S == 0 ) return G4PionMinus::PionMinus();
else if(A == -1 && Z == 0 && S == 0 ) return G4PionZero::PionZero();
else if(A == 0 && Z == 0 && S == 0 ) return G4Gamma::Gamma();
else if(A == 2 && Z == 1 && S == 0 ) return G4Deuteron::Deuteron();
else if(A == 3 && Z == 1 && S == 0 ) return G4Triton::Triton();
else if(A == 3 && Z == 2 && S == 0 ) return G4He3::He3();
else if(A == 3 && Z == 1 && S == -1) return G4HyperTriton::Definition();
else if(A == 4 && Z == 2 && S == 0 ) return G4Alpha::Alpha();
else if(A == 4 && Z == 1 && S == -1) return G4HyperH4::Definition();
else if(A == 4 && Z == 2 && S == -1) return G4HyperAlpha::Definition();
else if(A == 4 && Z == 1 && S == -2) return G4DoubleHyperH4::Definition();
else if(A == 4 && Z == 0 && S == -2) return G4DoubleHyperDoubleNeutron::Definition();
else if(A == 5 && Z == 2 && S == -1) return G4HyperHe5::Definition();
else if(A > 0 && Z > 0 && A > Z )
{ // Returns ground state ion definition.
auto ionfromtable = G4IonTable::GetIonTable()->GetIon(Z, A, std::abs(S), 0); // S is the number of lambdas
if(ionfromtable)
return ionfromtable;
G4ReactionProductVector* G4AblaInterface::DeExcite(G4Fragment& aFragment)
{
if (!isInitialised)
InitialiseModel();
ablaResult->clear();
const G4int ARem = aFragment.GetA_asInt();
const G4int ZRem = aFragment.GetZ_asInt();
const G4int SRem = -aFragment.GetNumberOfLambdas(); // Strangeness = - (Number of lambdas)
const G4double eStarRem = aFragment.GetExcitationEnergy() / MeV;
const G4double jRem = aFragment.GetAngularMomentum().mag() / hbar_Planck;
const G4LorentzVector& pRem = aFragment.GetMomentum();
const G4double pxRem = pRem.x() / MeV;
const G4double pyRem = pRem.y() / MeV;
const G4double pzRem = pRem.z() / MeV;
++eventNumber;
theABLAModel->DeexcitationAblaxx(ARem, ZRem, eStarRem, jRem, pxRem, pyRem, pzRem, (G4int)eventNumber, SRem);
G4ReactionProductVector* result = new G4ReactionProductVector;
for (G4int j = 0; j < ablaResult->ntrack; ++j)
{ // Copy ABLA result to the EventInfo
G4ReactionProduct* product = toG4Particle(ablaResult->avv[j],
ablaResult->zvv[j],
ablaResult->svv[j],
ablaResult->enerj[j],
ablaResult->pxlab[j],
ablaResult->pylab[j],
ablaResult->pzlab[j]);
if (product)
{
product->SetCreatorModelID(secID);
result->push_back(product);
}
}
return result;
}
G4ParticleDefinition* G4AblaInterface::toG4ParticleDefinition(G4int A, G4int Z, G4int S) const
{
if (A == 1 && Z == 1 && S == 0)
return G4Proton::Proton();
else if (A == 1 && Z == 0 && S == 0)
return G4Neutron::Neutron();
else if (A == 1 && Z == 0 && S == -1)
return G4Lambda::Lambda();
else if (A == -1 && Z == 1 && S == 0)
return G4PionPlus::PionPlus();
else if (A == -1 && Z == -1 && S == 0)
return G4PionMinus::PionMinus();
else if (A == -1 && Z == 0 && S == 0)
return G4PionZero::PionZero();
else if (A == 0 && Z == 0 && S == 0)
return G4Gamma::Gamma();
else if (A == 2 && Z == 1 && S == 0)
return G4Deuteron::Deuteron();
else if (A == 3 && Z == 1 && S == 0)
return G4Triton::Triton();
else if (A == 3 && Z == 2 && S == 0)
return G4He3::He3();
else if (A == 3 && Z == 1 && S == -1)
return G4HyperTriton::Definition();
else if (A == 4 && Z == 2 && S == 0)
return G4Alpha::Alpha();
else if (A == 4 && Z == 1 && S == -1)
return G4HyperH4::Definition();
else if (A == 4 && Z == 2 && S == -1)
return G4HyperAlpha::Definition();
else if (A == 4 && Z == 1 && S == -2)
return G4DoubleHyperH4::Definition();
else if (A == 4 && Z == 0 && S == -2)
return G4DoubleHyperDoubleNeutron::Definition();
else if (A == 5 && Z == 2 && S == -1)
return G4HyperHe5::Definition();
else if (A > 0 && Z > 0 && A > Z)
{ // Returns ground state ion definition.
auto ionfromtable = G4IonTable::GetIonTable()->GetIon(Z, A, std::abs(S), 0); // S is the number of lambdas
if (ionfromtable)
return ionfromtable;
else
{
G4cout << "Can't convert particle with A=" << A << ", Z=" << Z << ", S=" << S
<< " to G4ParticleDefinition, trouble ahead" << G4endl;
return 0;
}
}
else
{
G4cout << "Can't convert particle with A=" << A << ", Z=" << Z << ", S=" << S
<< " to G4ParticleDefinition, trouble ahead" << G4endl;
return 0;
{ // Error, unrecognized particle
G4cout << "Can't convert particle with A=" << A << ", Z=" << Z << ", S=" << S
<< " to G4ParticleDefinition, trouble ahead" << G4endl;
return 0;
}
}
else
{ // Error, unrecognized particle
G4cout << "Can't convert particle with A=" << A << ", Z=" << Z << ", S=" << S
<< " to G4ParticleDefinition, trouble ahead" << G4endl;
return 0;
}
}
G4ReactionProduct* G4AblaInterface::toG4Particle(G4int A, G4int Z, G4int S,
G4double kinE, G4double px,
G4double py, G4double pz) const {
G4ParticleDefinition* def = toG4ParticleDefinition(A, Z, S);
if(def == 0)
{ // Check if we have a valid particle definition
return 0;
}
G4ReactionProduct*
G4AblaInterface::toG4Particle(G4int A, G4int Z, G4int S, G4double kinE, G4double px, G4double py, G4double pz) const
{
G4ParticleDefinition* def = toG4ParticleDefinition(A, Z, S);
if (def == 0)
{ // Check if we have a valid particle definition
return 0;
}
const G4double energy = kinE * MeV;
const G4ThreeVector momentum(px, py, pz);
const G4ThreeVector momentumDirection = momentum.unit();
G4DynamicParticle p(def, momentumDirection, energy);
G4ReactionProduct* r = new G4ReactionProduct(def);
(*r) = p;
return r;
const G4double energy = kinE * MeV;
const G4ThreeVector momentum(px, py, pz);
const G4ThreeVector momentumDirection = momentum.unit();
G4DynamicParticle p(def, momentumDirection, energy);
G4ReactionProduct* r = new G4ReactionProduct(def);
(*r) = p;
return r;
}
void G4AblaInterface::ModelDescription(std::ostream& outFile) const
{
outFile << "ABLA++ does not provide an implementation of the ApplyYourself method!\n\n";
outFile << "ABLA++ does not provide an implementation of the ApplyYourself "
"method!\n\n";
}
void G4AblaInterface::DeExciteModelDescription(std::ostream& outFile) const
{
outFile
<< "ABLA++ is a statistical model for nuclear de-excitation. It simulates\n"
<< "the gamma emission and the evaporation of neutrons, light charged\n"
<< "particles and IMFs, as well as fission where applicable. The code\n"
<< "included in Geant4 is a C++ translation of the original Fortran\n"
<< "code ABLA07. Although the model has been recently extended to\n"
<< "hypernuclei by including the evaporation of lambda particles.\n"
<< "More details about the physics are available in the Geant4\n"
<< "Physics Reference Manual and in the reference articles.\n\n"
<< "References:\n"
<< "(1) A. Kelic, M. V. Ricciardi, and K. H. Schmidt, in Proceedings of "
"Joint\n"
<< "ICTP-IAEA Advanced Workshop on Model Codes for Spallation Reactions,\n"
<< "ICTP Trieste, Italy, 48 February 2008, edited by D. Filges, S. Leray, "
"Y. Yariv,\n"
<< "A. Mengoni, A. Stanculescu, and G. Mank (IAEA INDC(NDS)-530, Vienna, "
"2008), pp. 181221.\n\n"
<< "(2) J.L. Rodriguez-Sanchez, J.-C. David et al., Phys. Rev. C 98, "
"021602 (2018)\n\n";
outFile << "ABLA++ is a statistical model for nuclear de-excitation. It simulates\n"
<< "the gamma emission and the evaporation of neutrons, light charged\n"
<< "particles and IMFs, as well as fission where applicable. The code\n"
<< "included in Geant4 is a C++ translation of the original Fortran\n"
<< "code ABLA07. Although the model has been recently extended to\n"
<< "hypernuclei by including the evaporation of lambda particles.\n"
<< "More details about the physics are available in the Geant4\n"
<< "Physics Reference Manual and in the reference articles.\n\n"
<< "References:\n"
<< "(1) A. Kelic, M. V. Ricciardi, and K. H. Schmidt, in Proceedings of Joint\n"
<< "ICTP-IAEA Advanced Workshop on Model Codes for Spallation Reactions,\n"
<< "ICTP Trieste, Italy, 48 February 2008, edited by D. Filges, S. "
"Leray, Y. Yariv, A. Mengoni, A. Stanculescu, and G. Mank (IAEA "
"INDC(NDS)-530, Vienna, 2008), pp. 181221.\n\n"
<< "(2) J.L. Rodriguez-Sanchez, J.-C. David et al., Phys. Rev. C 98, 021602R (2018)\n"
<< "(3) J.L. Rodriguez-Sanchez et al., Phys. Rev. C 105, 014623 (2022)\n"
<< "(4) J.L. Rodriguez-Sanchez et al., Phys. Rev. Lett. 130, 132501 (2023)\n\n";
}
@@ -24,33 +24,19 @@
// ********************************************************************
//
// ABLAXX statistical de-excitation model
// Jose Luis Rodriguez, GSI (translation from ABLA07 and contact person)
// Jose Luis Rodriguez, UDC (translation from ABLA07 and contact person)
// Pekka Kaitaniemi, HIP (initial translation of ablav3p)
// Aleksandra Kelic, GSI (ABLA07 code)
// Davide Mancusi, CEA (contact person INCL)
// Aatos Heikkinen, HIP (project coordination)
//
#define ABLAXX_IN_GEANT4_MODE 1
#include "globals.hh"
#include "G4AblaRandom.hh"
#ifdef ABLAXX_IN_GEANT4_MODE
#include "globals.hh"
#include "Randomize.hh"
#else
#include "G4INCLRandom.hh"
#endif // ABLAXX_IN_GEANT4_MODE
#include "globals.hh"
namespace G4AblaRandom {
double flat() {
#ifdef ABLAXX_IN_GEANT4_MODE
return G4UniformRand();
#else
return G4INCL::Random::shoot();
#endif
}
}
namespace G4AblaRandom
{
G4double flat() { return G4UniformRand(); }
} // namespace G4AblaRandom
@@ -24,149 +24,86 @@
// ********************************************************************
//
// ABLAXX statistical de-excitation model
// Jose Luis Rodriguez, GSI (translation from ABLA07 and contact person)
// Jose Luis Rodriguez, UDC (translation from ABLA07 and contact person)
// Pekka Kaitaniemi, HIP (initial translation of ablav3p)
// Aleksandra Kelic, GSI (ABLA07 code)
// Davide Mancusi, CEA (contact person INCL)
// Aatos Heikkinen, HIP (project coordination)
//
#define ABLAXX_IN_GEANT4_MODE 1
#include "G4AblaVirtualData.hh"
#include "globals.hh"
#include "G4AblaVirtualData.hh"
#ifdef ABLAXX_IN_GEANT4_MODE
G4AblaVirtualData::G4AblaVirtualData() {}
#else
G4AblaVirtualData::G4AblaVirtualData(G4INCL::Config *) {}
#endif
G4AblaVirtualData::~G4AblaVirtualData() {}
bool G4AblaVirtualData::setAlpha(int A, int Z, double value)
G4bool G4AblaVirtualData::setAlpha(G4int A, G4int Z, G4double value)
{
alpha[A][Z] = value;
alpha[A][Z] = value;
return true;
return true;
}
bool G4AblaVirtualData::setEcnz(int A, int Z, double value)
G4bool G4AblaVirtualData::setEcnz(G4int A, G4int Z, G4double value)
{
ecnz[A][Z] = value;
ecnz[A][Z] = value;
return true;
return true;
}
bool G4AblaVirtualData::setVgsld(int A, int Z, double value)
G4bool G4AblaVirtualData::setVgsld(G4int A, G4int Z, G4double value)
{
vgsld[A][Z] = value;
vgsld[A][Z] = value;
return true;
return true;
}
bool G4AblaVirtualData::setPace2(int A, int Z, double value)
G4bool G4AblaVirtualData::setRms(G4int A, G4int Z, G4double value)
{
pace2[A][Z] = value;
rms[A][Z] = value;
return true;
return true;
}
bool G4AblaVirtualData::setRms(int A, int Z, double value)
G4bool G4AblaVirtualData::setMexp(G4int A, G4int Z, G4double value)
{
rms[A][Z] = value;
mexp[A][Z] = value;
return true;
return true;
}
bool G4AblaVirtualData::setMexp(int A, int Z, double value)
G4bool G4AblaVirtualData::setMexpID(G4int A, G4int Z, G4int value)
{
mexp[A][Z] = value;
mexpid[A][Z] = value;
return true;
return true;
}
bool G4AblaVirtualData::setMexpID(int A, int Z, int value)
G4bool G4AblaVirtualData::setBeta2(G4int A, G4int Z, G4double value)
{
mexpid[A][Z] = value;
beta2[A][Z] = value;
return true;
return true;
}
bool G4AblaVirtualData::setBeta2(int A, int Z, double value)
G4bool G4AblaVirtualData::setBeta4(G4int A, G4int Z, G4double value)
{
beta2[A][Z] = value;
beta4[A][Z] = value;
return true;
return true;
}
bool G4AblaVirtualData::setBeta4(int A, int Z, double value)
{
beta4[A][Z] = value;
G4double G4AblaVirtualData::getAlpha(G4int A, G4int Z) { return alpha[A][Z]; }
return true;
}
G4double G4AblaVirtualData::getEcnz(G4int A, G4int Z) { return ecnz[A][Z]; }
G4double G4AblaVirtualData::getVgsld(G4int A, G4int Z) { return vgsld[A][Z]; }
double G4AblaVirtualData::getAlpha(int A, int Z)
{
return alpha[A][Z];
}
G4double G4AblaVirtualData::getRms(G4int A, G4int Z) { return rms[A][Z]; }
double G4AblaVirtualData::getEcnz(int A, int Z)
{
return ecnz[A][Z];
}
G4double G4AblaVirtualData::getMexp(G4int A, G4int Z) { return mexp[A][Z]; }
double G4AblaVirtualData::getVgsld(int A, int Z)
{
return vgsld[A][Z];
}
G4int G4AblaVirtualData::getMexpID(G4int A, G4int Z) { return mexpid[A][Z]; }
double G4AblaVirtualData::getPace2(int A, int Z)
{
return pace2[A][Z];
}
G4double G4AblaVirtualData::getBeta2(G4int A, G4int Z) { return beta2[A][Z]; }
double G4AblaVirtualData::getRms(int A, int Z)
{
return rms[A][Z];
}
double G4AblaVirtualData::getMexp(int A, int Z)
{
return mexp[A][Z];
}
int G4AblaVirtualData::getMexpID(int A, int Z)
{
return mexpid[A][Z];
}
double G4AblaVirtualData::getBeta2(int A, int Z)
{
return beta2[A][Z];
}
double G4AblaVirtualData::getBeta4(int A, int Z)
{
return beta4[A][Z];
}
int G4AblaVirtualData::getAlphaRows()
{
return alphaRows;
}
int G4AblaVirtualData::getAlphaCols()
{
return alphaCols;
}
int G4AblaVirtualData::getPaceRows()
{
return paceRows;
}
int G4AblaVirtualData::getPaceCols()
{
return paceCols;
}
G4double G4AblaVirtualData::getBeta4(G4int A, G4int Z) { return beta4[A][Z]; }
@@ -6,7 +6,7 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2024-05-22 Gunter Folger (had-binary-V11-01-01)
## 2024-05-22 Gunter Folger (had-binary-V11-02-00)
- Address problem reported by Atlas of throwing execption if momentum cannot
be corrected. Problem ocurrs for D + H around 1600 MeV
- The exception is removed,in this rare case the initial state is kept
@@ -5,6 +5,33 @@ 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!
-------------------------------------------------------------------------------
## 2024-01-29 Dennis Wright (hadr-casc-V11-02-02)
- G4CascadeFinalStateAlgorithm::GenerateCosTheta()
For 4-body and higher-body generation of cosTheta, use direct sampling
of exp(1 - cosTheta) instead of previously used rejection method on
sinTheta * exp(-sinTheta). This removes the reflection about cosTheta = 0
that caused a symmetric double bump in the Feynman-x distribution.
## 2024-01-24 Dennis Wright (hadr-casc-V11-02-01)
- G4InuclSpecialFunctions::inuclRndm() is just a wrapper of G4UniformRand()
remove method from class G4InuclSpecialFunctions and replace all
occurrences of inuclRndm() with G4UniformRand() in files
G4BigBanger.cc
G4CascadeFinalStateAlgorithm.cc
G4EquilibriumEvaporator.cc
G4Fissioner.cc
G4IntraNucleiCascader.cc
G4InuclParamAngDst.cc
G4InuclSpecialFunctions.cc
G4NonEquilibriumEvaporator.cc
G4NucleiModel.cc
## 2023-12-11 Dennis Wright (hadr-casc-V11-02-00)
- improved calculation of di-nucleon density using Levinger quasi-deuteron
model proposed by Einar Elen (Lund) and Natalia Toro (SLAC) :
- add method G4NucleiModel::setDinucleonDensityScale() to calculate
correction factor to be applied to dinucleon densities
- modify method G4NucleiModel::getCurrentDensity() to apply this factor
## 2023-11-17 Vladimir Ivantchenko (hadr-casc-V11-01-03)
- G4CascadeParamMessenger - fixed memory leak at exit and simplified the code.
@@ -66,8 +66,6 @@ namespace G4InuclSpecialFunctions {
G4double G4cbrt(G4double x); // Can't use "cbrt" name, clashes with <math.h>
G4double G4cbrt(G4int n); // Use G4Pow::powN() here for speedup
G4double inuclRndm(); // Wrapper for G4UniformRand()
G4double randomInuclPowers(G4double ekin, // Power series in Ekin, S
const G4double (&coeff)[4][4]);
@@ -241,6 +241,9 @@ protected:
G4double generateInteractionLength(const G4CascadParticle& cparticle,
G4double path, G4double invmfp) const;
// Set scaling factor for effective number of di-nucleons in nucleus
void setDinucleonDensityScale();
private:
G4int verboseLevel;
@@ -289,6 +292,11 @@ private:
G4int current_nucl1;
G4int current_nucl2;
G4double dinucleonDensityScale;
// Ratio of naive to effective number of di-nucleons as predicted in
// local density approximation
// O. Benhar et al., arXiv:nucl-th/0301091v1. (2003)
G4CascadeInterpolator<30> gammaQDinterp; // quasideuteron interpolator
// Symbolic names for nuclear potentials
@@ -58,6 +58,7 @@
#include "G4InuclSpecialFunctions.hh"
#include "G4ParticleLargerEkin.hh"
#include "G4Pow.hh"
#include "Randomize.hh"
using namespace G4InuclSpecialFunctions;
@@ -327,12 +328,12 @@ G4double G4BigBanger::generateX(G4int a, G4double promax) const {
G4int itry = 0;
G4double x;
while(itry < itry_max) { /* Loop checking 08.06.2015 MHK */
while(itry < itry_max) { /* Loop checking 08.06.2015 MHK */
itry++;
x = inuclRndm();
x = G4UniformRand();
if(xProbability(x, a) >= promax*G4UniformRand() ) return x;
}
if(xProbability(x, a) >= promax * inuclRndm()) return x;
};
if (verboseLevel > 2) {
G4cout << " BigBanger -> can not generate x " << G4endl;
}
@@ -45,7 +45,6 @@
#include "G4CascadeFinalStateAlgorithm.hh"
#include "G4CascadeParameters.hh"
#include "G4Exp.hh"
#include "G4InuclElementaryParticle.hh"
#include "G4InuclSpecialFunctions.hh"
#include "G4LorentzConvertor.hh"
@@ -413,7 +412,7 @@ G4double G4CascadeFinalStateAlgorithm::
GenerateCosTheta(G4int ptype, G4double pmod) const {
if (GetVerboseLevel() > 2) {
G4cout << " >>> " << GetName() << "::GenerateCosTheta " << ptype
<< " " << pmod << G4endl;
<< " " << pmod << G4endl;
}
if (multiplicity == 3) { // Use distribution for three-body
@@ -421,39 +420,14 @@ GenerateCosTheta(G4int ptype, G4double pmod) const {
}
// Throw multi-body distribution
G4double p0 = ptype<3 ? 0.36 : 0.25; // Nucleon vs. everything else
G4double alf = 1.0 / p0 / (p0 - (pmod+p0)*G4Exp(-pmod / p0));
G4double sinth = 2.0;
G4int itry1 = -1; /* Loop checking 08.06.2015 MHK */
while (std::fabs(sinth) > maxCosTheta && ++itry1 < itry_max) {
G4double s1 = pmod * inuclRndm();
G4double s2 = alf * oneOverE * p0 * inuclRndm();
G4double salf = s1 * alf * G4Exp(-s1 / p0);
if (GetVerboseLevel() > 3) {
G4cout << " s1 * alf * G4Exp(-s1 / p0) " << salf
<< " s2 " << s2 << G4endl;
}
if (salf > s2) sinth = s1 / pmod;
}
if (GetVerboseLevel() > 3)
G4cout << " itry1 " << itry1 << " sinth " << sinth << G4endl;
if (itry1 == itry_max) {
if (GetVerboseLevel() > 2)
G4cout << " high energy angles generation: itry1 " << itry1 << G4endl;
sinth = 0.5 * inuclRndm();
}
// Convert generated sin(theta) to cos(theta) with random sign
G4double costh = std::sqrt(1.0 - sinth * sinth);
if (inuclRndm() > 0.5) costh = -costh;
return costh;
// Sample costheta directly from exp(-a*pmod*(1 - costheta) )
// Previous method sampled from a*sintheta*exp(-a*sintheta),
// converted to costheta and (incorrectly) reflected around 180 degrees
//
G4double p0 = ptype < 3 ? 0.36 : 0.25; // 0.36 for nucleon, 0.25 for all others
G4double alf = 3.*pmod/p0;
return G4Log(G4UniformRand()*(G4Exp(2.*alf) - 1.) + 1.)/alf - 1.;
}
@@ -400,13 +400,13 @@ void G4EquilibriumEvaporator::deExcite(const G4Fragment& target,
G4cout << " T04 " << T04 << " FMAX (EEXS^4) " << FMAX << G4endl;
G4double S(0), X1(0);
while (itry < itry_max) {
itry++;
S = EEXS * inuclRndm();
X1 = (S*S*S*S) * G4Exp((EEXS - S) / T00);
while (itry < itry_max) {
itry++;
S = EEXS*G4UniformRand();
X1 = (S*S*S*S) * G4Exp((EEXS - S) / T00);
if (X1 > FMAX * inuclRndm()) break;
};
if (X1 > FMAX*G4UniformRand() ) break;
}
if (itry == itry_max) { // Maximum attempts exceeded
try_again = false;
@@ -448,7 +448,8 @@ void G4EquilibriumEvaporator::deExcite(const G4Fragment& target,
} // while (EEXS > cut_off
try_again = false;
} else { // if (prob_sum < prob_cut_off)
G4double SL = prob_sum * inuclRndm();
G4double SL = prob_sum*G4UniformRand();
if (verboseLevel > 3) G4cout << " random SL " << SL << G4endl;
G4double S1 = 0.0;
@@ -58,6 +58,7 @@
#include "G4FissionStore.hh"
#include "G4FissionConfiguration.hh"
#include "G4InuclSpecialFunctions.hh"
#include "Randomize.hh"
using namespace G4InuclSpecialFunctions;
@@ -148,7 +149,7 @@ void G4Fissioner::deExcite(const G4Fragment& target,
if (store_size == 0) return; // No fission products
G4FissionConfiguration config =
fissionStore.generateConfiguration(ALMA, inuclRndm());
fissionStore.generateConfiguration(ALMA, G4UniformRand() );
A1 = G4int(config.afirst);
A2 = A - A1;
@@ -346,8 +346,8 @@ void G4IntraNucleiCascader::setupCascade() {
theExitonConfiguration.incrementQP(knd);
};
G4int ihn = G4int(2 * (ab-zb) * inuclRndm() + 0.5);
G4int ihz = G4int(2 * zb * inuclRndm() + 0.5);
G4int ihn = G4int(2 * (ab-zb)*G4UniformRand() + 0.5);
G4int ihz = G4int(2.*zb*G4UniformRand() + 0.5);
for (i = 0; i < ihn; i++) theExitonConfiguration.incrementHoles(2);
for (i = 0; i < ihz; i++) theExitonConfiguration.incrementHoles(1);
@@ -35,6 +35,8 @@
#include "G4InuclParamAngDst.hh"
#include "G4InuclSpecialFunctions.hh"
#include "G4InuclParticleNames.hh"
#include "Randomize.hh"
using namespace G4InuclSpecialFunctions;
using namespace G4InuclParticleNames;
@@ -67,7 +69,7 @@ G4double G4InuclParamAngDst::GetCosTheta(G4int ptype, G4double ekin) const {
<< G4endl;
}
Spow = inuclRndm();
Spow = G4UniformRand();
}
return 2.0*Spow - 1.0; // Convert generated [0..1] to [-1..1]
@@ -121,15 +121,12 @@ G4double G4InuclSpecialFunctions::G4cbrt(G4int n) {
return n==0 ? 0. : (n<0?-1.:1.)*G4Pow::GetInstance()->Z13(std::abs(n));
}
G4double G4InuclSpecialFunctions::inuclRndm() {
return G4UniformRand();
}
G4double G4InuclSpecialFunctions::randomGauss(G4double sigma) {
const G4double eps = 1.0e-6;
G4double r1 = inuclRndm();
G4double r1 = G4UniformRand();
r1 = r1 > eps ? r1 : eps;
G4double r2 = inuclRndm();
G4double r2 = G4UniformRand();
r2 = r2 > eps ? r2 : eps;
r2 = r2 < 1.0 - eps ? r2 : 1.0 - eps;
@@ -137,11 +134,11 @@ G4double G4InuclSpecialFunctions::randomGauss(G4double sigma) {
}
G4double G4InuclSpecialFunctions::randomPHI() {
return twopi * inuclRndm();
return twopi*G4UniformRand();
}
std::pair<G4double, G4double> G4InuclSpecialFunctions::randomCOS_SIN() {
G4double CT = 1.0 - 2.0 * inuclRndm();
G4double CT = 1.0 - 2.0*G4UniformRand();
return std::pair<G4double, G4double>(CT, std::sqrt(1.0 - CT*CT));
}
@@ -61,6 +61,7 @@
#include "G4InuclSpecialFunctions.hh"
#include "G4LorentzConvertor.hh"
#include "G4Pow.hh"
#include "Randomize.hh"
using namespace G4InuclSpecialFunctions;
@@ -222,25 +223,25 @@ void G4NonEquilibriumEvaporator::deExcite(const G4Fragment& target,
try_again = NEX > 1 && (D[1] > width_cut * D[0] ||
D[2] > width_cut * D[0]);
if (try_again) {
G4double D5 = D[0] + D[1] + D[2];
G4double SL = D5 * inuclRndm();
G4double S1 = 0.;
if (try_again) {
G4double D5 = D[0] + D[1] + D[2];
G4double SL = D5*G4UniformRand();
G4double S1 = 0.;
if (verboseLevel > 3)
G4cout << " D5 " << D5 << " SL " << SL << G4endl;
if (verboseLevel > 3)
G4cout << " D5 " << D5 << " SL " << SL << G4endl;
for (G4int i = 0; i < 3; i++) {
S1 += D[i];
if (SL <= S1) {
icase = i;
break;
}
}
for (G4int i = 0; i < 3; i++) {
S1 += D[i];
if (SL <= S1) {
icase = i;
break;
}
}
if (verboseLevel > 3)
G4cout << " got icase " << icase << G4endl;
} // if (try_again)
if (verboseLevel > 3)
G4cout << " got icase " << icase << G4endl;
} // if (try_again)
} // if (NEX >= 2)
} else try_again = false; // if (D[0] > 0)
} else try_again = false; // if (F1>0 && F2>0)
@@ -304,16 +305,16 @@ void G4NonEquilibriumEvaporator::deExcite(const G4Fragment& target,
itry1++;
G4int itry = 0;
/* Loop checking 08.06.2015 MHK */
while (EEXS_new < 0.0 && itry < itry_max) {
itry++;
G4double R = inuclRndm();
G4double X;
/* Loop checking 08.06.2015 MHK */
while (EEXS_new < 0.0 && itry < itry_max) {
itry++;
G4double R = G4UniformRand();
G4double X;
if (NEX == 2) {
X = 1.0 - std::sqrt(R);
if (NEX == 2) {
X = 1.0 - std::sqrt(R);
} else {
} else {
G4double QEX2 = 1.0 / QEX;
G4double QEX1 = 1.0 / (QEX-1);
X = theG4Pow->powA(0.5*R, QEX2);
@@ -441,18 +442,18 @@ void G4NonEquilibriumEvaporator::deExcite(const G4Fragment& target,
QH++;
AR--;
if (AR > 1) {
G4double SL = PW * inuclRndm();
if (AR > 1) {
G4double SL = PW*G4UniformRand();
if (SL > PP) {
QNP++;
QNH++;
} else {
QPP++;
QPH++;
ZR--;
if (ZR < 2) try_again = false;
}
if (SL > PP) {
QNP++;
QNH++;
} else {
QPP++;
QPH++;
ZR--;
if (ZR < 2) try_again = false;
}
} else try_again = false;
} // if (icase==0 && try_again)
} // if (try_again)
@@ -179,6 +179,7 @@
#include "G4Neutron.hh"
#include "G4ParticleDefinition.hh"
#include "G4ParticleLargerBeta.hh"
#include "G4Pow.hh"
#include "G4PhysicalConstants.hh"
#include "G4Proton.hh"
#include "G4SystemOfUnits.hh"
@@ -378,6 +379,8 @@ void G4NucleiModel::generateModel(G4int a, G4int z) {
zone_potentials.push_back(kp);
zone_potentials.push_back(hp);
setDinucleonDensityScale();
nuclei_radius = zone_radii.back();
nuclei_volume = std::accumulate(zone_volumes.begin(),zone_volumes.end(),0.);
@@ -646,7 +649,7 @@ G4double G4NucleiModel::getFermiKinetic(G4int ip, G4int izone) const {
G4LorentzVector
G4NucleiModel::generateNucleonMomentum(G4int type, G4int zone) const {
G4double pmod = getFermiMomentum(type, zone) * G4cbrt(inuclRndm());
G4double pmod = getFermiMomentum(type, zone) * G4cbrt(G4UniformRand() );
G4double mass = G4InuclElementaryParticle::getParticleMass(type);
return generateWithRandomAngles(pmod, mass);
@@ -830,7 +833,7 @@ G4NucleiModel::generateInteractionPartners(G4CascadParticle& cparticle) {
G4double apath = generateInteractionLength(cparticle, path, tot_invmfp);
if (path<small || apath < path) { // choose the qdeutron
G4double sl = inuclRndm() * tot_invmfp;
G4double sl = G4UniformRand()*tot_invmfp;
G4double as = 0.0;
for (std::size_t i = 0; i < qdeutrons.size(); i++) {
@@ -1394,9 +1397,49 @@ G4double G4NucleiModel::getRatio(G4int ip) const {
return 0.;
}
void G4NucleiModel::setDinucleonDensityScale() {
if (A < 5) {
dinucleonDensityScale = 1.0;
// No scaling for light nuclei
return;
}
// At what A should LDA start to be applied?
// Not satisfactory for medium nuclei according to Benhar et al., and a
// sizable experimental uncertainty
// Levinger factor
const G4double Levinger_LDA {10.83 - 9.73/G4Pow::GetInstance()->A13(A)};
// Effective number of quasi-deuterons in a nucleus according to
// local density approximation
const G4double num_LDA_QDs {(Levinger_LDA*Z*(A-Z))/A};
// Number of quasi-deuterons expected from proton and neutron nuclear
// shell densities alone
G4double num_Naive_QDs{0.};
for (G4int zone = 0; zone < number_of_zones; ++zone) {
num_Naive_QDs += getVolume(zone)*getDensity(proton, zone)*
getVolume(zone)*getDensity(neutron, zone);
}
// Density scaling factor determined for quasi-deuterons to be used
// for pp, nn, pn
dinucleonDensityScale = num_LDA_QDs/num_Naive_QDs;
if (verboseLevel > 4) {
G4cout << " >>> G4NucleiModel::setDinucleonDensityScale()" << G4endl;
G4cout << " >>> Naive number of quasi-deuterons in nucleus ("
<< Z << ", " << A << ") = " << num_Naive_QDs << G4endl;
G4cout << " >>> Number of quasi-deuterons expected from Levinger LDA is "
<< num_LDA_QDs << G4endl;
G4cout << "Rescaling dinucleon densities by " << dinucleonDensityScale << G4endl;
}
}
G4double G4NucleiModel::getCurrentDensity(G4int ip, G4int izone) const {
const G4double pn_spec = 1.0; // Scale factor for pn vs. pp/nn
//const G4double pn_spec = 0.5;
// const G4double pn_spec = 1.0; // Scale factor for pn vs. pp/nn
const G4double combinatoric_factor = 0.5;
G4double dens = 0.;
@@ -1404,13 +1447,16 @@ G4double G4NucleiModel::getCurrentDensity(G4int ip, G4int izone) const {
else { // For dibaryons, remove extra 1/volume term in density product
switch (ip) {
case diproton:
dens = getDensity(proton,izone) * getDensity(proton,izone);
dens = getDensity(proton,izone) * getDensity(proton,izone)
* dinucleonDensityScale * combinatoric_factor;
break;
case unboundPN:
dens = getDensity(proton,izone) * getDensity(neutron,izone) * pn_spec;
dens = getDensity(proton,izone) * getDensity(neutron,izone)
* dinucleonDensityScale;
break;
case dineutron:
dens = getDensity(neutron,izone) * getDensity(neutron,izone);
dens = getDensity(neutron,izone) * getDensity(neutron,izone)
* dinucleonDensityScale * combinatoric_factor;
break;
default: dens = 0.;
}
@@ -1430,7 +1476,7 @@ G4NucleiModel::initializeCascad(G4InuclElementaryParticle* particle) {
// FIXME: Previous version generated random sin(theta), then used -cos(theta)
// Using generateWithRandomAngles changes result!
// G4ThreeVector pos = generateWithRandomAngles(nuclei_radius).vect();
G4double costh = std::sqrt(1.0 - inuclRndm());
G4double costh = std::sqrt(1.0 - G4UniformRand() );
G4ThreeVector pos = generateWithFixedTheta(-costh, nuclei_radius);
// Start particle outside nucleus, unless capture-at-rest
@@ -1490,31 +1536,31 @@ void G4NucleiModel::initializeCascad(G4InuclNuclei* bullet,
if (bullet->getKineticEnergy()/ab > ekin_cut*ben) {
G4int itryg = 0;
/* Loop checking 08.06.2015 MHK */
/* Loop checking 08.06.2015 MHK */
while (casparticles.size() == 0 && itryg < itry_max) {
itryg++;
particles.clear();
itryg++;
particles.clear();
// nucleons coordinates and momenta in nuclei rest frame
coordinates.clear();
momentums.clear();
// nucleons coordinates and momenta in nuclei rest frame
coordinates.clear();
momentums.clear();
if (ab < 3) { // deuteron, simplest case
G4double r = 2.214 - 3.4208 * G4Log(1.0 - 0.981 * inuclRndm());
G4ThreeVector coord1 = generateWithRandomAngles(r).vect();
coordinates.push_back(coord1);
coordinates.push_back(-coord1);
if (ab < 3) { // deuteron, simplest case
G4double r = 2.214 - 3.4208 * G4Log(1.0 - 0.981*G4UniformRand() );
G4ThreeVector coord1 = generateWithRandomAngles(r).vect();
coordinates.push_back(coord1);
coordinates.push_back(-coord1);
G4double p = 0.0;
G4bool bad = true;
G4int itry = 0;
G4double p = 0.0;
G4bool bad = true;
G4int itry = 0;
while (bad && itry < itry_max) { /* Loop checking 08.06.2015 MHK */
itry++;
p = 456.0 * inuclRndm();
while (bad && itry < itry_max) { /* Loop checking 08.06.2015 MHK */
itry++;
p = 456.0*G4UniformRand();
if (p * p / (p * p + 2079.36) / (p * p + 2079.36) > 1.2023e-4 * inuclRndm() &&
p * r > 312.0) bad = false;
if (p*p / (p*p + 2079.36) / (p*p + 2079.36) > 1.2023e-4 *G4UniformRand()
&& p*r > 312.0) bad = false;
}
if (itry == itry_max)
@@ -1540,41 +1586,41 @@ void G4NucleiModel::initializeCascad(G4InuclNuclei* bullet,
G4int itry = 0;
if (ab == 3) {
while (badco && itry < itry_max) {/* Loop checking 08.06.2015 MHK */
if (itry > 0) coordinates.clear();
itry++;
G4int i(0);
if (ab == 3) {
while (badco && itry < itry_max) {/* Loop checking 08.06.2015 MHK */
if (itry > 0) coordinates.clear();
itry++;
G4int i(0);
for (i = 0; i < 2; i++) {
G4int itry1 = 0;
G4double ss, u, rho;
G4double fmax = G4Exp(-0.5) / std::sqrt(0.5);
for (i = 0; i < 2; i++) {
G4int itry1 = 0;
G4double ss, u, rho;
G4double fmax = G4Exp(-0.5) / std::sqrt(0.5);
while (itry1 < itry_max) { /* Loop checking 08.06.2015 MHK */
itry1++;
ss = -G4Log(inuclRndm());
u = fmax * inuclRndm();
rho = std::sqrt(ss) * G4Exp(-ss);
while (itry1 < itry_max) { /* Loop checking 08.06.2015 MHK */
itry1++;
ss = -G4Log(G4UniformRand() );
u = fmax*G4UniformRand();
rho = std::sqrt(ss) * G4Exp(-ss);
if (rho > u && ss < s3max) {
ss = r0forAeq3 * std::sqrt(ss);
coord1 = generateWithRandomAngles(ss).vect();
coordinates.push_back(coord1);
if (rho > u && ss < s3max) {
ss = r0forAeq3 * std::sqrt(ss);
coord1 = generateWithRandomAngles(ss).vect();
coordinates.push_back(coord1);
if (verboseLevel > 2){
G4cout << " i " << i << " r " << coord1.mag() << G4endl;
}
break;
}
}
if (verboseLevel > 2){
G4cout << " i " << i << " r " << coord1.mag() << G4endl;
}
break;
}
}
if (itry1 == itry_max) { // bad case
coord1.set(10000.,10000.,10000.);
coordinates.push_back(coord1);
break;
}
}
if (itry1 == itry_max) { // bad case
coord1.set(10000.,10000.,10000.);
coordinates.push_back(coord1);
break;
}
}
coord1 = -coordinates[0] - coordinates[1];
if (verboseLevel > 2) {
@@ -1623,24 +1669,24 @@ void G4NucleiModel::initializeCascad(G4InuclNuclei* bullet,
G4int itry1 = 0;
G4double ss;
while (itry1 < itry_max) { /* Loop checking 08.06.2015 MHK */
itry1++;
ss = -G4Log(inuclRndm());
u = fmax * inuclRndm();
while (itry1 < itry_max) { /* Loop checking 08.06.2015 MHK */
itry1++;
ss = -G4Log(G4UniformRand() );
u = fmax*G4UniformRand();
if (std::sqrt(ss) * G4Exp(-ss) * (1.0 + ss/b) > u
&& ss < s4max) {
ss = r0forAeq4 * std::sqrt(ss);
coord1 = generateWithRandomAngles(ss).vect();
coordinates.push_back(coord1);
if (std::sqrt(ss) * G4Exp(-ss) * (1.0 + ss/b) > u
&& ss < s4max) {
ss = r0forAeq4 * std::sqrt(ss);
coord1 = generateWithRandomAngles(ss).vect();
coordinates.push_back(coord1);
if (verboseLevel > 2) {
G4cout << " i " << i << " r " << coord1.mag() << G4endl;
}
if (verboseLevel > 2) {
G4cout << " i " << i << " r " << coord1.mag() << G4endl;
}
break;
}
}
break;
}
}
if (itry1 == itry_max) { // bad case
coord1.set(10000.,10000.,10000.);
@@ -1701,10 +1747,10 @@ void G4NucleiModel::initializeCascad(G4InuclNuclei* bullet,
while(itry2 < itry_max) { /* Loop checking 08.06.2015 MHK */
itry2++;
u = -G4Log(0.879853 - 0.8798502 * inuclRndm());
u = -G4Log(0.879853 - 0.8798502*G4UniformRand() );
x = u * G4Exp(-u);
if(x > inuclRndm()) {
if(x > G4UniformRand() ) {
p = std::sqrt(0.01953 * u);
mom = generateWithRandomAngles(p, massb);
momentums.push_back(mom);
@@ -1744,7 +1790,7 @@ void G4NucleiModel::initializeCascad(G4InuclNuclei* bullet,
}
// nuclei i.p. as a whole
G4double s1 = std::sqrt(inuclRndm());
G4double s1 = std::sqrt(G4UniformRand() );
G4double phi = randomPHI();
G4double rz = (nuclei_radius + rb) * s1;
G4ThreeVector global_pos(rz*std::cos(phi), rz*std::sin(phi),
@@ -1905,8 +1951,8 @@ G4NucleiModel::generateInteractionLength(const G4CascadParticle& cparticle,
G4cout << " mfp " << 1./invmfp << " pw " << pw << G4endl;
// Primary particle(s) should always interact at least once
if (forceFirst(cparticle) || (inuclRndm() < pw)) {
spath = -G4Log(1.0 - pw * inuclRndm()) / invmfp;
if (forceFirst(cparticle) || (G4UniformRand() < pw) ) {
spath = -G4Log(1.0 - pw*G4UniformRand() )/invmfp;
if (cparticle.young(young_cut, spath)) spath = large;
if (verboseLevel > 2)
@@ -6,8 +6,8 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2024-05-02 Gabriele Cosmo (hadr-cohe-V11-01-05)
- Fixed compilation warnings for potentially uninitialised local variables in
## 2024-05-02 Gabriele Cosmo (hadr-cohe-V11-02-00)
- Fixed compilation warnings for potentially initialised local variables in
SampleThetaCMS() for G4DiffuseElastic and G4NuclNuclDiffuseElastic.
## 2023-10-23 Vladimir Ivanchenko (hadr-cohe-V11-01-04)
@@ -6,16 +6,47 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2024-01-29 Vladimir Ivanchenko (hadr-deex-V11-01-12)
## 2024-05-30 Vladimir Ivanchenko (hadr-deex-V11-02-05)
- G4ExcitationHandle, G4NeutronRadCapture - correct model ID for IC electrons
- G4VCoulombBarrier, G4CoulombBarrier, G4GEMCoulombBarrier,
G4FermiBreakUpUtil - clean-up Coulomb barrier classes, removed unused
headers and variables
- G4GEMChannelVI, G4GEMProbabilityVI - updated interfaces and simplified
algorithm of computation of probability
## 2024-05-16 Vladimir Ivanchenko (hadr-deex-V11-02-04)
- G4NuclearLevelData, G4PairingCorrection, G4CameronGilbertPairingCorrections,
G4CameronGilbertShellCorrections - simplified computation of corrections,
computations are done in one place only, not spreaded between classes.
- G4EvaporationChannel, G4EvaporationProbability - fixed usage of pairing
corrections, agreement with test data is improved.
## 2024-05-09 Vladimir Ivanchenko (hadr-deex-V11-02-03)
- G4DeexPrecoParameters - moved definition of int and bool parameters to
source, improve comments, added default width of nuclear level needed
for selection of final excitation in a decay of an excited state
- G4VEmissionProbability - use the new width parameter
- G4EvaporationChannel - fixed computation of minimal kinetic energy of a
fragment for odd-even residual nucleaus
## 2024-01-29 Vladimir Ivanchenko (hadr-deex-V11-02-02)
- G4StatMFChannel - fixed compilation warnings at alma9-gcc131 seen in CMSSW
by substitution of C-arrays by std::vector
## 2024-01-25 Vladimir Ivanchenko
## 2024-01-25 Vladimir Ivanchenko (hadr-deex-V11-02-01)
- G4FermiBreakUpVI, G4FermiFragmentsPoolVI - fixed problem 2584 (production
of fake excited isomeres) by moving the check on lifetime limit from the
pull (initialized once as a static object) to the Initialise() method of
the model allowing to change this limit in an application, do not consider
decay chains with no final state.
- G4VEmissionProbability - substitute local variable "g" by "gg" to avoid
possible shadowing
- G4ExcitationHandler - improved debug printout
## 2024-01-23 Vladimir Ivanchenko (hadr-deex-V11-02-00)
- G4PhotonEvaporation - use in all computations abs(JP) instead of JP,
because since 11.2 JP may be negative due to parity. This address
problem report 2587.
## 2023-11-15 Vladimir Ivanchenko (hadr-deex-V11-01-11)
- G4FermiChannels - fixed memory leak at exit
@@ -78,6 +78,8 @@ private:
G4double muu;
G4double freeU;
G4double a0;
G4double a1;
G4double delta0;
G4double delta1;
// Gamma is A_f(2S_f+1) factor, where A_f is fragment atomic
@@ -88,18 +88,17 @@ G4double G4EvaporationChannel::GetEmissionProbability(G4Fragment* fragment)
{ return 0.0; }
G4double exEnergy = fragment->GetExcitationEnergy();
G4double delta0 = theLevelData->GetPairingCorrection(fragZ,fragA);
/*
G4cout << "G4EvaporationChannel::Initialize Z= "<<theZ<<" A= "<<theA
<< " FragZ= " << fragZ << " FragA= " << fragA
<< " exEnergy= " << exEnergy << " d0= " << delta0 << G4endl;
*/
if(exEnergy < delta0) { return 0.0; }
G4double fragMass = fragment->GetGroundStateMass();
mass = fragMass + exEnergy;
resMass = G4NucleiProperties::GetNuclearMass(resA, resZ);
if (mass <= evapMass + resMass) { return 0.0; }
ekinmax = 0.5*((mass-resMass)*(mass+resMass) + evapMass2)/mass - evapMass;
G4double elim = 0.0;
@@ -107,7 +106,7 @@ G4double G4EvaporationChannel::GetEmissionProbability(G4Fragment* fragment)
bCoulomb = theCoulombBarrier->GetCoulombBarrier(resA, resZ, 0.0);
// for OPTxs >0 penetration under the barrier is taken into account
elim = (0 != OPTxs) ? bCoulomb*0.6 : bCoulomb;
elim = (0 != OPTxs) ? bCoulomb*0.5 : bCoulomb;
}
/*
G4cout << "exEnergy= " << exEnergy << " Ec= " << bCoulomb
@@ -115,14 +114,12 @@ G4double G4EvaporationChannel::GetEmissionProbability(G4Fragment* fragment)
<< " Free= " << mass - resMass - evapMass
<< G4endl;
*/
if(mass <= resMass + evapMass + elim) { return 0.0; }
// Coulomb barrier compound at rest
G4double resM = mass - evapMass - elim;
if (resM < resMass) { return 0.0; }
G4double ekinmin =
std::max(0.5*((mass-resM)*(mass+resM) + evapMass2)/mass - evapMass, 0.0);
G4double ekinmin = 0.0;
if(elim > 0.0) {
G4double resM = mass - evapMass - elim;
ekinmin =
std::max(0.5*((mass-resM)*(mass+resM) + evapMass2)/mass - evapMass, 0.0);
}
/*
G4cout << "Emin= " <<ekinmin<<" Emax= "<<ekinmax
<< " mass= " << mass << " resM= " << resMass
@@ -133,7 +130,7 @@ G4double G4EvaporationChannel::GetEmissionProbability(G4Fragment* fragment)
theProbability->SetDecayKinematics(resZ, resA, resMass, mass);
G4double prob = theProbability->TotalProbability(*fragment, ekinmin,
ekinmax, bCoulomb,
exEnergy - delta0);
exEnergy);
return prob;
}
@@ -52,13 +52,16 @@
#include "G4Log.hh"
#include "G4Pow.hh"
static const G4double explim = 160.;
namespace
{
const G4double explim = 160.;
}
G4EvaporationProbability::G4EvaporationProbability(G4int anA, G4int aZ,
G4double aGamma)
: G4VEmissionProbability(aZ, anA), fGamma(aGamma)
{
resA13 = lastA = muu = freeU = a0 = delta1 = 0.0;
resA13 = lastA = muu = freeU = a0 = a1 = delta0 = delta1 = 0.0;
pcoeff = fGamma*pEvapMass*CLHEP::millibarn
/((CLHEP::pi*CLHEP::hbarc)*(CLHEP::pi*CLHEP::hbarc));
@@ -87,11 +90,11 @@ G4double G4EvaporationProbability::TotalProbability(
G4double CB, G4double exEnergy)
{
G4int fragA = fragment.GetA_asInt();
G4int fragZ = fragment.GetZ_asInt();
G4double U = fragment.GetExcitationEnergy();
a0 = pNuclearLevelData->GetLevelDensity(fragZ,fragA,U);
G4int fragZ = fragment.GetZ_asInt();
freeU = exEnergy;
delta1 = pNuclearLevelData->GetPairingCorrection(resZ,resA);
a0 = pNuclearLevelData->GetLevelDensity(fragZ, fragA, freeU);
delta0 = pNuclearLevelData->GetPairingCorrection(fragZ, fragA);
delta1 = pNuclearLevelData->GetPairingCorrection(resZ, resA);
resA13 = pG4pow->Z13(resA);
/*
G4cout << "G4EvaporationProbability: Z= " << theZ << " A= " << theA
@@ -112,7 +115,7 @@ G4double G4EvaporationProbability::TotalProbability(
G4double Beta = CalcBetaParam(fragment);
// to be checked where to use a0, where - a1
G4double a1 = pNuclearLevelData->GetLevelDensity(resZ,resA,freeU);
a1 = pNuclearLevelData->GetLevelDensity(resZ,resA,freeU);
G4double GlobalFactor = fGamma*Alpha*pEvapMass*RN2*resA13*resA13/(a1*a1);
G4double maxea = maxEnergy*a1;
@@ -140,20 +143,22 @@ G4double G4EvaporationProbability::TotalProbability(
}
G4double G4EvaporationProbability::ComputeProbability(G4double K, G4double CB)
{
G4double E0 = freeU;
{
// abnormal case - should never happens
if(pMass < pEvapMass + pResMass) { return 0.0; }
G4double m02 = pMass*pMass;
G4double m12 = pEvapMass*pEvapMass;
G4double mres = std::sqrt(m02 + m12 - 2.*pMass*(pEvapMass + K));
G4double pEvapM2 = pEvapMass*pEvapMass;
G4double mres = std::sqrt(pMass*pMass + pEvapM2 - 2.*pMass*(pEvapMass + K));
G4double excRes = mres - pResMass;
G4double E1 = excRes - delta1;
if(E1 <= 0.0) { return 0.0; }
G4double a1 = pNuclearLevelData->GetLevelDensity(resZ,resA,excRes);
G4double xs = CrossSection(K, CB);
if (excRes < 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 erec = (pMass*(K + pEvapMass) - pEvapM2)/mres - pEvapMass;
erec = std::max(erec, 0.0);
G4double xs = CrossSection(erec, CB);
G4double prob = pcoeff*G4Exp(2.0*(std::sqrt(a1*E1) - std::sqrt(a0*E0)))*K*xs;
return prob;
}
@@ -173,7 +178,7 @@ G4EvaporationProbability::CrossSection(G4double K, G4double CB)
index, theZ, resA);
} else {
// added barrier penetration factor
G4double elim = 0.6*CB;
G4double elim = 0.5*CB;
if (K > elim) {
res = G4KalbachCrossSection::ComputeCrossSection(K, CB, resA13, muu,
index, theZ, theA, resA);
@@ -35,16 +35,15 @@
namespace G4FermiBreakUpUtil {
const G4double deltaR = 0.6*CLHEP::fermi;
const G4double coeff = 0.9;
const G4double coeff = 0.6;
// Coulomb barrier
G4double CoulombBarrier(const G4int Z1, const G4int A1,
const G4int Z2, const G4int A2, const G4double exc) {
const G4double r1 = G4NuclearRadii::RadiusCB(Z1, A1);
const G4double r2 = G4NuclearRadii::RadiusCB(Z2, A2);
G4double CB = coeff*CLHEP::elm_coupling*(Z1*Z2)/(r1 + r2 - deltaR);
if(exc > 0.0) { CB /= (1.0 + std::sqrt(exc/((2*(A1 + A2))*CLHEP::MeV))); }
G4double CB = CLHEP::elm_coupling*(Z1*Z2)/(coeff*r1 + r2);
if (exc > 0.0) { CB /= (1.0 + std::sqrt(exc/((2*(A1 + A2))*CLHEP::MeV))); }
return CB;
}
@@ -37,43 +37,60 @@ class G4VCoulombBarrier;
class G4LevelManager;
class G4GEMProbabilityVI;
class G4GEMChannelVI final: public G4VEvaporationChannel
class G4GEMChannelVI : public G4VEvaporationChannel
{
public:
explicit G4GEMChannelVI(G4int theA, G4int theZ);
~G4GEMChannelVI() final;
G4double GetEmissionProbability(G4Fragment* theNucleus) final;
~G4GEMChannelVI() override;
G4Fragment* EmittedFragment(G4Fragment* theNucleus) final;
void Initialise() override;
void Dump() const final;
G4double GetEmissionProbability(G4Fragment* theNucleus) override;
G4Fragment* EmittedFragment(G4Fragment* theNucleus) override;
void Dump() const override;
G4GEMChannelVI(const G4GEMChannelVI & right) = delete;
const G4GEMChannelVI & operator=(const G4GEMChannelVI & right) = delete;
G4bool operator==(const G4GEMChannelVI & right) const = delete;
G4bool operator!=(const G4GEMChannelVI & right) const = delete;
private:
G4GEMChannelVI(const G4GEMChannelVI & right);
const G4GEMChannelVI & operator=(const G4GEMChannelVI & right);
G4bool operator==(const G4GEMChannelVI & right) const;
G4bool operator!=(const G4GEMChannelVI & right) const;
const G4VCoulombBarrier* cBarrier;
const G4PairingCorrection* pairingCorrection;
G4GEMProbabilityVI* fProbability;
G4double fEvapMass;
G4double fEvapMass2;
G4double fMass{0.0};
G4double fResMass{0.0};
G4double fExc{0.0};
G4double bCoulomb{0.0};
G4double fCoeff;
G4int A;
G4int Z;
G4int resA;
G4int resZ;
G4int fragA;
G4int fragZ;
G4int secID; // Creator model ID for the secondaries created by this model
G4int resA{0};
G4int resZ{0};
G4int fragA{0};
G4int fragZ{0};
G4int fVerbose{1};
G4int nProb{1};
G4int secID;
G4int indexC;
G4double mass;
G4double resMass;
G4double evapMass;
G4double evapMass2;
// 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];
};
#endif
@@ -33,6 +33,8 @@
#include "G4CoulombBarrier.hh"
#include "globals.hh"
class G4Pow;
class G4GEMCoulombBarrier : public G4CoulombBarrier
{
public:
@@ -50,6 +52,7 @@ private:
G4double CalcCompoundRadius(G4int ARes) const;
G4Pow* g4calc;
G4double AejectOneThird;
};
#endif
@@ -31,46 +31,35 @@
#include "G4VEmissionProbability.hh"
//const G4int NPOINTSGEM = 10;
class G4LevelManager;
class G4GEMProbabilityVI final: public G4VEmissionProbability
class G4GEMProbabilityVI : public G4VEmissionProbability
{
public:
explicit G4GEMProbabilityVI(G4int anA, G4int aZ, const G4LevelManager*);
~G4GEMProbabilityVI() final;
~G4GEMProbabilityVI() override = default;
G4double ComputeTotalProbability(const G4Fragment&, G4double CB);
G4double TotalProbability(const G4Fragment&,
const G4double tmin, const G4double tmax,
const G4double CB, const G4double exEnergy,
const G4double exEvap);
// compute probability for evaporated fragment in ground state
G4double ComputeProbability(G4double ekin, G4double CB) override;
G4Fragment* SampleEvaporationFragment();
G4double SampleEnergy(const G4double tmin, const G4double tmax,
const G4double CB, const G4double exEnergy,
const G4double exEvap);
G4GEMProbabilityVI(const G4GEMProbabilityVI& right) = delete;
const G4GEMProbabilityVI & operator=(const G4GEMProbabilityVI& right) = delete;
G4bool operator==(const G4GEMProbabilityVI& right) const = delete;
G4bool operator!=(const G4GEMProbabilityVI& right) const = delete;
private:
// compute probability for evaporated fragment may be excited
G4double Integrated2DProbability();
// probability as a function of excitations
G4double ProbabilityDistributionFunction(G4double exc, G4double resExc);
G4Fragment* Sample2DDistribution();
G4double I0(G4double t);
G4double I1(G4double t, G4double tx);
G4double I2(G4double s0, G4double sx);
G4double I3(G4double s0, G4double sx);
// Copy constructor
G4GEMProbabilityVI(const G4GEMProbabilityVI &right);
const G4GEMProbabilityVI & operator=(const G4GEMProbabilityVI &right);
G4bool operator==(const G4GEMProbabilityVI &right) const;
G4bool operator!=(const G4GEMProbabilityVI &right) const;
const G4LevelManager* lManager;
G4int fragA;
@@ -38,23 +38,50 @@
#include "G4NucleiProperties.hh"
#include "G4RandomDirection.hh"
#include "G4PhysicsModelCatalog.hh"
#include "Randomize.hh"
namespace
{
const G4double minExc = 1.0*CLHEP::MeV;
const G4int nProbMax = 10;
}
G4GEMChannelVI::G4GEMChannelVI(G4int theA, G4int theZ)
: A(theA), Z(theZ), secID(-1)
{
: A(theA), Z(theZ)
{
G4NuclearLevelData* nData = G4NuclearLevelData::GetInstance();
pairingCorrection = nData->GetPairingCorrection();
const G4LevelManager* lManager = nullptr;
if(A > 4) { lManager = nData->GetLevelManager(Z, A); }
evapMass = G4NucleiProperties::GetNuclearMass(A, Z);
evapMass2 = evapMass*evapMass;
if (A > 4) { lManager = nData->GetLevelManager(Z, A); }
fEvapMass = G4NucleiProperties::GetNuclearMass(A, Z);
fEvapMass2 = fEvapMass*fEvapMass;
cBarrier = new G4CoulombBarrier(A, Z);
fProbability = new G4GEMProbabilityVI(A, Z, lManager);
resA = resZ = fragZ = fragA = 0;
mass = resMass = 0.0;
fCoeff = CLHEP::millibarn/((CLHEP::pi*CLHEP::hbarc)*(CLHEP::pi*CLHEP::hbarc));
secID = G4PhysicsModelCatalog::GetModelID("model_G4GEMChannelVI");
if (Z == 0 && A == 1) {
indexC = 0;
fCoeff *= 2.0;
} else if (Z == 1 && A == 1) {
indexC = 1;
fCoeff *= 2.0;
} else if (Z == 1 && A == 2) {
indexC = 2;
fCoeff *= 3.0;
} else if (Z == 1 && A == 3) {
indexC = 3;
fCoeff *= 2.0;
} else if (Z == 2 && A == 3) {
indexC = 4;
fCoeff *= 2.0;
} else if (Z == 2 && A == 4) {
indexC = 5;
} else {
indexC = 6;
}
}
G4GEMChannelVI::~G4GEMChannelVI()
@@ -63,6 +90,12 @@ G4GEMChannelVI::~G4GEMChannelVI()
delete fProbability;
}
void G4GEMChannelVI::Initialise()
{
fProbability->Initialise();
G4VEvaporationChannel::Initialise();
}
G4double G4GEMChannelVI::GetEmissionProbability(G4Fragment* fragment)
{
fProbability->ResetProbability();
@@ -74,23 +107,53 @@ G4double G4GEMChannelVI::GetEmissionProbability(G4Fragment* fragment)
return 0.0;
}
const G4double exc = fragment->GetExcitationEnergy();
const G4double delta0 =
std::max(pairingCorrection->GetPairingCorrection(fragA, fragZ),0.0);
if(exc < delta0) { return 0.0; }
resMass = G4NucleiProperties::GetNuclearMass(resA, resZ);
const G4double fragM = fragment->GetGroundStateMass() + exc;
const G4double CB = cBarrier->GetCoulombBarrier(resA, resZ, exc);
const G4double delta1 =
std::max(0.0,pairingCorrection->GetPairingCorrection(resA,resZ));
if(fragM <= resMass + CB + delta1) { return 0.0; }
fExc = fragment->GetExcitationEnergy();
fMass = fragment->GetGroundStateMass() + fExc;
fResMass = G4NucleiProperties::GetNuclearMass(resA, resZ);
fProbability->SetDecayKinematics(resZ, resA, resMass, fragM);
G4double prob = fProbability->ComputeTotalProbability(*fragment, CB);
//G4cout<<"G4EvaporationChannel: probability= "<< prob <<G4endl;
return prob;
// limit for the case when both evaporation and residual
// fragments are in ground states
if (fMass <= fEvapMass + fResMass) { return 0.0; }
if (Z > 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;
} else {
nProb = std::min(nProb, nProbMax);
}
if (2 < fVerbose) {
G4cout << "## G4GEMChannelVI::GetEmissionProbability fragZ="
<< fragZ << " fragA=" << fragA << " Z=" << Z << " A=" << A
<< " Eex(MeV)=" << fExc << " nProb=" << nProb
<< 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;
}
return sump;
}
G4Fragment* G4GEMChannelVI::EmittedFragment(G4Fragment* theNucleus)
@@ -99,23 +162,36 @@ G4Fragment* G4GEMChannelVI::EmittedFragment(G4Fragment* theNucleus)
// if value iz zero no possiblity to sample final state
G4Fragment* evFragment = nullptr;
G4LorentzVector lv0 = theNucleus->GetMomentum();
if(resA <= 4 || fProbability->GetProbability() == 0.0) {
G4double ekin =
std::max(0.5*(mass*mass - resMass*resMass + evapMass2)/mass
- evapMass, 0.0);
G4LorentzVector lv(std::sqrt(ekin*(ekin + 2.0*evapMass))
*G4RandomDirection(), ekin + evapMass);
lv.boost(lv0.boostVector());
evFragment = new G4Fragment(A, Z, lv);
lv0 -= lv;
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 {
evFragment = fProbability->SampleEvaporationFragment();
G4LorentzVector lv = evFragment->GetMomentum();
lv.boost(lv0.boostVector());
evFragment->SetMomentum(lv);
lv0 -= lv;
G4double p = G4UniformRand()*probMax;
G4int i{1};
for (; i<nProb; ++i) {
if (p <= fEData[i].prob) { break; }
}
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);
}
if(evFragment != nullptr) { evFragment->SetCreatorModelID(secID); }
G4double m1 = fEvapMass + exc;
G4LorentzVector lv(std::sqrt(ekin*(ekin + 2.0*m1))
*G4RandomDirection(), ekin + m1);
lv.boost(lv0.boostVector());
evFragment = new G4Fragment(A, Z, lv);
lv0 -= lv;
evFragment->SetCreatorModelID(secID);
theNucleus->SetZandA_asInt(resZ, resA);
theNucleus->SetMomentum(lv0);
theNucleus->SetCreatorModelID(secID);
@@ -36,6 +36,7 @@
G4GEMCoulombBarrier::G4GEMCoulombBarrier(G4int anA, G4int aZ) :
G4CoulombBarrier(anA, aZ)
{
g4calc = G4Pow::GetInstance();
AejectOneThird = g4calc->Z13(anA);
}
@@ -44,7 +45,7 @@ G4double G4GEMCoulombBarrier::GetCoulombBarrier(G4int ARes, G4int ZRes,
{
// Calculation of Coulomb potential energy (barrier) for outgoing fragment
G4double Barrier = 0.0;
if (theZ > 0 && ZRes > 0) {
if (theZ > 0) {
G4double CompoundRadius = CalcCompoundRadius(ARes);
Barrier = CLHEP::elm_coupling * (theZ * ZRes)/CompoundRadius;
@@ -38,33 +38,6 @@
#include "G4Pow.hh"
#include "G4Exp.hh"
// 10-Points Gauss-Legendre abcisas and weights
/*
const G4double G4GEMChannelVI::ws[] = {
0.0666713443086881,
0.149451349150581,
0.219086362515982,
0.269266719309996,
0.295524224714753,
0.295524224714753,
0.269266719309996,
0.219086362515982,
0.149451349150581,
0.0666713443086881
};
const G4double G4GEMChannelVI::xs[] = {
-0.973906528517172,
-0.865063366688985,
-0.679409568299024,
-0.433395394129247,
-0.148874338981631,
0.148874338981631,
0.433395394129247,
0.679409568299024,
0.865063366688985,
0.973906528517172
};
*/
G4GEMProbabilityVI::G4GEMProbabilityVI(G4int anA, G4int aZ, const G4LevelManager* p)
: G4VEmissionProbability(aZ, anA), lManager(p)
@@ -87,11 +60,11 @@ G4GEMProbabilityVI::G4GEMProbabilityVI(G4int anA, G4int aZ, const G4LevelManager
}
}
G4GEMProbabilityVI::~G4GEMProbabilityVI()
{}
G4double G4GEMProbabilityVI::ComputeTotalProbability(
const G4Fragment& fragment, G4double CB)
G4double G4GEMProbabilityVI::TotalProbability(
const G4Fragment& fragment,
const G4double tmin, const G4double tmax,
const G4double CB, const G4double exEnergy,
const G4double exEvap)
{
fragA = fragment.GetA_asInt();
fragZ = fragment.GetZ_asInt();
@@ -105,38 +78,15 @@ G4double G4GEMProbabilityVI::ComputeTotalProbability(
resA13 = pG4pow->Z13(resA);
a0 = pNuclearLevelData->GetLevelDensity(fragZ,fragA,U);
G4double C = 0.0;
G4int Z2 = theZ*theZ;
G4int Z3 = Z2*theZ;
G4int Z4 = Z2*Z2;
if(resA >= 50) {
C = -0.10/(G4double)theA;
} else if(resZ > 20) {
C = (0.123482-0.00534691*theZ-0.0000610624*Z2+5.93719*1e-7*Z3+
1.95687*1e-8*Z4)/(G4double)theA;
}
if(0 == theZ) {
alphaP = 0.76+1.93/resA13;
betaP = (1.66/(resA13*resA13)-0.05)*CLHEP::MeV/alphaP;
} else {
alphaP = 1.0 + C;
betaP = - bCoulomb;
}
if(isExcited) {
pProbability = Integrated2DProbability();
} else {
const G4double twoMass = pMass + pMass;
const G4double evapMass2 = pEvapMass*pEvapMass;
G4double ekinmax =
const G4double twoMass = pMass + pMass;
const G4double evapMass2 = pEvapMass*pEvapMass;
G4double ekinmax =
((pMass-pResMass)*(pMass+pResMass) + evapMass2)/twoMass - pEvapMass;
G4double ekinmin =
G4double ekinmin =
std::max((CB*(twoMass - CB) + evapMass2)/twoMass - pEvapMass,0.0);
if(ekinmax <= ekinmin) { return 0.0; }
pProbability = IntegrateProbability(ekinmin, ekinmax, CB);
}
if(ekinmax <= ekinmin) { return 0.0; }
pProbability = IntegrateProbability(ekinmin, ekinmax, CB);
pProbability += tmax - tmin + exEnergy -exEvap;
/*
G4cout << "G4GEMProbabilityVI: Z= " << theZ << " A= " << theA
<< " resZ= " << resZ << " resA= " << resA
@@ -159,141 +109,18 @@ G4double G4GEMProbabilityVI::ComputeProbability(G4double ekin, G4double)
G4double excRes = std::max(mres - pResMass, 0.0);
a1 = pNuclearLevelData->GetLevelDensity(resZ,resA,excRes);
G4double prob = ProbabilityDistributionFunction(0.0, excRes);
G4double prob = 0.5; //CrossSection(0.0, excRes);
//G4cout<<"### G4GEMProbabilityVI::ComputeProbability: Ekin(MeV)= "<<ekin
//<< " excRes(MeV)= " << excRes << " prob= " << prob << << G4endl;
return prob;
}
G4Fragment* G4GEMProbabilityVI::SampleEvaporationFragment()
G4double G4GEMProbabilityVI::SampleEnergy(
const G4double tmin, const G4double tmax,
const G4double CB, const G4double exEnergy,
const G4double exEvap)
{
if(isExcited) { return Sample2DDistribution(); }
G4double ekin = SampleEnergy();
G4LorentzVector lv(std::sqrt(ekin*(ekin + 2.0*pEvapMass))
*G4RandomDirection(), ekin + pEvapMass);
G4Fragment* evFragment = new G4Fragment(theA, theZ, lv);
return evFragment;
G4double ekin = tmax - tmin - CB -exEnergy + exEvap;
return ekin;
}
G4double G4GEMProbabilityVI::Integrated2DProbability()
{
return 0.0;
}
G4double G4GEMProbabilityVI::ProbabilityDistributionFunction(
G4double exc, G4double resExc)
{
G4double Ux = (2.5 + 150.0/G4double(resA))*CLHEP::MeV;
G4double Ex = Ux + delta1;
G4double T = 1.0/(std::sqrt(a0/Ux) - 1.5/Ux);
G4double E0 = Ex - T*(G4Log(T) - G4Log(a0)*0.25
- 1.25*G4Log(Ux) + 2.0*std::sqrt(a0*Ux));
G4double UxCN = (2.5 + 150.0/(G4double)theA)*CLHEP::MeV;
G4double ExCN = UxCN + delta0;
G4double TCN = 1.0/(std::sqrt(a0/UxCN) - 1.5/UxCN);
G4double mass1 = pEvapMass + exc;
G4double mass2 = pResMass + resExc;
G4double maxKinEnergy = std::max(0.5*((pMass - mass2)*(pMass + mass2)
+ mass1*mass1)/pMass - mass1, 0.0);
G4double Width = 0.0;
G4double t = maxKinEnergy/T;
if ( maxKinEnergy < Ex ) {
Width = (I1(t,t)*T + (betaP+bCoulomb)*I0(t))/G4Exp(E0/T);
} else {
G4double tx = Ex/T;
G4double s0 = 2.0*std::sqrt(a0*(maxKinEnergy-delta0));
G4double sx = 2.0*std::sqrt(a0*(Ex-delta0));
// VI: protection against FPE exception
s0 = std::min(s0, 350.);
G4double expE0T = G4Exp(E0/T);
G4double exps0 = G4Exp(s0);
const G4double sqrt2 = std::sqrt(2.0);
Width = I1(t,tx)*T/expE0T + I3(s0,sx)*exps0/(sqrt2*a0);
if (0 == theZ) {
Width += (betaP+bCoulomb)*(I0(tx)/expE0T + 2.0*sqrt2*I2(s0,sx)*exps0);
}
}
Width *= alphaP*pMass;
//JMQ 190709 fix on Rb and geometrical cross sections according to
// Furihata's paper (JAERI-Data/Code 2001-105, p6)
G4double Rb = 0.0;
if (theA > 4) {
Rb = 1.12*(resA13 + A13) - 0.86*((resA13 + A13)/(resA13*A13))+2.85;
} else if (theA > 1) {
Rb=1.5*(resA13 + A13);
} else {
Rb = 1.5*resA13;
}
G4double ild;
if (exc < ExCN ) {
G4double E0CN = ExCN - TCN*(G4Log(TCN) - 0.25*G4Log(a0)
- 1.25*G4Log(UxCN)
+ 2.0*std::sqrt(a0*UxCN));
ild = G4Exp((exc-E0CN)/TCN)/TCN;
} else {
G4double x = exc - delta0;
G4double x1 = std::sqrt(a0*x);
ild = G4Exp(2*x1)/(x*std::sqrt(x1));
}
Width *= (Rb*Rb/ild);
return Width;
}
G4Fragment* G4GEMProbabilityVI::Sample2DDistribution()
{
G4Fragment* aFragment = nullptr;
return aFragment;
}
G4double G4GEMProbabilityVI::I0(G4double t)
{
return G4Exp(t) - 1.0;
}
G4double G4GEMProbabilityVI::I1(G4double t, G4double tx)
{
return (t - tx + 1.0)*G4Exp(tx) - t - 1.0;
}
G4double G4GEMProbabilityVI::I2(G4double s0, G4double sx)
{
G4double S = 1.0/std::sqrt(s0);
G4double Sx = 1.0/std::sqrt(sx);
G4double p1 = S*S*S*( 1.0 + S*S*( 1.5 + 3.75*S*S) );
G4double p2 = Sx*Sx*Sx*( 1.0 + Sx*Sx*( 1.5 + 3.75*Sx*Sx) )*G4Exp(sx-s0);
return p1-p2;
}
G4double G4GEMProbabilityVI::I3(G4double s0, G4double sx)
{
G4double s2 = s0*s0;
G4double sx2 = sx*sx;
G4double S = 1.0/std::sqrt(s0);
G4double S2 = S*S;
G4double Sx = 1.0/std::sqrt(sx);
G4double Sx2 = Sx*Sx;
G4double p1 = S *(2.0 + S2 *( 4.0 + S2 *( 13.5 + S2 *( 60.0 + S2 * 325.125 ))));
G4double p2 = Sx*Sx2 *((s2-sx2) + Sx2 *((1.5*s2+0.5*sx2)
+ Sx2 *((3.75*s2+0.25*sx2) + Sx2 *((12.875*s2+0.625*sx2)
+ Sx2 *((59.0625*s2+0.9375*sx2) + Sx2 *(324.8*s2+3.28*sx2))))));
p2 *= G4Exp(sx-s0);
return p1-p2;
}
@@ -139,7 +139,6 @@ void G4ExcitationHandler::SetParameters()
minEForMultiFrag = param->GetMinExPerNucleounForMF();
minExcitation = param->GetMinExcitation();
maxExcitation = param->GetPrecoHighEnergy();
icID = G4PhysicsModelCatalog::GetModelID("model_e-InternalConversion");
// allowing local debug printout
fVerbose = std::max(fVerbose, param->GetVerbose());
@@ -506,7 +505,7 @@ G4ExcitationHandler::BreakItUp(const G4Fragment & theInitialState)
// in memory for the vector
theReactionProductVector->reserve( theResults.size() );
if (fVerbose > 2) {
if (fVerbose > 1) {
G4cout << "### ExcitationHandler provides " << theResults.size()
<< " evaporated products:" << G4endl;
}
@@ -587,6 +586,7 @@ G4ExcitationHandler::BreakItUp(const G4Fragment & theInitialState)
G4cout << "### EXCH: Find ion Z= " << fragmentZ
<< " A= " << fragmentA
<< " Eexc(MeV)= " << eexc/MeV << " idx= " << idxf
<< " " << theKindOfFragment->GetParticleName()
<< G4endl;
}
}
@@ -608,11 +608,7 @@ G4ExcitationHandler::BreakItUp(const G4Fragment & theInitialState)
}
theNew->SetTotalEnergy(etot);
theNew->SetFormationTime(frag->GetCreationTime());
if (theKindOfFragment == theElectron) {
theNew->SetCreatorModelID(icID);
} else {
theNew->SetCreatorModelID(frag->GetCreatorModelID());
}
theNew->SetCreatorModelID(frag->GetCreatorModelID());
theReactionProductVector->push_back(theNew);
// fragment not found out ground state is created
@@ -86,6 +86,8 @@ public:
inline G4double GetMinExcitation() const;
inline G4double GetNuclearLevelWidth() const;
inline G4double GetMaxLifeTime() const;
inline G4double GetMinExPerNucleounForMF() const;
@@ -150,6 +152,8 @@ public:
void SetMinExcitation(G4double);
void SetNuclearLevelWidth(G4double);
void SetMaxLifeTime(G4double);
void SetMinExPerNucleounForMF(G4double);
@@ -234,47 +238,48 @@ private:
G4double fPrecoHighEnergy;
// Preco phenomenological factor
G4double fPhenoFactor = 1.0;
G4double fPhenoFactor;
// Excitation handler
G4double fMinExcitation;
G4double fNuclearLevelWidth;
G4double fMaxLifeTime;
// Multi-fragmentation model
G4double fMinExPerNucleounForMF;
// Cross section type
G4int fPrecoType = 3;
G4int fDeexType = 3;
G4int fPrecoType;
G4int fDeexType;
G4int fTwoJMAX = 10;
G4int fTwoJMAX;
// Preco model
G4int fMinZForPreco = 3;
G4int fMinAForPreco = 5;
G4int fMinZForPreco;
G4int fMinAForPreco;
G4int fVerbose = 1;
G4int fVerbose;
// Preco flags
G4bool fNeverGoBack = false;
G4bool fUseSoftCutoff = false;
G4bool fUseCEM = true;
G4bool fUseGNASH = false;
G4bool fUseHETC = false;
G4bool fUseAngularGen = true;
G4bool fPrecoDummy = false;
G4bool fNeverGoBack;
G4bool fUseSoftCutoff;
G4bool fUseCEM;
G4bool fUseGNASH;
G4bool fUseHETC;
G4bool fUseAngularGen;
G4bool fPrecoDummy;
// Deex flags
G4bool fCorrelatedGamma = false;
G4bool fStoreAllLevels = false;
G4bool fInternalConversion = true;
G4bool fLD = true; // use simple level density model
G4bool fFD = true; // use transition to discrete level
G4bool fIsomerFlag = true; // enable isomere production
G4bool fIsPrinted = false;
G4bool fCorrelatedGamma;
G4bool fStoreAllLevels;
G4bool fInternalConversion;
G4bool fLD;
G4bool fFD;
G4bool fIsomerFlag;
G4bool fIsPrinted{false};
// type of a set of e-exitation channels
G4DeexChannelType fDeexChannelType = fCombined;
// type of a set of de-exitation channels
G4DeexChannelType fDeexChannelType;
};
inline G4double G4DeexPrecoParameters::GetLevelDensity() const
@@ -322,6 +327,11 @@ inline G4double G4DeexPrecoParameters::GetMinExcitation() const
return fMinExcitation;
}
inline G4double G4DeexPrecoParameters::GetNuclearLevelWidth() const
{
return fNuclearLevelWidth;
}
inline G4double G4DeexPrecoParameters::GetMaxLifeTime() const
{
return fMaxLifeTime;
@@ -112,6 +112,7 @@ protected:
G4double pResMass = 0.0;
G4double pProbability = 0.0;
G4double pTolerance = 0.0;
G4double pWidth = 0.0;
private:
@@ -58,16 +58,47 @@ void G4DeexPrecoParameters::SetDefaults()
void G4DeexPrecoParameters::Initialise()
{
// common parameters
fVerbose = 1;
fLevelDensity = 0.075/CLHEP::MeV;
fR0 = 1.5*CLHEP::fermi;
fTransitionsR0 = 0.6*CLHEP::fermi;
fFBUEnergyLimit = 20.0*CLHEP::MeV;
fFermiEnergy = 35.0*CLHEP::MeV;
// preco parameters
fPrecoLowEnergy = 0.1*CLHEP::MeV;
fPrecoHighEnergy = 30*CLHEP::MeV;
fPhenoFactor = 1.0;
fPrecoType = 3;
fMinZForPreco = 3;
fMinAForPreco = 5;
fNeverGoBack = false;
fUseSoftCutoff = false;
fUseCEM = true;
fUseGNASH = false;
fUseHETC = false;
fUseAngularGen = true;
fPrecoDummy = false;
// de-exitation parameters
fMinExcitation = 10*CLHEP::eV;
fNuclearLevelWidth = 0.2*CLHEP::MeV;
fFBUEnergyLimit = 20.0*CLHEP::MeV;
fFermiEnergy = 35.0*CLHEP::MeV;
fMaxLifeTime = 1*CLHEP::nanosecond;
fMinExPerNucleounForMF = 200*CLHEP::GeV;
fDeexChannelType = fCombined;
fDeexType = 3;
fTwoJMAX = 10;
fCorrelatedGamma = false;
fStoreAllLevels = false;
fInternalConversion = true;
fLD = true; // use simple level density model
fFD = false; // use transition to discrete level
fIsomerFlag = true; // enable isomere production
}
void G4DeexPrecoParameters::SetLevelDensity(G4double val)
@@ -124,6 +155,12 @@ void G4DeexPrecoParameters::SetMinExcitation(G4double val)
fMinExcitation = val;
}
void G4DeexPrecoParameters::SetNuclearLevelWidth(G4double val)
{
if(IsLocked() || val < 0.0) { return; }
fNuclearLevelWidth = val;
}
void G4DeexPrecoParameters::SetMaxLifeTime(G4double val)
{
if(IsLocked() || val < 0.0) { return; }
@@ -620,30 +620,24 @@ G4ShellCorrection* G4NuclearLevelData::GetShellCorrection()
G4double G4NuclearLevelData::GetLevelDensity(G4int Z, G4int A, G4double U)
{
if(fDeexPrecoParameters->GetLevelDensityFlag()) {
if (fDeexPrecoParameters->GetLevelDensityFlag()) {
return A*fDeexPrecoParameters->GetLevelDensity();
}
const G4LevelManager* man = GetLevelManager(Z, A);
return (man) ? man->LevelDensity(U)
return (nullptr != man) ? man->LevelDensity(U)
: 0.058025*A*(1.0 + 5.9059/fG4calc->Z13(A));
}
G4double G4NuclearLevelData::GetPairingCorrection(G4int Z, G4int A)
{
if(fDeexPrecoParameters->GetLevelDensityFlag()) {
return fPairingCorrection->GetPairingCorrection(A, Z);
}
G4int N = A - Z;
const G4double par = 12.*CLHEP::MeV;
G4double x = (A <= 36) ? 6.0 : std::sqrt((G4double)A);
return (2 - Z + (Z/2)*2 - N + (N/2)*2)*par/x;
return fPairingCorrection->GetPairingCorrection(A, Z);
}
void G4NuclearLevelData::StreamLevels(std::ostream& os,
G4int Z, G4int A)
{
const G4LevelManager* man = GetLevelManager(Z, A);
if(man) {
if (man) {
os << "Level data for Z= " << Z << " A= " << A << " "
<< man->NumberOfTransitions() + 1 << " levels \n";
man->StreamInfo(os);
@@ -53,6 +53,7 @@ void G4VEmissionProbability::Initialise()
pVerbose = param->GetVerbose();
fFD = param->GetDiscreteExcitationFlag();
pTolerance = param->GetMinExcitation();
pWidth = param->GetNuclearLevelWidth();
}
void G4VEmissionProbability::ResetIntegrator(size_t, G4double de, G4double eps)
@@ -185,7 +186,7 @@ G4double G4VEmissionProbability::SampleEnergy()
CLHEP::HepRandomEngine* rndm = G4Random::getTheEngine();
const G4int nmax = 1000;
G4double ekin, g, gmax;
G4double ekin, gg, gmax;
G4int n = 0;
do {
++n;
@@ -201,22 +202,22 @@ G4double G4VEmissionProbability::SampleEnergy()
gmax = probmax*((x > alim) ? G4Exp(-x) : 1.0 - x*(1.0 - 0.5*x));
}
}
g = ComputeProbability(ekin, eCoulomb);
gg = ComputeProbability(ekin, eCoulomb);
if(pVerbose > 2) {
G4cout << " " << n
<< ". prob= " << g << " probmax= " << probmax
<< ". prob= " << gg << " probmax= " << probmax
<< " Ekin= " << ekin << G4endl;
}
if((g > gmax || n > nmax) && pVerbose > 1) {
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=" << g/gmax
<< " prob=" << g << " gmax=" << gmax << " probmax=" << probmax
<< " prob/gmax=" << gg/gmax
<< " prob=" << gg << " gmax=" << gmax << " probmax=" << probmax
<< "\n Ekin= " << ekin << " Emin= " << emin
<< " Emax= " << emax << G4endl;
}
} while(gmax*rndm->flat() > g && n < nmax);
} while(gmax*rndm->flat() > gg && n < nmax);
G4double enew = FindRecoilExcitation(ekin);
if(pVerbose > 1) {
G4cout << "### SampleEnergy: Efinal= "
@@ -258,15 +259,21 @@ G4double G4VEmissionProbability::FindRecoilExcitation(const G4double e)
if(fExcRes > lManager->MaxLevelEnergy() + pTolerance) { return e; }
// find level
G4double elevel = lManager->NearestLevelEnergy(fExcRes);
std::size_t idx = lManager->NearestLevelIndex(fExcRes);
auto level = lManager->GetLevel(idx);
// excited level
if(pMass > mass + pResMass + elevel &&
std::abs(elevel - fExcRes) <= pTolerance) {
G4double massR = pResMass + elevel;
G4double mr2 = massR*massR;
fExcRes = elevel;
return std::max(0.5*(m02 + m12 - mr2)/pMass - mass, 0.0);
// unstable level
if (level->GetTimeGamma() == 0.0) { return e; }
// is possible to use level energy?
G4double elevel = lManager->LevelEnergy(idx);
if (std::abs(elevel - fExcRes) > pWidth || pMass < mass + pResMass + elevel) {
return e;
}
return e;
// 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);
}
@@ -52,27 +52,25 @@ class G4NeutronRadCapture : public G4HadronicInteraction
{
public:
explicit G4NeutronRadCapture();
G4NeutronRadCapture();
virtual ~G4NeutronRadCapture();
~G4NeutronRadCapture() override;
virtual G4HadFinalState* ApplyYourself(const G4HadProjectile & aTrack,
G4Nucleus & targetNucleus) final;
G4HadFinalState* ApplyYourself(const G4HadProjectile & aTrack,
G4Nucleus & targetNucleus) override;
virtual void InitialiseModel() final;
private:
void InitialiseModel() override;
G4NeutronRadCapture & operator=(const G4NeutronRadCapture &right) = delete;
G4NeutronRadCapture(const G4NeutronRadCapture&) = delete;
G4int icID; // creator model ID for electrons produced by internal conversion
G4int secID; // creator model ID for the other secondaries produced by this model
const G4ParticleDefinition* electron;
private:
G4int secID; // creator model ID for secondaries produced by this model
G4double lowestEnergyLimit;
G4double minExcitation;
G4VEvaporationChannel* photonEvaporation;
G4IonTable* theTableOfIons;
G4IonTable* theTableOfIons;
G4LorentzVector lab4mom;
};
@@ -59,11 +59,6 @@ G4NeutronRadCapture::G4NeutronRadCapture()
{
lowestEnergyLimit = 10*CLHEP::eV;
minExcitation = 0.1*CLHEP::keV;
SetMinEnergy( 0.0*CLHEP::GeV );
SetMaxEnergy( G4HadronicParameters::Instance()->GetMaxEnergy() );
electron = G4Electron::Electron();
icID = -1;
secID = -1;
theTableOfIons = G4ParticleTable::GetParticleTable()->GetIonTable();
}
@@ -79,7 +74,6 @@ void G4NeutronRadCapture::InitialiseModel()
G4DeexPrecoParameters* param =
G4NuclearLevelData::GetInstance()->GetParameters();
minExcitation = param->GetMinExcitation();
icID = G4PhysicsModelCatalog::GetModelID("model_e-InternalConversion");
secID = G4PhysicsModelCatalog::GetModelID("model_" + GetModelName());
photonEvaporation = new G4PhotonEvaporation();
photonEvaporation->Initialise();
@@ -101,7 +95,7 @@ G4HadFinalState* G4NeutronRadCapture::ApplyYourself(
lab4mom.set(0.,0.,0.,G4NucleiProperties::GetNuclearMass(A, Z));
lab4mom += aTrack.Get4Momentum();
G4double M = lab4mom.mag();
G4double M = lab4mom.mag();
++A;
G4double mass = G4NucleiProperties::GetNuclearMass(A, Z);
//G4cout << "Capture start: Z= " << Z << " A= " << A
@@ -176,14 +170,14 @@ G4HadFinalState* G4NeutronRadCapture::ApplyYourself(
// Sample final state
//
G4FragmentVector* fv = photonEvaporation->BreakUpFragment(aFragment);
if(!fv) { fv = new G4FragmentVector(); }
if (nullptr == fv) { fv = new G4FragmentVector(); }
fv->push_back(aFragment);
size_t n = fv->size();
std::size_t n = fv->size();
if (verboseLevel > 1) {
G4cout << "G4NeutronRadCapture: " << n << " final particle icID= " << icID << G4endl;
G4cout << "G4NeutronRadCapture: " << n << " final particles" << G4endl;
}
for(size_t i=0; i<n; ++i) {
for(std::size_t i=0; i<n; ++i) {
G4Fragment* f = (*fv)[i];
G4double etot = f->GetMomentum().e();
@@ -221,11 +215,7 @@ G4HadFinalState* G4NeutronRadCapture::ApplyYourself(
G4double timeF = f->GetCreationTime();
if(timeF < 0.0) { timeF = 0.0; }
news->SetTime(time + timeF);
if(theDef == electron) {
news->SetCreatorModelID(icID);
} else {
news->SetCreatorModelID(secID);
}
news->SetCreatorModelID(secID);
theParticleChange.AddSecondary(*news);
delete news;
delete f;
@@ -396,7 +396,7 @@ G4PhotonEvaporation::GenerateGamma(G4Fragment* nucleus)
ntrans = level->NumberOfTransitions();
}
}
JP1 = fLevelManager->TwoSpinParity(fIndex);
JP1 = std::abs(fLevelManager->TwoSpinParity(fIndex));
}
}
// if a level has no defined transitions
@@ -500,7 +500,7 @@ G4PhotonEvaporation::GenerateGamma(G4Fragment* nucleus)
}
if(fVerbose > 2) {
G4cout << "Ntrans= " << ntrans << " idx= " << idx
<< " ICM= " << fICM << " JP1= " << JP1 << G4endl;
<< " ICM= " << fICM << " abs(JP1)= " << JP1 << G4endl;
}
G4double prob = level->GammaProbability(idx);
// prob = 0 means that there is only internal conversion
@@ -518,7 +518,7 @@ G4PhotonEvaporation::GenerateGamma(G4Fragment* nucleus)
ratio = level->MultipolarityRatio(idx);
multiP = level->TransitionType(idx);
fIndex = level->FinalExcitationIndex(idx);
JP2 = fLevelManager->TwoSpinParity(fIndex);
JP2 = std::abs(fLevelManager->TwoSpinParity(fIndex));
// final energy and time
efinal = fLevelManager->LevelEnergy(fIndex);
@@ -561,7 +561,7 @@ G4PhotonEvaporation::GenerateGamma(G4Fragment* nucleus)
<< " idxFinal= " << fIndex << " isDiscrete: " << isDiscrete
<< " isGamma: " << isGamma << " multiP= " << multiP
<< " shell= " << vShellNumber
<< " JP1= " << JP1 << " JP2= " << JP2 << G4endl;
<< " abs(JP1)= " << JP1 << " abs(JP2)= " << JP2 << G4endl;
}
return result;
}
@@ -40,25 +40,31 @@ class G4CameronGilbertPairingCorrections
{
public:
explicit G4CameronGilbertPairingCorrections();
G4CameronGilbertPairingCorrections();
inline G4bool GetPairingCorrection(G4int N, G4int Z, G4double& result) const
~G4CameronGilbertPairingCorrections() = default;
G4bool GetPairingCorrection(G4int N, G4int Z, G4double& result) const
{
G4bool res = false;
if(Z >= ZTableMin && Z <= ZTableMax && N >= NTableMin && N <= NTableMax) {
result = PairingZTable[Z-ZTableMin] + PairingNTable[N-NTableMin];
if (Z >= TableMin && Z <= ZTableMax && N >= TableMin && N <= NTableMax) {
result = PairingZTable[Z - TableMin] + PairingNTable[N - TableMin];
res = true;
}
return res;
}
enum { ZTableSize = 88, NTableSize = 140, ZTableMin = 11, ZTableMax = 98,
NTableMin = 11, NTableMax = 150 };
G4CameronGilbertPairingCorrections(const G4CameronGilbertPairingCorrections& right) = delete;
const G4CameronGilbertPairingCorrections& operator=
(const G4CameronGilbertPairingCorrections& right) = delete;
private:
G4CameronGilbertPairingCorrections(const G4CameronGilbertPairingCorrections & right) = delete;
const G4CameronGilbertPairingCorrections & operator=(const G4CameronGilbertPairingCorrections & right) = delete;
const G4int TableMin{11};
const G4int ZTableMax{98};
const G4int NTableMax{150};
static const G4int ZTableSize{88};
static const G4int NTableSize{140};
static G4double PairingZTable[ZTableSize];
static G4double PairingNTable[NTableSize];
@@ -43,18 +43,15 @@ public:
~G4CameronGilbertShellCorrections() = default;
inline G4bool GetShellCorrection(G4int N, G4int Z, G4double& result) const
G4bool GetShellCorrection(G4int N, G4int Z, G4double& result) const
{
G4bool res = false;
if(Z >= ZTableMin && Z <= ZTableMax && N >= NTableMin && N <= NTableMax) {
result = ShellZTable[Z-ZTableMin] + ShellNTable[N-NTableMin];
if (Z >= TableMin && Z <= ZTableMax && N >= TableMin && N <= NTableMax) {
result = ShellZTable[Z - TableMin] + ShellNTable[N - TableMin];
res = true;
}
return res;
}
enum { ZTableSize = 88, NTableSize = 140, ZTableMin = 11, ZTableMax = 98,
NTableMin = 11, NTableMax = 150 };
G4CameronGilbertShellCorrections(const G4CameronGilbertShellCorrections & right) = delete;
const G4CameronGilbertShellCorrections & operator=
@@ -62,6 +59,13 @@ public:
private:
const G4int TableMin{11};
const G4int ZTableMax{98};
const G4int NTableMax{150};
static const G4int ZTableSize{88};
static const G4int NTableSize{140};
static G4double ShellZTable[ZTableSize];
static G4double ShellNTable[NTableSize];
@@ -32,7 +32,6 @@
#ifndef G4CoulombBarrier_h
#define G4CoulombBarrier_h 1
#include "globals.hh"
#include "G4VCoulombBarrier.hh"
class G4CoulombBarrier : public G4VCoulombBarrier
@@ -36,14 +36,12 @@
#include "globals.hh"
#include "G4CameronGilbertPairingCorrections.hh"
#include "G4CameronGilbertShellCorrections.hh"
#include "G4CameronShellPlusPairingCorrections.hh"
class G4PairingCorrection
{
public:
explicit G4PairingCorrection();
G4PairingCorrection();
~G4PairingCorrection() = default;
@@ -58,8 +56,6 @@ public:
private:
G4CameronGilbertPairingCorrections theCameronGilbertPairingCorrections;
G4CameronGilbertShellCorrections theCameronGilbertShellCorrections;
G4CameronShellPlusPairingCorrections theCorr;
};
#endif
@@ -33,8 +33,6 @@
#include "globals.hh"
class G4Pow;
class G4VCoulombBarrier
{
public:
@@ -54,14 +52,11 @@ public:
protected:
G4Pow* g4calc;
G4int theA;
G4int theZ;
G4double theR0;
G4double theRho = 0.0;
G4double factor = 0.0;
G4double theRho{0.0};
G4double factor{0.0};
};
#endif
@@ -70,8 +70,8 @@ G4double G4CameronGilbertPairingCorrections::PairingNTable[] =
G4CameronGilbertPairingCorrections::G4CameronGilbertPairingCorrections()
{
for(size_t i=0; i<ZTableSize; ++i) { PairingZTable[i] *= CLHEP::MeV; }
for(size_t i=0; i<NTableSize; ++i) { PairingNTable[i] *= CLHEP::MeV; }
for (G4int i=0; i<ZTableSize; ++i) { PairingZTable[i] *= CLHEP::MeV; }
for (G4int i=0; i<NTableSize; ++i) { PairingNTable[i] *= CLHEP::MeV; }
}
@@ -70,8 +70,8 @@ G4double G4CameronGilbertShellCorrections::ShellNTable[] =
G4CameronGilbertShellCorrections::G4CameronGilbertShellCorrections()
{
for(size_t i=0; i<ZTableSize; ++i) { ShellZTable[i] *= CLHEP::MeV; }
for(size_t i=0; i<NTableSize; ++i) { ShellNTable[i] *= CLHEP::MeV; }
for (G4int i=0; i<ZTableSize; ++i) { ShellZTable[i] *= CLHEP::MeV; }
for (G4int i=0; i<NTableSize; ++i) { ShellNTable[i] *= CLHEP::MeV; }
}
@@ -39,15 +39,15 @@ 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);
SetParameters(0.6*G4NuclearRadii::RadiusCB(Z, A), 1.5*CLHEP::fermi);
}
G4double G4CoulombBarrier::GetCoulombBarrier(
G4int ARes, G4int ZRes, G4double U) const
{
if(0 == theZ) { return 0.0; }
if (0 == theZ) { return 0.0; }
G4double cb = factor*ZRes/(G4NuclearRadii::RadiusCB(ZRes,ARes) + theRho);
if(U > 0.0) { cb /= (1.0 + std::sqrt( U/((2*ARes)*CLHEP::MeV) )); }
if (U > 0.0) { cb /= (1.0 + std::sqrt( U/((2*(ARes + theA))*CLHEP::MeV) )); }
return cb;
}
@@ -33,7 +33,10 @@
#include "G4PairingCorrection.hh"
#include "G4SystemOfUnits.hh"
const G4double PairingConstant = 12.0*CLHEP::MeV;
namespace
{
const G4double PairingConstant = 12.0*CLHEP::MeV;
}
G4PairingCorrection::G4PairingCorrection()
{}
@@ -43,20 +46,18 @@ G4double G4PairingCorrection::GetPairingCorrection(G4int A, G4int Z) const
G4double pairCorr = 0.0;
G4int N = A - Z;
if(!theCameronGilbertPairingCorrections.GetPairingCorrection(N,Z,pairCorr)) {
pairCorr = ((1 - Z + 2*(Z/2)) + (1 - N + 2*(N/2)))
if (!theCameronGilbertPairingCorrections.GetPairingCorrection(N, Z, pairCorr) ) {
pairCorr = (2 - A + 2*(Z/2) + 2*(N/2))
*PairingConstant/std::sqrt(static_cast<G4double>(A));
}
//theCorr.GetPairingCorrection(N,Z,pairCorr);
return std::max(pairCorr, 0.0);
return pairCorr;
}
G4double
G4PairingCorrection::GetFissionPairingCorrection(G4int A, G4int Z) const
{
G4int N = A - Z;
G4double pairCorr = ((1 - Z + 2*(Z/2)) + (1 - N + 2*(N/2)))
G4double pairCorr = (2 - A + 2*(Z/2) + 2*(N/2))
*PairingConstant/std::sqrt(static_cast<G4double>(A));
return pairCorr;
}
@@ -29,20 +29,16 @@
#include "G4VCoulombBarrier.hh"
#include "G4PhysicalConstants.hh"
#include "G4Pow.hh"
G4VCoulombBarrier::G4VCoulombBarrier(G4int anA, G4int aZ)
: g4calc(G4Pow::GetInstance())
{
theA = anA;
theZ = aZ;
theR0 = 1.5*CLHEP::fermi;
}
void G4VCoulombBarrier::SetParameters(G4double rho, G4double r0)
void G4VCoulombBarrier::SetParameters(G4double rho, G4double)
{
theRho = rho;
theR0 = r0;
}
G4double G4VCoulombBarrier::BarrierPenetrationFactor(G4int) const
@@ -6,6 +6,9 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2024-02-12 Gabriele Cosmo (hadr-fission-V11-02-00)
- G4FissLib: fixed compilation warning on gcc when LTO settings are enabled.
## 2022-11-26 Gabriele Cosmo (hadr-fission-V11-00-03)
- Fixed compilation warnings for implicit type conversions on macOS/XCode 14.1.
@@ -146,7 +146,7 @@ class G4FissLib : public G4HadronicInteraction
G4double* xSec;
G4ParticleHPChannel* theFission;
G4String dirName;
G4int numEle;
std::size_t numEle;
};
#endif
@@ -73,12 +73,11 @@ G4FissLib::G4FissLib()
dirName = G4FindDataDir("G4NEUTRONHPDATA");
G4String tString = "/Fission/";
dirName = dirName + tString;
numEle = (G4int)G4Element::GetNumberOfElements();
numEle = G4Element::GetNumberOfElements();
theFission = new G4ParticleHPChannel[numEle];
for (G4int i=0; i<numEle; ++i)
for (std::size_t i=0; i<numEle; ++i)
{
// G4cout << "G4FissLib::G4FissLib(): element "<< i << " : " << (*(G4Element::GetElementTable()))[i]->GetZ()<< G4endl;
if((*(G4Element::GetElementTable()))[i]->GetZ()>89)
{
theFission[i].Init((*(G4Element::GetElementTable()))[i], dirName);
@@ -6,7 +6,7 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2024-04-12 Jean-Christophe David (hadr-inclxx-V11-01-05)
## 2024-04-12 Jean-Christophe David (hadr-inclxx-V11-02-00)
- Fix in G4INCLInteractionAvatar to not use local energy for all antibaryons.
## 2023-12-01 Ben Morgan (hadr-inclxx-V11-01-04)
@@ -6,21 +6,21 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2024-05-02 Gabriele Cosmo (hadr-lend-V11-01-04)
## 2024-05-02 Gabriele Cosmo (hadr-lend-V11-02-03)
- Fixed compilation warnings for potentially initialised local variables in
ptwXY_createFromFunctionZeroCrossing().
## 2024-04-24 Pere Mato
## 2024-04-24 Pere Mato (hadr-lend-V11-02-02)
- Math macros such as M_PI are not standard. To define them the macro
_USE_MATH_DEFINES needs to be defined before including <cmath>.
- macro WIN32 is not standard, the correect macro is _WIN32.
- <BaseTsd.h> should be <basetsd.h> for MinGW.
## 2024-01-29 Vladimir Ivanchenko (hadr-lend-V11-01-03)
## 2024-01-29 Vladimir Ivanchenko (hadr-lend-V11-02-01)
- MCGIDI_product, MCGIDI_outputChannel, MCGIDI_distribution - fixed alma9-gcc131
compilation warnings seen in CMSSW
compilation warnings seen in CMSSW.
## 2023-12-18 Gabriele Cosmo
## 2023-12-18 Gabriele Cosmo (hadr-lend-V11-02-00)
- Fixed compilation error on latest Windows VC++ compiler 17.8.3 for use of
std::isfinite() in nf_specialFunctions_h and in nf_floatToShortestString().
Addressing problem report #2582.
@@ -6,6 +6,9 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2024-02-01 Vladimir Ivanchenko (hadr-lepnuc-V11-02-00)
- Fixed Coverity warning on unused variable in neutrino models
## 2023-09-04 Vladimir Ivanchenko (hadr-lepnuc-V11-01-00)
- G4ElectroVDNuclearModel : updated initialisation of data tables
@@ -425,15 +425,13 @@ G4HadFinalState* G4ANuElNucleusCcModel::ApplyYourself(
}
*/
G4Nucleus recoil;
G4double rM(0.), ratio = G4double(Z)/G4double(A);
G4double ratio = G4double(Z)/G4double(A);
if( ratio > G4UniformRand() ) // proton is excited
{
fProton = true;
recoil = G4Nucleus(A-1,Z-1);
fRecoil = &recoil;
rM = recoil.AtomicMass(A-1,Z-1);
if( pName == "anti_nu_e" ) // (++) state -> p + pi+
{
fMt = G4ParticleTable::GetParticleTable()->FindParticle(2212)->GetPDGMass()
@@ -450,8 +448,6 @@ G4HadFinalState* G4ANuElNucleusCcModel::ApplyYourself(
fProton = false;
recoil = G4Nucleus(A-1,Z);
fRecoil = &recoil;
rM = recoil.AtomicMass(A-1,Z);
if( pName == "anti_nu_e" ) // (+) state -> n + pi+
{
fMt = G4ParticleTable::GetParticleTable()->FindParticle(2112)->GetPDGMass()
@@ -479,6 +475,7 @@ G4HadFinalState* G4ANuElNucleusCcModel::ApplyYourself(
{
fString = false;
G4double rM;
if( fProton )
{
fPDGencoding = 2212;
@@ -383,15 +383,13 @@ G4HadFinalState* G4ANuElNucleusNcModel::ApplyYourself(
return &theParticleChange;
}
G4Nucleus recoil;
G4double rM(0.), ratio = G4double(Z)/G4double(A);
G4double ratio = G4double(Z)/G4double(A);
if( ratio > G4UniformRand() ) // proton is excited
{
fProton = true;
recoil = G4Nucleus(A-1,Z-1);
fRecoil = &recoil;
rM = recoil.AtomicMass(A-1,Z-1);
fMt = G4ParticleTable::GetParticleTable()->FindParticle(2212)->GetPDGMass()
+ G4ParticleTable::GetParticleTable()->FindParticle(111)->GetPDGMass();
}
@@ -400,8 +398,6 @@ G4HadFinalState* G4ANuElNucleusNcModel::ApplyYourself(
fProton = false;
recoil = G4Nucleus(A-1,Z);
fRecoil = &recoil;
rM = recoil.AtomicMass(A-1,Z);
fMt = G4ParticleTable::GetParticleTable()->FindParticle(2112)->GetPDGMass()
+ G4ParticleTable::GetParticleTable()->FindParticle(111)->GetPDGMass();
}
@@ -419,6 +415,7 @@ G4HadFinalState* G4ANuElNucleusNcModel::ApplyYourself(
{
fString = false;
G4double rM;
if( fProton )
{
fPDGencoding = 2212;
@@ -422,15 +422,13 @@ G4HadFinalState* G4ANuMuNucleusCcModel::ApplyYourself(
}
*/
G4Nucleus recoil;
G4double rM(0.), ratio = G4double(Z)/G4double(A);
G4double ratio = G4double(Z)/G4double(A);
if( ratio > G4UniformRand() ) // proton is excited
{
fProton = true;
recoil = G4Nucleus(A-1,Z-1);
fRecoil = &recoil;
rM = recoil.AtomicMass(A-1,Z-1);
if( pName == "anti_nu_mu" ) // (0) state -> p + pi-
{
fMt = G4ParticleTable::GetParticleTable()->FindParticle(2212)->GetPDGMass()
@@ -447,8 +445,6 @@ G4HadFinalState* G4ANuMuNucleusCcModel::ApplyYourself(
fProton = false;
recoil = G4Nucleus(A-1,Z);
fRecoil = &recoil;
rM = recoil.AtomicMass(A-1,Z);
if( pName == "anti_nu_mu" ) // (+) state -> n + pi+
{
fMt = G4ParticleTable::GetParticleTable()->FindParticle(2112)->GetPDGMass()
@@ -476,6 +472,7 @@ G4HadFinalState* G4ANuMuNucleusCcModel::ApplyYourself(
{
fString = false;
G4double rM;
if( fProton )
{
fPDGencoding = 2212;

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