Import Geant4 10.6.0 source tree
This commit is contained in:
@@ -23,6 +23,7 @@ CPPFLAGS += -I$(G4BASE)/global/management/include \
|
||||
-I$(G4BASE)/particles/hadrons/mesons/include \
|
||||
-I$(G4BASE)/particles/hadrons/barions/include \
|
||||
-I$(G4BASE)/particles/hadrons/ions/include \
|
||||
-I$(G4BASE)/processes/cuts/include \
|
||||
-I$(G4BASE)/processes/management/include \
|
||||
-I$(G4BASE)/processes/hadronic/models/management/include/ \
|
||||
-I$(G4BASE)/processes/hadronic/util/include \
|
||||
|
||||
@@ -14,6 +14,79 @@ code and to keep track of all tags.
|
||||
* Please list in reverse chronological order (last date on top)
|
||||
---------------------------------------------------------------
|
||||
|
||||
19 November 2019 - G. Folger (hadr-cross-V10-05-31)
|
||||
- remove using namespace std and using namespace CLHEP from header file G4NeutronElectronElXsc.hh
|
||||
|
||||
07 November 2019 - Alberto Ribon (hadr-cross-V10-05-30)
|
||||
- G4HadronNucleonXsc : set protection against division by zero by introducing
|
||||
a minimum energy cutoff (100 keV), below which the cross section is
|
||||
considered constant.
|
||||
|
||||
06 November 2019 - Vladimir Ivanchenko (hadr-cross-V10-05-29)
|
||||
- G4NeutronInelasticXS, G4ParticleInelasticXS, G4NeutronElasticXS,
|
||||
G4NeutronCaptureXS, G4ComponentSAIDTotalXS, G4CrossSectionDataStore
|
||||
getenv -> std::getenv
|
||||
|
||||
10 October 2019 - Vladimir Ivanchenko (hadr-cross-V10-05-28)
|
||||
- G4BGGPionInelasticXS, G4BGGPionElasticXS - clean-up pi+ x-section
|
||||
below 20 MeV
|
||||
|
||||
27 September 2019 - Vladimir Ivanchenko (hadr-cross-V10-05-27)
|
||||
- G4BGGNucleonInelasticXS, G4BGGNucleonElasticXS,
|
||||
G4BGGPionInelasticXS, G4BGGPionElasticXS - clean-up low-energy
|
||||
- G4UPiNuclearCrossSection - below 20 MeV cross section is now
|
||||
const, BGGPion cross section inplement low-energy part
|
||||
|
||||
16 September 2019 - V. Grichine (hadr-cross-V10-05-26)
|
||||
- G4HadronNucleonXsc.hh/cc - new interface to G4ComponentGGHadronNucleonXsc
|
||||
including s-,c-,b-, particles
|
||||
|
||||
27 August 2019 - Vladimir Ivanchenko (hadr-cross-V10-05-25)
|
||||
- G4BGGNucleonInelasticXS, G4BGGNucleonElasticXS - use coherent
|
||||
low-energy threshold 14 MeV; code clean-up
|
||||
- G4BGGPionInelasticXS, G4BGGPionElasticXS,
|
||||
G4ComponentBarNucleonNucleusXsc - cosmetic clean-up
|
||||
|
||||
23 August 2019 - Vladimir Ivanchenko (hadr-cross-V10-05-24)
|
||||
- G4BGGPionInelasticXS, G4BGGPionElasticXS - use coherent low-energy
|
||||
limit 1 MeV
|
||||
- G4BGGNucleonInelasticXS, G4BGGNucleonElasticXS - minor clean-up
|
||||
- G4UPiNuclearCrossSection - cleaned-up and optimise interpolation
|
||||
method, moved two run time methods to inline, improve low-energy
|
||||
parameterisation
|
||||
|
||||
19 August 2019 - Vladimir Ivanchenko (hadr-cross-V10-05-23)
|
||||
- G4HadronNucleonXsc - fixed K+p and K+n parameterisations (NS and VG)
|
||||
|
||||
07 August 2019 - Vladimir Ivanchenko (hadr-cross-V10-05-22)
|
||||
- G4NeutronInelasticXS, G4ParticleInelasticXS, G4NeutronElasticXS - added
|
||||
special method for tritium and He3 targets (fixed problem #2162),
|
||||
upload data only for elements used in geometry, code clean-up, use C++11
|
||||
- G4NeutronElasticXS - implemented isotope cross section
|
||||
- G4NeutronCaptureXS - code clean-up, use C++11
|
||||
|
||||
25 July 2019 - Vladimir Ivanchenko (hadr-cross-V10-05-21)
|
||||
- G4NeutronCaptureXS - upload data only for elements used in geometry
|
||||
|
||||
21 July 2019 - Mihaly Novak (hadr-cross-V10-05-20)
|
||||
- G4ParticleInelasticXS - use the new, optimised log-vector access method
|
||||
|
||||
17 July 2019 - Mihaly Novak (hadr-cross-V10-05-19)
|
||||
- G4NeutronElasticXS, G4NeutronInelasticXS, G4NeutronCaptureXS - utilise the new
|
||||
G4PhysicsVector::LogVectorValue optimised (for log-vector) method
|
||||
|
||||
13 July 2019 - Vladimir Ivanchenko (hadr-cross-V10-05-18)
|
||||
- G4NeutronCaptureXS - restore computation of isotope x-section as
|
||||
it was in 10.5
|
||||
|
||||
28 June 2019 - Vladimir Ivanchenko (hadr-cross-V10-05-17)
|
||||
- G4BGGNucleonElasticXS, G4BGGNucleonInelasticXS - fixed initialisation
|
||||
for protons and neutrons by usage of separate vectors of correction
|
||||
coeffitients
|
||||
- G4BGGPionInelasticXS - fixed low-energy parameterisation (restore
|
||||
one from Geant4 10.5, where low-energy limits were different for
|
||||
pi+ and pi-)
|
||||
|
||||
12 June 2019 - Vladimir Ivanchenko (hadr-cross-V10-05-16)
|
||||
- G4BGGPionElasticXS, G4BGGPionInelasticXS - fixed initialisation for
|
||||
pi+- by usage of separate vectors of correction factors; fixed
|
||||
|
||||
@@ -97,11 +97,12 @@ private:
|
||||
G4double fGlauberEnergy;
|
||||
G4double fLowEnergy;
|
||||
|
||||
static G4double theGlauberFac[93];
|
||||
static G4double theCoulombFac[93];
|
||||
static G4double theGlauberFacP[93];
|
||||
static G4double theCoulombFacP[93];
|
||||
static G4double theGlauberFacN[93];
|
||||
static G4double theCoulombFacN[93];
|
||||
static G4int theA[93];
|
||||
|
||||
const G4ParticleDefinition* particle;
|
||||
const G4ParticleDefinition* theProton;
|
||||
G4ComponentGGHadronNucleusXsc* fGlauber;
|
||||
G4NucleonNuclearCrossSection* fNucleon;
|
||||
|
||||
@@ -96,13 +96,13 @@ private:
|
||||
|
||||
G4double fGlauberEnergy;
|
||||
G4double fLowEnergy;
|
||||
G4double fHighEnergy;
|
||||
|
||||
static G4double theGlauberFac[93];
|
||||
static G4double theCoulombFac[93];
|
||||
static G4double theGlauberFacP[93];
|
||||
static G4double theCoulombFacP[93];
|
||||
static G4double theGlauberFacN[93];
|
||||
static G4double theCoulombFacN[93];
|
||||
static G4int theA[93];
|
||||
|
||||
const G4ParticleDefinition* particle;
|
||||
const G4ParticleDefinition* theProton;
|
||||
|
||||
G4ComponentGGHadronNucleusXsc* fGlauber;
|
||||
|
||||
@@ -59,6 +59,7 @@ class G4HadronNucleonXsc;
|
||||
class G4Material;
|
||||
class G4Element;
|
||||
class G4Isotope;
|
||||
class G4Pow;
|
||||
|
||||
class G4BGGPionElasticXS : public G4VCrossSectionDataSet
|
||||
{
|
||||
@@ -89,11 +90,16 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
G4double CoulombFactorPiPlus(G4double kinEnergy, G4int Z);
|
||||
|
||||
G4double FactorPiMinus(G4double kinEnergy);
|
||||
|
||||
G4BGGPionElasticXS & operator=(const G4BGGPionElasticXS &right);
|
||||
G4BGGPionElasticXS(const G4BGGPionElasticXS&);
|
||||
|
||||
G4double fGlauberEnergy;
|
||||
G4double fLowEnergy;
|
||||
G4double fLowestEnergy;
|
||||
|
||||
static G4double theGlauberFacPiPlus[93];
|
||||
static G4double theCoulombFacPiPlus[93];
|
||||
@@ -101,8 +107,11 @@ private:
|
||||
static G4double theCoulombFacPiMinus[93];
|
||||
static G4int theA[93];
|
||||
|
||||
const G4ParticleDefinition* particle;
|
||||
const G4ParticleDefinition* theProton;
|
||||
const G4ParticleDefinition* thePiPlus;
|
||||
|
||||
G4Pow* fG4pow;
|
||||
|
||||
G4ComponentGGHadronNucleusXsc* fGlauber;
|
||||
G4UPiNuclearCrossSection* fPion;
|
||||
G4HadronNucleonXsc* fHadron;
|
||||
|
||||
@@ -91,13 +91,16 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
G4double CoulombFactor(G4double kinEnergy, G4int Z);
|
||||
G4double CoulombFactorPiPlus(G4double kinEnergy, G4int Z);
|
||||
|
||||
G4double FactorPiMinus(G4double kinEnergy);
|
||||
|
||||
G4BGGPionInelasticXS & operator=(const G4BGGPionInelasticXS &right);
|
||||
G4BGGPionInelasticXS(const G4BGGPionInelasticXS&);
|
||||
|
||||
G4double fGlauberEnergy;
|
||||
G4double fLowEnergy;
|
||||
G4double fGlauberEnergy;
|
||||
G4double fLowEnergy;
|
||||
G4double fLowestEnergy;
|
||||
|
||||
static G4double theGlauberFacPiPlus[93];
|
||||
static G4double theGlauberFacPiMinus[93];
|
||||
@@ -105,8 +108,8 @@ private:
|
||||
static G4double theLowEPiMinus[93];
|
||||
static G4int theA[93];
|
||||
|
||||
const G4ParticleDefinition* particle;
|
||||
const G4ParticleDefinition* theProton;
|
||||
const G4ParticleDefinition* thePiPlus;
|
||||
|
||||
G4Pow* fG4pow;
|
||||
|
||||
|
||||
@@ -55,6 +55,10 @@ public:
|
||||
~G4HadronNucleonXsc ();
|
||||
|
||||
// Xsc parametrisations return total x-section
|
||||
|
||||
G4double HadronNucleonXsc(const G4ParticleDefinition* theParticle,
|
||||
const G4ParticleDefinition* nucleon, G4double ekin);
|
||||
|
||||
G4double HadronNucleonXscPDG(const G4ParticleDefinition* theParticle,
|
||||
const G4ParticleDefinition* nucleon, G4double ekin);
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class header file
|
||||
@@ -91,7 +90,13 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
void Initialise(G4int Z, const char*);
|
||||
void Initialise(G4int Z);
|
||||
|
||||
void InitialiseOnFly(G4int Z);
|
||||
|
||||
const G4String& FindDirectoryPath();
|
||||
|
||||
const G4PhysicsVector* GetPhysicsVector(G4int Z);
|
||||
|
||||
G4PhysicsVector* RetrieveVector(std::ostringstream& in, G4bool warn);
|
||||
|
||||
@@ -104,14 +109,14 @@ private:
|
||||
G4double elimit;
|
||||
G4double logElimit;
|
||||
|
||||
size_t fIdxXSTable;
|
||||
std::vector<G4double> temp;
|
||||
|
||||
G4bool isMaster;
|
||||
|
||||
static G4ElementData* data;
|
||||
std::vector<G4double> temp;
|
||||
|
||||
static const G4int amin[MAXZCAPTURE];
|
||||
static const G4int amax[MAXZCAPTURE];
|
||||
static G4String gDataDirectory;
|
||||
|
||||
#ifdef G4MULTITHREADED
|
||||
static G4Mutex neutronCaptureXSMutex;
|
||||
|
||||
@@ -46,7 +46,6 @@
|
||||
#include "globals.hh"
|
||||
#include "G4Threading.hh"
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
const G4int MAXZEL = 93;
|
||||
|
||||
@@ -70,16 +69,35 @@ public:
|
||||
G4bool IsElementApplicable(const G4DynamicParticle*,
|
||||
G4int Z, const G4Material*) final;
|
||||
|
||||
G4bool IsIsoApplicable(const G4DynamicParticle*, G4int Z, G4int A,
|
||||
const G4Element*, const G4Material*) final;
|
||||
|
||||
G4double GetElementCrossSection(const G4DynamicParticle*,
|
||||
G4int Z, const G4Material*) final;
|
||||
|
||||
G4double GetIsoCrossSection(const G4DynamicParticle*, G4int Z, G4int A,
|
||||
const G4Isotope* iso,
|
||||
const G4Element* elm,
|
||||
const G4Material* mat) final;
|
||||
|
||||
const G4Isotope* SelectIsotope(const G4Element*,
|
||||
G4double kinEnergy, G4double logE) final;
|
||||
|
||||
void BuildPhysicsTable(const G4ParticleDefinition&) final;
|
||||
|
||||
void CrossSectionDescription(std::ostream&) const final;
|
||||
|
||||
G4double IsoCrossSection(G4double ekin, G4double logE, G4int Z, G4int A);
|
||||
|
||||
private:
|
||||
|
||||
void Initialise(G4int Z, const char*);
|
||||
void Initialise(G4int Z);
|
||||
|
||||
void InitialiseOnFly(G4int Z);
|
||||
|
||||
const G4String& FindDirectoryPath();
|
||||
|
||||
G4PhysicsVector* GetPhysicsVector(G4int Z);
|
||||
|
||||
G4NeutronElasticXS & operator=(const G4NeutronElasticXS &right);
|
||||
G4NeutronElasticXS(const G4NeutronElasticXS&);
|
||||
@@ -88,10 +106,13 @@ private:
|
||||
G4ComponentGGHadronNucleusXsc* ggXsection;
|
||||
const G4ParticleDefinition* neutron;
|
||||
|
||||
std::vector<G4double> temp;
|
||||
|
||||
static G4PhysicsVector* data[MAXZEL];
|
||||
static G4double coeff[MAXZEL];
|
||||
static G4double aeff[MAXZEL];
|
||||
static G4String gDataDirectory;
|
||||
|
||||
size_t fIdxXSTable;
|
||||
G4bool isMaster;
|
||||
|
||||
#ifdef G4MULTITHREADED
|
||||
|
||||
@@ -38,9 +38,6 @@
|
||||
#include "G4VCrossSectionDataSet.hh"
|
||||
#include "G4DynamicParticle.hh"
|
||||
|
||||
using namespace std;
|
||||
using namespace CLHEP;
|
||||
|
||||
// class G4ParticleDefinition;
|
||||
class G4PhysicsLogVector;
|
||||
class G4PhysicsTable;
|
||||
@@ -119,10 +116,10 @@ GetElementNonRelXsc(const G4DynamicParticle* aPart, G4int ZZ,
|
||||
G4double result(0.), te(0.), momentum(0.);
|
||||
|
||||
te = aPart->GetKineticEnergy()*fme/fM;
|
||||
momentum = sqrt( te*(te + 2.*fme) );
|
||||
momentum = std::sqrt( te*(te + 2.*fme) );
|
||||
fAm = CalculateAm(momentum);
|
||||
|
||||
result = 1. + log(1. +1./fAm);
|
||||
result = 1. + std::log(1. +1./fAm);
|
||||
result *= fCofXsc; //*energy;
|
||||
result *= ZZ; // incoherent sum over all element electrons
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class header file
|
||||
@@ -47,7 +46,6 @@
|
||||
#include "G4ElementData.hh"
|
||||
#include "G4Threading.hh"
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
const G4int MAXZINEL = 93;
|
||||
|
||||
@@ -75,8 +73,7 @@ public:
|
||||
const G4Element*, const G4Material*) final;
|
||||
|
||||
G4double GetElementCrossSection(const G4DynamicParticle*,
|
||||
G4int Z,
|
||||
const G4Material* mat=nullptr) final;
|
||||
G4int Z, const G4Material*) final;
|
||||
|
||||
G4double GetIsoCrossSection(const G4DynamicParticle*, G4int Z, G4int A,
|
||||
const G4Isotope* iso,
|
||||
@@ -92,7 +89,13 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
void Initialise(G4int Z, const char*);
|
||||
void Initialise(G4int Z);
|
||||
|
||||
void InitialiseOnFly(G4int Z);
|
||||
|
||||
const G4String& FindDirectoryPath();
|
||||
|
||||
const G4PhysicsVector* GetPhysicsVector(G4int Z);
|
||||
|
||||
G4PhysicsVector* RetrieveVector(std::ostringstream& in, G4bool warn);
|
||||
|
||||
@@ -106,17 +109,16 @@ private:
|
||||
|
||||
const G4ParticleDefinition* neutron;
|
||||
|
||||
G4double emax;
|
||||
std::vector<G4double> temp;
|
||||
|
||||
size_t fIdxXSTable;
|
||||
G4bool isMaster;
|
||||
|
||||
static G4ElementData* data;
|
||||
|
||||
static G4double coeff[MAXZINEL];
|
||||
static G4double aeff[MAXZINEL];
|
||||
static const G4int amin[MAXZINEL];
|
||||
static const G4int amax[MAXZINEL];
|
||||
static G4String gDataDirectory;
|
||||
|
||||
#ifdef G4MULTITHREADED
|
||||
static G4Mutex neutronInelasticXSMutex;
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class header file
|
||||
@@ -92,7 +91,13 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
void Initialise(G4int Z, const char*);
|
||||
void Initialise(G4int Z);
|
||||
|
||||
void InitialiseOnFly(G4int Z);
|
||||
|
||||
const G4String& FindDirectoryPath();
|
||||
|
||||
const G4PhysicsVector* GetPhysicsVector(G4int Z);
|
||||
|
||||
G4PhysicsVector* RetrieveVector(std::ostringstream& in, G4bool warn);
|
||||
|
||||
@@ -106,18 +111,16 @@ private:
|
||||
const G4ParticleDefinition* particle;
|
||||
const G4ParticleDefinition* proton;
|
||||
|
||||
G4double emax;
|
||||
std::vector<G4double> temp;
|
||||
|
||||
size_t fIdxXSTable;
|
||||
G4bool isMaster;
|
||||
|
||||
static G4double coeff[MAXZINELP];
|
||||
|
||||
static G4ElementData* data;
|
||||
static G4double coeff[MAXZINELP];
|
||||
static G4double aeff[MAXZINELP];
|
||||
static const G4int amin[MAXZINELP];
|
||||
static const G4int amax[MAXZINELP];
|
||||
|
||||
static G4ElementData* data;
|
||||
static G4String gDataDirectory;
|
||||
|
||||
#ifdef G4MULTITHREADED
|
||||
static G4Mutex particleInelasticXSMutex;
|
||||
|
||||
@@ -31,12 +31,12 @@
|
||||
// 05.03.07 V.Ivanchenko - add IfZAApplicable
|
||||
//
|
||||
|
||||
|
||||
#ifndef G4UPiNuclearCrossSection_h
|
||||
#define G4UPiNuclearCrossSection_h
|
||||
|
||||
#include "G4VCrossSectionDataSet.hh"
|
||||
#include "G4DynamicParticle.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "globals.hh"
|
||||
#include "G4Threading.hh"
|
||||
|
||||
@@ -53,9 +53,11 @@ public:
|
||||
G4bool IsElementApplicable(const G4DynamicParticle* aParticle,
|
||||
G4int Z, const G4Material*) final;
|
||||
|
||||
inline
|
||||
G4double GetElasticCrossSection(const G4DynamicParticle* aParticle,
|
||||
G4int Z, G4int A) const;
|
||||
|
||||
inline
|
||||
G4double GetInelasticCrossSection(const G4DynamicParticle* aParticle,
|
||||
G4int Z, G4int A) const;
|
||||
|
||||
@@ -67,7 +69,8 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
G4double Interpolate(G4int Z, G4int A, G4double ekin, G4PhysicsTable*) const;
|
||||
G4double Interpolate(G4int Z, G4int A, G4double ekin,
|
||||
const G4PhysicsTable*) const;
|
||||
|
||||
void AddDataSet(const G4String& p, const G4double* tot,
|
||||
const G4double* in, const G4double* e, G4int n);
|
||||
@@ -79,6 +82,7 @@ private:
|
||||
|
||||
static const G4int NZ = 16;
|
||||
static G4int theZ[NZ];
|
||||
static G4int idxZ[93];
|
||||
|
||||
static G4double theA[NZ];
|
||||
static G4double APower[93];
|
||||
@@ -90,7 +94,6 @@ private:
|
||||
|
||||
G4double aPower;
|
||||
G4double elow;
|
||||
G4double elowest;
|
||||
|
||||
G4bool isMaster;
|
||||
|
||||
@@ -99,4 +102,22 @@ private:
|
||||
#endif
|
||||
};
|
||||
|
||||
inline G4double
|
||||
G4UPiNuclearCrossSection::GetElasticCrossSection(
|
||||
const G4DynamicParticle* dp, G4int Z, G4int A) const
|
||||
{
|
||||
const G4PhysicsTable* table =
|
||||
(dp->GetDefinition() == piPlus) ? piPlusElastic : piMinusElastic;
|
||||
return Interpolate(Z, A, dp->GetKineticEnergy(), table);
|
||||
}
|
||||
|
||||
inline G4double
|
||||
G4UPiNuclearCrossSection::GetInelasticCrossSection(
|
||||
const G4DynamicParticle* dp, G4int Z, G4int A) const
|
||||
{
|
||||
const G4PhysicsTable* table =
|
||||
(dp->GetDefinition() == piPlus) ? piPlusInelastic : piMinusInelastic;
|
||||
return Interpolate(Z, A, dp->GetKineticEnergy(), table);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -30,6 +30,7 @@ include_directories(${CMAKE_SOURCE_DIR}/source/particles/hadrons/ions/include)
|
||||
include_directories(${CMAKE_SOURCE_DIR}/source/particles/hadrons/mesons/include)
|
||||
include_directories(${CMAKE_SOURCE_DIR}/source/particles/leptons/include)
|
||||
include_directories(${CMAKE_SOURCE_DIR}/source/particles/management/include)
|
||||
include_directories(${CMAKE_SOURCE_DIR}/source/processes/cuts/include)
|
||||
include_directories(${CMAKE_SOURCE_DIR}/source/processes/hadronic/models/management/include)
|
||||
include_directories(${CMAKE_SOURCE_DIR}/source/processes/hadronic/models/util/include)
|
||||
include_directories(${CMAKE_SOURCE_DIR}/source/processes/hadronic/util/include)
|
||||
@@ -197,6 +198,7 @@ GEANT4_DEFINE_MODULE(NAME G4hadronic_xsect
|
||||
GRANULAR_DEPENDENCIES
|
||||
G4baryons
|
||||
G4bosons
|
||||
G4cuts
|
||||
G4geometrymng
|
||||
G4globman
|
||||
G4had_mod_man
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class file
|
||||
@@ -43,16 +42,18 @@
|
||||
#include "G4ComponentGGHadronNucleusXsc.hh"
|
||||
#include "G4NucleonNuclearCrossSection.hh"
|
||||
#include "G4HadronNucleonXsc.hh"
|
||||
#include "G4NuclearRadii.hh"
|
||||
#include "G4Proton.hh"
|
||||
#include "G4Neutron.hh"
|
||||
#include "G4NistManager.hh"
|
||||
#include "G4Log.hh"
|
||||
#include "G4Exp.hh"
|
||||
#include "G4NuclearRadii.hh"
|
||||
|
||||
#include "G4CrossSectionDataSetRegistry.hh"
|
||||
|
||||
G4double G4BGGNucleonElasticXS::theGlauberFac[93] = {0.0};
|
||||
G4double G4BGGNucleonElasticXS::theCoulombFac[93] = {0.0};
|
||||
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
|
||||
@@ -64,13 +65,13 @@ G4BGGNucleonElasticXS::G4BGGNucleonElasticXS(const G4ParticleDefinition* p)
|
||||
{
|
||||
verboseLevel = 0;
|
||||
fGlauberEnergy = 91.*GeV;
|
||||
fLowEnergy = 0.75*MeV;
|
||||
fLowEnergy = 14.0*MeV;
|
||||
fNucleon = nullptr;
|
||||
fGlauber = nullptr;
|
||||
fHadron = nullptr;
|
||||
particle = p;
|
||||
|
||||
theProton= G4Proton::Proton();
|
||||
isProton = (theProton == p) ? true : false;
|
||||
isProton = (theProton == p);
|
||||
isMaster = false;
|
||||
SetForAllAtomsAndEnergies(true);
|
||||
}
|
||||
@@ -86,7 +87,7 @@ G4BGGNucleonElasticXS::~G4BGGNucleonElasticXS()
|
||||
|
||||
G4bool
|
||||
G4BGGNucleonElasticXS::IsElementApplicable(const G4DynamicParticle*, G4int,
|
||||
const G4Material*)
|
||||
const G4Material*)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -94,9 +95,9 @@ G4BGGNucleonElasticXS::IsElementApplicable(const G4DynamicParticle*, G4int,
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4bool G4BGGNucleonElasticXS::IsIsoApplicable(const G4DynamicParticle*,
|
||||
G4int Z, G4int,
|
||||
const G4Element*,
|
||||
const G4Material*)
|
||||
G4int Z, G4int,
|
||||
const G4Element*,
|
||||
const G4Material*)
|
||||
{
|
||||
return (1 == Z);
|
||||
}
|
||||
@@ -105,7 +106,7 @@ G4bool G4BGGNucleonElasticXS::IsIsoApplicable(const G4DynamicParticle*,
|
||||
|
||||
G4double
|
||||
G4BGGNucleonElasticXS::GetElementCrossSection(const G4DynamicParticle* dp,
|
||||
G4int ZZ, const G4Material*)
|
||||
G4int ZZ, const G4Material*)
|
||||
{
|
||||
// this method should be called only for Z > 1
|
||||
|
||||
@@ -116,20 +117,22 @@ G4BGGNucleonElasticXS::GetElementCrossSection(const G4DynamicParticle* dp,
|
||||
cross = 1.0115*GetIsoCrossSection(dp,1,1);
|
||||
} else {
|
||||
if(ekin <= fLowEnergy) {
|
||||
cross = theCoulombFac[Z]*CoulombFactor(ekin, Z);
|
||||
cross = (isProton) ? theCoulombFacP[Z] : theCoulombFacN[Z];
|
||||
cross *= CoulombFactor(ekin, Z);
|
||||
} else if(ekin > fGlauberEnergy) {
|
||||
cross = theGlauberFac[Z]*fGlauber->GetElasticGlauberGribov(dp, Z, theA[Z]);
|
||||
cross = (isProton) ? theGlauberFacP[Z] : theGlauberFacN[Z];
|
||||
cross *= fGlauber->GetElasticGlauberGribov(dp, Z, theA[Z]);
|
||||
} else {
|
||||
cross = fNucleon->GetElasticCrossSection(dp, Z);
|
||||
}
|
||||
}
|
||||
if(verboseLevel > 1) {
|
||||
G4cout << "G4BGGNucleonElasticXS::GetElementCrossSection for "
|
||||
<< dp->GetDefinition()->GetParticleName()
|
||||
<< " Ekin(GeV)= " << dp->GetKineticEnergy()/CLHEP::GeV
|
||||
<< " in nucleus Z= " << Z << " A= " << theA[Z]
|
||||
<< " XS(b)= " << cross/barn
|
||||
<< G4endl;
|
||||
<< dp->GetDefinition()->GetParticleName()
|
||||
<< " Ekin(GeV)= " << dp->GetKineticEnergy()/CLHEP::GeV
|
||||
<< " in nucleus Z= " << Z << " A= " << theA[Z]
|
||||
<< " XS(b)= " << cross/barn
|
||||
<< G4endl;
|
||||
}
|
||||
return cross;
|
||||
}
|
||||
@@ -138,23 +141,23 @@ G4BGGNucleonElasticXS::GetElementCrossSection(const G4DynamicParticle* dp,
|
||||
|
||||
G4double
|
||||
G4BGGNucleonElasticXS::GetIsoCrossSection(const G4DynamicParticle* dp,
|
||||
G4int Z, G4int A,
|
||||
const G4Isotope*,
|
||||
const G4Element*,
|
||||
const G4Material*)
|
||||
G4int Z, G4int A,
|
||||
const G4Isotope*,
|
||||
const G4Element*,
|
||||
const G4Material*)
|
||||
{
|
||||
// this method should be called only for Z = 1
|
||||
fHadron->HadronNucleonXscNS(dp->GetDefinition(), theProton,
|
||||
dp->GetKineticEnergy());
|
||||
dp->GetKineticEnergy());
|
||||
G4double cross = A*fHadron->GetElasticHadronNucleonXsc();
|
||||
|
||||
if(verboseLevel > 1) {
|
||||
G4cout << "G4BGGNucleonElasticXS::GetIsoCrossSection for "
|
||||
<< dp->GetDefinition()->GetParticleName()
|
||||
<< " Ekin(GeV)= " << dp->GetKineticEnergy()/CLHEP::GeV
|
||||
<< " in nucleus Z= " << Z << " A= " << A
|
||||
<< " XS(b)= " << cross/barn
|
||||
<< G4endl;
|
||||
<< dp->GetDefinition()->GetParticleName()
|
||||
<< " Ekin(GeV)= " << dp->GetKineticEnergy()/CLHEP::GeV
|
||||
<< " in nucleus Z= " << Z << " A= " << A
|
||||
<< " XS(b)= " << cross/barn
|
||||
<< G4endl;
|
||||
}
|
||||
return cross;
|
||||
}
|
||||
@@ -163,26 +166,24 @@ G4BGGNucleonElasticXS::GetIsoCrossSection(const G4DynamicParticle* dp,
|
||||
|
||||
void G4BGGNucleonElasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
|
||||
{
|
||||
if(fNucleon) { return; }
|
||||
if(&p == theProton || &p == G4Neutron::Neutron()) {
|
||||
particle = &p;
|
||||
isProton = (theProton == particle) ? true : false;
|
||||
isProton = (theProton == &p);
|
||||
|
||||
} else {
|
||||
G4ExceptionDescription ed;
|
||||
ed << "This BGG cross section is applicable only to nucleons and not to "
|
||||
<< p.GetParticleName() << G4endl;
|
||||
G4Exception("G4BGGNucleonElasticXS::BuildPhysicsTable", "had001",
|
||||
FatalException, ed);
|
||||
FatalException, ed);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!fNucleon) {
|
||||
fNucleon = (G4NucleonNuclearCrossSection*)G4CrossSectionDataSetRegistry::Instance()->GetCrossSectionDataSet(G4NucleonNuclearCrossSection::Default_Name());
|
||||
fGlauber = new G4ComponentGGHadronNucleusXsc();
|
||||
fHadron = new G4HadronNucleonXsc();
|
||||
}
|
||||
fNucleon->BuildPhysicsTable(*particle);
|
||||
fGlauber->BuildPhysicsTable(*particle);
|
||||
fNucleon = new G4NucleonNuclearCrossSection();
|
||||
fGlauber = new G4ComponentGGHadronNucleusXsc();
|
||||
fHadron = new G4HadronNucleonXsc();
|
||||
|
||||
fNucleon->BuildPhysicsTable(p);
|
||||
|
||||
if(0 == theA[0]) {
|
||||
#ifdef G4MULTITHREADED
|
||||
@@ -194,45 +195,63 @@ void G4BGGNucleonElasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
|
||||
}
|
||||
G4MUTEXUNLOCK(&nucleonElasticXSMutex);
|
||||
#endif
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if(isMaster && 0 == theA[0]) {
|
||||
|
||||
theA[0] = 1;
|
||||
theA[0] = theA[1] = 1;
|
||||
G4ThreeVector mom(0.0,0.0,1.0);
|
||||
G4DynamicParticle dp(particle, mom, fGlauberEnergy);
|
||||
G4DynamicParticle dp(theProton, mom, fGlauberEnergy);
|
||||
|
||||
G4NistManager* nist = G4NistManager::Instance();
|
||||
G4double csup, csdn;
|
||||
|
||||
if(verboseLevel > 0) {
|
||||
G4cout << "### G4BGGNucleonElasticXS::Initialise for "
|
||||
<< particle->GetParticleName() << G4endl;
|
||||
<< p.GetParticleName() << G4endl;
|
||||
}
|
||||
|
||||
for(G4int iz=2; iz<93; iz++) {
|
||||
|
||||
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;
|
||||
|
||||
theGlauberFac[iz] = csdn/csup;
|
||||
if(verboseLevel > 0) {
|
||||
G4cout << "Z= " << iz << " A= " << A
|
||||
<< " factor= " << theGlauberFac[iz] << G4endl;
|
||||
G4cout << "Z= " << iz << " A= " << theA[iz]
|
||||
<< " GFactorP= " << theGlauberFacP[iz]
|
||||
<< " GFactorN= " << theGlauberFacN[iz] << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
theCoulombFac[0] = theCoulombFac[1] = 1.0;
|
||||
theCoulombFacP[0] = theCoulombFacP[1] =
|
||||
theCoulombFacN[0] = theCoulombFacN[1] = 1.0;
|
||||
dp.SetDefinition(theProton);
|
||||
dp.SetKineticEnergy(fLowEnergy);
|
||||
for(G4int iz=2; iz<93; ++iz) {
|
||||
theCoulombFac[iz] =
|
||||
fNucleon->GetElasticCrossSection(&dp, iz)/CoulombFactor(fLowEnergy, 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]
|
||||
<< " factor= " << theCoulombFac[iz] << G4endl;
|
||||
G4cout << "Z= " << iz << " A= " << theA[iz]
|
||||
<< " CFactorP= " << theCoulombFacP[iz]
|
||||
<< " CFactorN= " << theCoulombFacN[iz] << G4endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -243,26 +262,9 @@ void G4BGGNucleonElasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
|
||||
G4double G4BGGNucleonElasticXS::CoulombFactor(G4double kinEnergy, G4int Z)
|
||||
{
|
||||
G4double res= 1.0;
|
||||
|
||||
// from G4ProtonInelasticCrossSection
|
||||
if(isProton) {
|
||||
|
||||
if (Z <= 1) { return kinEnergy*kinEnergy; }
|
||||
|
||||
static const G4double llog10 = G4Log(10.);
|
||||
G4double elog = G4Log(kinEnergy/GeV)/llog10;
|
||||
G4double aa = theA[Z];
|
||||
|
||||
G4double ff1 = 5.6 - 0.016*aa; // slope of the drop at medium energies.
|
||||
G4double ff2 = 1.37 + 1.37/aa; // start of the slope.
|
||||
G4double ff3 = 0.8 + 18./aa - 0.002*aa; // stephight
|
||||
res = 1.0 + ff3*(1.0 - (1.0/(1+G4Exp(-ff1*(elog + ff2)))));
|
||||
|
||||
ff1 = 8. - 8./aa - 0.008*aa; // slope of the rise
|
||||
ff2 = 2.34 - 5.4/aa - 0.0028*aa; // start of the rise
|
||||
res /= (1.0 + G4Exp(-ff1*(elog + ff2)));
|
||||
|
||||
}
|
||||
res = G4NuclearRadii::CoulombFactor(Z, theA[Z], theProton, kinEnergy);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class file
|
||||
@@ -54,6 +53,7 @@
|
||||
#include "G4Isotope.hh"
|
||||
#include "G4Log.hh"
|
||||
#include "G4Exp.hh"
|
||||
#include "G4NuclearRadii.hh"
|
||||
|
||||
#include "G4CrossSectionDataSetRegistry.hh"
|
||||
|
||||
@@ -61,8 +61,10 @@
|
||||
|
||||
const G4double llog10 = G4Log(10.);
|
||||
|
||||
G4double G4BGGNucleonInelasticXS::theGlauberFac[93] = {0.0};
|
||||
G4double G4BGGNucleonInelasticXS::theCoulombFac[93] = {0.0};
|
||||
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
|
||||
@@ -75,15 +77,13 @@ G4BGGNucleonInelasticXS::G4BGGNucleonInelasticXS(const G4ParticleDefinition* p)
|
||||
verboseLevel = 0;
|
||||
fGlauberEnergy = 91.*GeV;
|
||||
fLowEnergy = 14.*MeV;
|
||||
fHighEnergy = 5.*GeV;
|
||||
|
||||
fNucleon = nullptr;
|
||||
fGlauber = nullptr;
|
||||
fHadron = nullptr;
|
||||
|
||||
particle = p;
|
||||
theProton= G4Proton::Proton();
|
||||
isProton = (theProton == p) ? true : false;
|
||||
isProton = (theProton == p);
|
||||
isMaster = false;
|
||||
SetForAllAtomsAndEnergies(true);
|
||||
}
|
||||
@@ -98,7 +98,7 @@ G4BGGNucleonInelasticXS::~G4BGGNucleonInelasticXS()
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4bool G4BGGNucleonInelasticXS::IsElementApplicable(const G4DynamicParticle*,
|
||||
G4int, const G4Material*)
|
||||
G4int, const G4Material*)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -106,9 +106,9 @@ G4bool G4BGGNucleonInelasticXS::IsElementApplicable(const G4DynamicParticle*,
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4bool G4BGGNucleonInelasticXS::IsIsoApplicable(const G4DynamicParticle*,
|
||||
G4int Z, G4int,
|
||||
const G4Element*,
|
||||
const G4Material*)
|
||||
G4int Z, G4int,
|
||||
const G4Element*,
|
||||
const G4Material*)
|
||||
{
|
||||
return (1 == Z);
|
||||
}
|
||||
@@ -117,24 +117,20 @@ G4bool G4BGGNucleonInelasticXS::IsIsoApplicable(const G4DynamicParticle*,
|
||||
|
||||
G4double
|
||||
G4BGGNucleonInelasticXS::GetElementCrossSection(const G4DynamicParticle* dp,
|
||||
G4int ZZ, const G4Material*)
|
||||
G4int ZZ, const G4Material*)
|
||||
{
|
||||
G4double cross = 0.0;
|
||||
G4double ekin = dp->GetKineticEnergy();
|
||||
G4int Z = std::min(ZZ, 92);
|
||||
if(1 == Z) {
|
||||
cross = 1.0115*GetIsoCrossSection(dp,1,1);
|
||||
} else if(2 == Z) {
|
||||
if(ekin > fGlauberEnergy) {
|
||||
cross = theGlauberFac[Z]*fGlauber->GetInelasticGlauberGribov(dp, Z, theA[Z]);
|
||||
} else {
|
||||
cross = fNucleon->GetElementCrossSection(dp, Z);
|
||||
}
|
||||
} else {
|
||||
if(ekin <= fLowEnergy) {
|
||||
cross = theCoulombFac[Z]*CoulombFactor(ekin, Z);
|
||||
cross = (isProton) ? theCoulombFacP[Z] : theCoulombFacN[Z];
|
||||
cross *= CoulombFactor(ekin, Z);
|
||||
} else if(ekin > fGlauberEnergy) {
|
||||
cross = theGlauberFac[Z]*fGlauber->GetInelasticGlauberGribov(dp, Z, theA[Z]);
|
||||
cross = (isProton) ? theGlauberFacP[Z] : theGlauberFacN[Z];
|
||||
cross *= fGlauber->GetInelasticGlauberGribov(dp, Z, theA[Z]);
|
||||
} else {
|
||||
cross = fNucleon->GetElementCrossSection(dp, Z);
|
||||
}
|
||||
@@ -142,11 +138,11 @@ G4BGGNucleonInelasticXS::GetElementCrossSection(const G4DynamicParticle* dp,
|
||||
|
||||
if(verboseLevel > 1) {
|
||||
G4cout << "G4BGGNucleonInelasticXS::GetCrossSection for "
|
||||
<< dp->GetDefinition()->GetParticleName()
|
||||
<< " Ekin(GeV)= " << dp->GetKineticEnergy()/CLHEP::GeV
|
||||
<< " in nucleus Z= " << Z << " A= " << theA[Z]
|
||||
<< " XS(b)= " << cross/barn
|
||||
<< G4endl;
|
||||
<< dp->GetDefinition()->GetParticleName()
|
||||
<< " Ekin(GeV)= " << dp->GetKineticEnergy()/CLHEP::GeV
|
||||
<< " in nucleus Z= " << Z << " A= " << theA[Z]
|
||||
<< " XS(b)= " << cross/barn
|
||||
<< G4endl;
|
||||
}
|
||||
return cross;
|
||||
}
|
||||
@@ -155,23 +151,23 @@ G4BGGNucleonInelasticXS::GetElementCrossSection(const G4DynamicParticle* dp,
|
||||
|
||||
G4double
|
||||
G4BGGNucleonInelasticXS::GetIsoCrossSection(const G4DynamicParticle* dp,
|
||||
G4int Z, G4int A,
|
||||
const G4Isotope*,
|
||||
const G4Element*,
|
||||
const G4Material*)
|
||||
G4int Z, G4int A,
|
||||
const G4Isotope*,
|
||||
const G4Element*,
|
||||
const G4Material*)
|
||||
{
|
||||
// this method should be called only for Z = 1
|
||||
fHadron->HadronNucleonXscNS(dp->GetDefinition(), theProton,
|
||||
dp->GetKineticEnergy());
|
||||
dp->GetKineticEnergy());
|
||||
G4double cross = A*fHadron->GetInelasticHadronNucleonXsc();
|
||||
|
||||
if(verboseLevel > 1) {
|
||||
G4cout << "G4BGGNucleonInelasticXS::GetIsoCrossSection for "
|
||||
<< dp->GetDefinition()->GetParticleName()
|
||||
<< " Ekin(GeV)= " << dp->GetKineticEnergy()/CLHEP::GeV
|
||||
<< " in nucleus Z= " << Z << " A= " << theA[Z]
|
||||
<< " XS(b)= " << cross/barn
|
||||
<< G4endl;
|
||||
<< dp->GetDefinition()->GetParticleName()
|
||||
<< " Ekin(GeV)= " << dp->GetKineticEnergy()/CLHEP::GeV
|
||||
<< " in nucleus Z= " << Z << " A= " << theA[Z]
|
||||
<< " XS(b)= " << cross/barn
|
||||
<< G4endl;
|
||||
}
|
||||
return cross;
|
||||
}
|
||||
@@ -180,26 +176,23 @@ G4BGGNucleonInelasticXS::GetIsoCrossSection(const G4DynamicParticle* dp,
|
||||
|
||||
void G4BGGNucleonInelasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
|
||||
{
|
||||
if(fNucleon) { return; }
|
||||
if(&p == theProton || &p == G4Neutron::Neutron()) {
|
||||
particle = &p;
|
||||
isProton = (theProton == particle) ? true : false;
|
||||
isProton = (theProton == &p);
|
||||
} else {
|
||||
G4ExceptionDescription ed;
|
||||
ed << "This BGG cross section is applicable only to nucleons and not to "
|
||||
<< p.GetParticleName() << G4endl;
|
||||
G4Exception("G4BGGNucleonInelasticXS::BuildPhysicsTable", "had001",
|
||||
FatalException, ed);
|
||||
FatalException, ed);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!fNucleon) {
|
||||
fNucleon = (G4NucleonNuclearCrossSection*)G4CrossSectionDataSetRegistry::Instance()->GetCrossSectionDataSet(G4NucleonNuclearCrossSection::Default_Name());
|
||||
fGlauber = new G4ComponentGGHadronNucleusXsc();
|
||||
fHadron = new G4HadronNucleonXsc();
|
||||
}
|
||||
fNucleon = new G4NucleonNuclearCrossSection();
|
||||
fGlauber = new G4ComponentGGHadronNucleusXsc();
|
||||
fHadron = new G4HadronNucleonXsc();
|
||||
|
||||
fNucleon->BuildPhysicsTable(*particle);
|
||||
fGlauber->BuildPhysicsTable(*particle);
|
||||
fNucleon->BuildPhysicsTable(p);
|
||||
|
||||
if(0 == theA[0]) {
|
||||
#ifdef G4MULTITHREADED
|
||||
@@ -211,44 +204,61 @@ void G4BGGNucleonInelasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
|
||||
}
|
||||
G4MUTEXUNLOCK(&nucleonInelasticXSMutex);
|
||||
#endif
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if(isMaster && 0 == theA[0]) {
|
||||
|
||||
theA[0] = 1;
|
||||
theA[0] = theA[1] = 1;
|
||||
G4ThreeVector mom(0.0,0.0,1.0);
|
||||
G4DynamicParticle dp(particle, mom, fGlauberEnergy);
|
||||
G4DynamicParticle dp(theProton, mom, fGlauberEnergy);
|
||||
|
||||
G4NistManager* nist = G4NistManager::Instance();
|
||||
G4double csup, csdn;
|
||||
|
||||
if(verboseLevel > 0) {
|
||||
G4cout << "### G4BGGNucleonInelasticXS::Initialise for "
|
||||
<< particle->GetParticleName() << G4endl;
|
||||
<< p.GetParticleName() << G4endl;
|
||||
}
|
||||
for(G4int iz=2; iz<93; iz++) {
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
theGlauberFac[iz] = csdn/csup;
|
||||
if(verboseLevel > 0) {
|
||||
G4cout << "Z= " << iz << " A= " << A
|
||||
<< " GlauberFactor= " << theGlauberFac[iz] << G4endl;
|
||||
G4cout << "Z= " << iz << " A= " << theA[iz]
|
||||
<< " GFactorP= " << theGlauberFacP[iz]
|
||||
<< " GFactorN= " << theGlauberFacN[iz] << G4endl;
|
||||
}
|
||||
}
|
||||
theCoulombFac[1] = 1.0;
|
||||
theCoulombFacP[1] = theCoulombFacN[1] = 1.0;
|
||||
dp.SetDefinition(theProton);
|
||||
dp.SetKineticEnergy(fLowEnergy);
|
||||
for(G4int iz=2; iz<93; ++iz) {
|
||||
theCoulombFac[iz] =
|
||||
fNucleon->GetElementCrossSection(&dp, iz)/CoulombFactor(fLowEnergy, 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]
|
||||
<< " CoulombFactor= " << theCoulombFac[iz] << G4endl;
|
||||
G4cout << "Z= " << iz << " A= " << theA[iz]
|
||||
<< " CFactorP= " << theCoulombFacP[iz]
|
||||
<< " CFactorN= " << theCoulombFacN[iz] << G4endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -258,27 +268,28 @@ void G4BGGNucleonInelasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
|
||||
|
||||
G4double G4BGGNucleonInelasticXS::CoulombFactor(G4double kinEnergy, G4int Z)
|
||||
{
|
||||
G4double res= 0.0;
|
||||
G4double res = 0.0;
|
||||
|
||||
if(kinEnergy <= 0.0) { return res; }
|
||||
else if (Z <= 1) { return kinEnergy*kinEnergy; }
|
||||
|
||||
|
||||
G4double elog = G4Log(kinEnergy/GeV)/llog10;
|
||||
G4double aa = theA[Z];
|
||||
|
||||
if(isProton) {
|
||||
|
||||
// from G4ProtonInelasticCrossSection
|
||||
if(isProton) {
|
||||
|
||||
G4double ff1 = 5.6 - 0.016*aa; // slope of the drop at medium energies.
|
||||
G4double ff2 = 1.37 + 1.37/aa; // start of the slope.
|
||||
G4double ff3 = 0.8 + 18./aa - 0.002*aa; // stephight
|
||||
res = 1.0 + ff3*(1.0 - (1.0/(1+G4Exp(-ff1*(elog + ff2)))));
|
||||
|
||||
ff1 = 8. - 8./aa - 0.008*aa; // slope of the rise
|
||||
ff2 = 2.34 - 5.4/aa - 0.0028*aa; // start of the rise
|
||||
res /= (1.0 + G4Exp(-ff1*(elog + ff2)));
|
||||
res = G4NuclearRadii::CoulombFactor(Z, theA[Z], theProton, kinEnergy);
|
||||
|
||||
// from G4ProtonInelasticCrossSection
|
||||
if(res > 0.0) {
|
||||
G4double ff1 = 5.6 - 0.016*aa; // slope of the drop at medium energies.
|
||||
G4double ff2 = 1.37 + 1.37/aa; // start of the slope.
|
||||
G4double ff3 = 0.8 + 18./aa - 0.002*aa; // stephight
|
||||
res *= (1.0 + ff3*(1.0 - (1.0/(1+G4Exp(-ff1*(elog + ff2))))));
|
||||
ff1 = 8. - 8./aa - 0.008*aa; // slope of the rise
|
||||
ff2 = 2.34 - 5.4/aa - 0.0028*aa; // start of the rise
|
||||
res /= (1.0 + G4Exp(-ff1*(elog + ff2)));
|
||||
}
|
||||
} else {
|
||||
|
||||
// from G4NeutronInelasticCrossSection
|
||||
G4double p3 = 0.6 + 13./aa - 0.0005*aa;
|
||||
G4double p4 = 7.2449 - 0.018242*aa;
|
||||
@@ -290,7 +301,6 @@ G4double G4BGGNucleonInelasticXS::CoulombFactor(G4double kinEnergy, G4int Z)
|
||||
G4double secondexp = G4Exp(-p6*(elog + p7));
|
||||
|
||||
res = (1.+p3*firstexp/(1. + firstexp))/(1. + secondexp);
|
||||
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -44,11 +44,14 @@
|
||||
#include "G4ComponentGGHadronNucleusXsc.hh"
|
||||
#include "G4UPiNuclearCrossSection.hh"
|
||||
#include "G4HadronNucleonXsc.hh"
|
||||
#include "G4NuclearRadii.hh"
|
||||
|
||||
#include "G4Proton.hh"
|
||||
#include "G4PionPlus.hh"
|
||||
#include "G4PionMinus.hh"
|
||||
#include "G4NistManager.hh"
|
||||
#include "G4HadronicParameters.hh"
|
||||
#include "G4Pow.hh"
|
||||
|
||||
G4double G4BGGPionElasticXS::theGlauberFacPiPlus[93] = {0.0};
|
||||
G4double G4BGGPionElasticXS::theCoulombFacPiPlus[93] = {0.0};
|
||||
@@ -67,16 +70,20 @@ G4BGGPionElasticXS::G4BGGPionElasticXS(const G4ParticleDefinition* p)
|
||||
{
|
||||
verboseLevel = 0;
|
||||
fGlauberEnergy = 91.*GeV;
|
||||
fLowEnergy = 1.*MeV;
|
||||
fLowEnergy = 20.*MeV;
|
||||
fLowestEnergy = 1.*MeV;
|
||||
SetMinKinEnergy(0.0);
|
||||
SetMaxKinEnergy( G4HadronicParameters::Instance()->GetMaxEnergy() );
|
||||
|
||||
fPion = nullptr;
|
||||
fGlauber = nullptr;
|
||||
fHadron = nullptr;
|
||||
particle = p;
|
||||
|
||||
fG4pow = G4Pow::GetInstance();
|
||||
|
||||
theProton= G4Proton::Proton();
|
||||
isPiplus = (p == G4PionPlus::PionPlus()) ? true : false;
|
||||
thePiPlus= G4PionPlus::PionPlus();
|
||||
isPiplus = (p == thePiPlus);
|
||||
isMaster = false;
|
||||
SetForAllAtomsAndEnergies(true);
|
||||
}
|
||||
@@ -92,7 +99,7 @@ G4BGGPionElasticXS::~G4BGGPionElasticXS()
|
||||
|
||||
G4bool
|
||||
G4BGGPionElasticXS::IsElementApplicable(const G4DynamicParticle*, G4int,
|
||||
const G4Material*)
|
||||
const G4Material*)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -100,7 +107,7 @@ G4BGGPionElasticXS::IsElementApplicable(const G4DynamicParticle*, G4int,
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4bool G4BGGPionElasticXS::IsIsoApplicable(const G4DynamicParticle*,
|
||||
G4int Z, G4int,
|
||||
G4int Z, G4int,
|
||||
const G4Element*, const G4Material*)
|
||||
{
|
||||
return (1 == Z);
|
||||
@@ -110,18 +117,18 @@ G4bool G4BGGPionElasticXS::IsIsoApplicable(const G4DynamicParticle*,
|
||||
|
||||
G4double
|
||||
G4BGGPionElasticXS::GetElementCrossSection(const G4DynamicParticle* dp,
|
||||
G4int ZZ, const G4Material*)
|
||||
G4int ZZ, const G4Material*)
|
||||
{
|
||||
// this method should be called only for Z > 1
|
||||
|
||||
G4double cross = 0.0;
|
||||
G4double ekin = dp->GetKineticEnergy();
|
||||
G4double ekin = std::max(dp->GetKineticEnergy(), fLowestEnergy);
|
||||
G4int Z = std::min(ZZ, 92);
|
||||
if(1 == Z) {
|
||||
cross = 1.0115*GetIsoCrossSection(dp,1,1);
|
||||
} else {
|
||||
if(ekin <= fLowEnergy) {
|
||||
cross = (isPiplus) ? theCoulombFacPiPlus[Z] : theCoulombFacPiMinus[Z];
|
||||
cross = (isPiplus) ? theCoulombFacPiPlus[Z]*CoulombFactorPiPlus(ekin, Z)
|
||||
: theCoulombFacPiMinus[Z]*FactorPiMinus(ekin);
|
||||
} else if(ekin > fGlauberEnergy) {
|
||||
cross = (isPiplus) ? theGlauberFacPiPlus[Z] : theGlauberFacPiMinus[Z];
|
||||
cross *= fGlauber->GetElasticGlauberGribov(dp, Z, theA[Z]);
|
||||
@@ -131,34 +138,34 @@ G4BGGPionElasticXS::GetElementCrossSection(const G4DynamicParticle* dp,
|
||||
}
|
||||
if(verboseLevel > 1) {
|
||||
G4cout << "G4BGGPionElasticXS::GetElementCrossSection for "
|
||||
<< dp->GetDefinition()->GetParticleName()
|
||||
<< " Ekin(GeV)= " << dp->GetKineticEnergy()
|
||||
<< " in nucleus Z= " << Z << " A= " << theA[Z]
|
||||
<< " XS(b)= " << cross/barn
|
||||
<< G4endl;
|
||||
<< dp->GetDefinition()->GetParticleName()
|
||||
<< " Ekin(GeV)= " << dp->GetKineticEnergy()
|
||||
<< " in nucleus Z= " << Z << " A= " << theA[Z]
|
||||
<< " XS(b)= " << cross/barn
|
||||
<< G4endl;
|
||||
}
|
||||
return cross;
|
||||
}
|
||||
|
||||
G4double
|
||||
G4BGGPionElasticXS::GetIsoCrossSection(const G4DynamicParticle* dp,
|
||||
G4int Z, G4int A,
|
||||
const G4Isotope*,
|
||||
const G4Element*,
|
||||
const G4Material*)
|
||||
G4int Z, G4int A,
|
||||
const G4Isotope*,
|
||||
const G4Element*,
|
||||
const G4Material*)
|
||||
{
|
||||
// this method should be called only for Z = 1
|
||||
fHadron->HadronNucleonXscNS(dp->GetDefinition(), theProton,
|
||||
dp->GetKineticEnergy());
|
||||
dp->GetKineticEnergy());
|
||||
G4double cross = A*fHadron->GetElasticHadronNucleonXsc();
|
||||
|
||||
if(verboseLevel > 1) {
|
||||
G4cout << "G4BGGPionElasticXS::GetIsoCrossSection for "
|
||||
<< dp->GetDefinition()->GetParticleName()
|
||||
<< " Ekin(GeV)= " << dp->GetKineticEnergy()
|
||||
<< " in nucleus Z= " << Z << " A= " << A
|
||||
<< " XS(b)= " << cross/barn
|
||||
<< G4endl;
|
||||
<< dp->GetDefinition()->GetParticleName()
|
||||
<< " Ekin(GeV)= " << dp->GetKineticEnergy()
|
||||
<< " in nucleus Z= " << Z << " A= " << A
|
||||
<< " XS(b)= " << cross/barn
|
||||
<< G4endl;
|
||||
}
|
||||
return cross;
|
||||
}
|
||||
@@ -167,25 +174,27 @@ G4BGGPionElasticXS::GetIsoCrossSection(const G4DynamicParticle* dp,
|
||||
|
||||
void G4BGGPionElasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
|
||||
{
|
||||
if(fPion) { return; }
|
||||
if(verboseLevel > 1) {
|
||||
G4cout << "G4BGGPionElasticXS::BuildPhysicsTable for "
|
||||
<< p.GetParticleName() << G4endl;
|
||||
}
|
||||
if(&p == G4PionPlus::PionPlus() || &p == G4PionMinus::PionMinus()) {
|
||||
particle = &p;
|
||||
isPiplus = (particle == G4PionPlus::PionPlus()) ? true : false;
|
||||
isPiplus = (&p == G4PionPlus::PionPlus());
|
||||
} else {
|
||||
G4ExceptionDescription ed;
|
||||
ed << "This BGG cross section is applicable only to pions and not to "
|
||||
<< p.GetParticleName() << G4endl;
|
||||
G4Exception("G4BGGPionElasticXS::BuildPhysicsTable", "had001",
|
||||
FatalException, ed);
|
||||
FatalException, ed);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!fPion) {
|
||||
fPion = new G4UPiNuclearCrossSection();
|
||||
fGlauber = new G4ComponentGGHadronNucleusXsc();
|
||||
fHadron = new G4HadronNucleonXsc();
|
||||
}
|
||||
fPion = new G4UPiNuclearCrossSection();
|
||||
fGlauber = new G4ComponentGGHadronNucleusXsc();
|
||||
fHadron = new G4HadronNucleonXsc();
|
||||
|
||||
fPion->BuildPhysicsTable(*particle);
|
||||
fPion->BuildPhysicsTable(p);
|
||||
|
||||
if(0 == theA[0]) {
|
||||
#ifdef G4MULTITHREADED
|
||||
@@ -197,13 +206,15 @@ void G4BGGPionElasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
|
||||
}
|
||||
G4MUTEXUNLOCK(&pionElasticXSMutex);
|
||||
#endif
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if(isMaster && 0 == theA[0]) {
|
||||
|
||||
theA[0] = 1;
|
||||
theA[0] = theA[1] = 1;
|
||||
G4ThreeVector mom(0.0,0.0,1.0);
|
||||
G4DynamicParticle dp(particle, mom, fGlauberEnergy);
|
||||
G4DynamicParticle dp(thePiPlus, mom, fGlauberEnergy);
|
||||
|
||||
G4NistManager* nist = G4NistManager::Instance();
|
||||
|
||||
@@ -213,43 +224,64 @@ void G4BGGPionElasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
|
||||
G4int A = G4lrint(nist->GetAtomicMassAmu(iz));
|
||||
theA[iz] = A;
|
||||
|
||||
dp.SetDefinition(G4PionPlus::PionPlus());
|
||||
csup = fGlauber->GetElasticGlauberGribov(&dp, iz, A);
|
||||
csdn = fPion->GetElasticCrossSection(&dp, iz, A);
|
||||
theGlauberFacPiPlus[iz] = csdn/csup;
|
||||
}
|
||||
|
||||
dp.SetDefinition(G4PionMinus::PionMinus());
|
||||
csup = fGlauber->GetElasticGlauberGribov(&dp, iz, A);
|
||||
csdn = fPion->GetElasticCrossSection(&dp, iz, A);
|
||||
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= " << A
|
||||
<< " factorPiPlus= " << theGlauberFacPiPlus[iz]
|
||||
<< " factorPiMinus= " << theGlauberFacPiMinus[iz]
|
||||
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) {
|
||||
dp.SetDefinition(G4PionPlus::PionPlus());
|
||||
theCoulombFacPiPlus[iz] = fPion->GetElasticCrossSection(&dp, iz, theA[iz]);
|
||||
|
||||
dp.SetDefinition(G4PionMinus::PionMinus());
|
||||
theCoulombFacPiMinus[iz] = fPion->GetElasticCrossSection(&dp, iz, theA[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]
|
||||
G4cout << "Z= " << iz << " A= " << theA[iz]
|
||||
<< " CoulombFactorPiPlus= " << theCoulombFacPiPlus[iz]
|
||||
<< " CoulombFactorPiMinus= " << theCoulombFacPiMinus[iz]
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4BGGPionElasticXS::CoulombFactorPiPlus(G4double kinEnergy, G4int Z)
|
||||
{
|
||||
return (kinEnergy > 0.0) ?
|
||||
G4NuclearRadii::CoulombFactor(Z, theA[Z], thePiPlus, kinEnergy) : 0.0;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4BGGPionElasticXS::FactorPiMinus(G4double kinEnergy)
|
||||
{
|
||||
return 1.0/std::sqrt(kinEnergy);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void
|
||||
G4BGGPionElasticXS::CrossSectionDescription(std::ostream& outFile) const
|
||||
{
|
||||
@@ -258,3 +290,5 @@ G4BGGPionElasticXS::CrossSectionDescription(std::ostream& outFile) const
|
||||
<< "Barashenkov parameterization is used below 91 GeV and the\n"
|
||||
<< "Glauber-Gribov parameterization is used above 91 GeV.\n";
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class file
|
||||
@@ -44,6 +43,7 @@
|
||||
#include "G4ComponentGGHadronNucleusXsc.hh"
|
||||
#include "G4UPiNuclearCrossSection.hh"
|
||||
#include "G4HadronNucleonXsc.hh"
|
||||
#include "G4NuclearRadii.hh"
|
||||
|
||||
#include "G4Proton.hh"
|
||||
#include "G4PionPlus.hh"
|
||||
@@ -67,8 +67,9 @@ G4BGGPionInelasticXS::G4BGGPionInelasticXS(const G4ParticleDefinition* p)
|
||||
: G4VCrossSectionDataSet("BarashenkovGlauberGribov")
|
||||
{
|
||||
verboseLevel = 0;
|
||||
fGlauberEnergy = 91.*GeV;
|
||||
fLowEnergy = 20.*MeV;
|
||||
fGlauberEnergy = 91.*CLHEP::GeV;
|
||||
fLowEnergy = 20.*CLHEP::MeV;
|
||||
fLowestEnergy = 1.*CLHEP::MeV;
|
||||
SetMinKinEnergy(0.0);
|
||||
SetMaxKinEnergy( G4HadronicParameters::Instance()->GetMaxEnergy() );
|
||||
|
||||
@@ -78,10 +79,10 @@ G4BGGPionInelasticXS::G4BGGPionInelasticXS(const G4ParticleDefinition* p)
|
||||
|
||||
fG4pow = G4Pow::GetInstance();
|
||||
|
||||
particle = p;
|
||||
theProton= G4Proton::Proton();
|
||||
isPiplus = (p == G4PionPlus::PionPlus()) ? true : false;
|
||||
isMaster = false;
|
||||
theProton = G4Proton::Proton();
|
||||
thePiPlus = G4PionPlus::PionPlus();
|
||||
isPiplus = (p == thePiPlus);
|
||||
isMaster = false;
|
||||
SetForAllAtomsAndEnergies(true);
|
||||
}
|
||||
|
||||
@@ -96,7 +97,7 @@ G4BGGPionInelasticXS::~G4BGGPionInelasticXS()
|
||||
|
||||
G4bool
|
||||
G4BGGPionInelasticXS::IsElementApplicable(const G4DynamicParticle*, G4int,
|
||||
const G4Material*)
|
||||
const G4Material*)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -104,9 +105,9 @@ G4BGGPionInelasticXS::IsElementApplicable(const G4DynamicParticle*, G4int,
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4bool G4BGGPionInelasticXS::IsIsoApplicable(const G4DynamicParticle*,
|
||||
G4int Z, G4int,
|
||||
const G4Element*,
|
||||
const G4Material*)
|
||||
G4int Z, G4int,
|
||||
const G4Element*,
|
||||
const G4Material*)
|
||||
{
|
||||
return (1 == Z);
|
||||
}
|
||||
@@ -115,19 +116,19 @@ G4bool G4BGGPionInelasticXS::IsIsoApplicable(const G4DynamicParticle*,
|
||||
|
||||
G4double
|
||||
G4BGGPionInelasticXS::GetElementCrossSection(const G4DynamicParticle* dp,
|
||||
G4int ZZ, const G4Material*)
|
||||
G4int ZZ, const G4Material*)
|
||||
{
|
||||
// this method should be called only for Z > 1
|
||||
|
||||
G4double cross = 0.0;
|
||||
G4double ekin = dp->GetKineticEnergy();
|
||||
G4double ekin = std::max(dp->GetKineticEnergy(), fLowestEnergy);
|
||||
G4int Z = std::min(ZZ, 92);
|
||||
|
||||
if(1 == Z) {
|
||||
cross = 1.0115*GetIsoCrossSection(dp,1,1);
|
||||
} else if(ekin <= fLowEnergy) {
|
||||
cross = (isPiplus) ? theLowEPiPlus[Z]*CoulombFactor(ekin, Z)
|
||||
: theLowEPiMinus[Z];
|
||||
} else if(ekin < fLowEnergy) {
|
||||
cross = (isPiplus) ? theLowEPiPlus[Z]*CoulombFactorPiPlus(ekin, Z)
|
||||
: theLowEPiMinus[Z]*FactorPiMinus(ekin);
|
||||
} else if(ekin > fGlauberEnergy) {
|
||||
cross = (isPiplus) ? theGlauberFacPiPlus[Z] : theGlauberFacPiMinus[Z];
|
||||
cross *= fGlauber->GetInelasticGlauberGribov(dp, Z, theA[Z]);
|
||||
@@ -136,11 +137,11 @@ G4BGGPionInelasticXS::GetElementCrossSection(const G4DynamicParticle* dp,
|
||||
}
|
||||
if(verboseLevel > 1) {
|
||||
G4cout << "G4BGGPionInelasticXS::GetCrossSection for "
|
||||
<< dp->GetDefinition()->GetParticleName()
|
||||
<< " Ekin(GeV)= " << dp->GetKineticEnergy()
|
||||
<< " in nucleus Z= " << Z << " A= " << theA[Z]
|
||||
<< " XS(b)= " << cross/barn
|
||||
<< G4endl;
|
||||
<< dp->GetDefinition()->GetParticleName()
|
||||
<< " Ekin(GeV)= " << dp->GetKineticEnergy()
|
||||
<< " in nucleus Z= " << Z << " A= " << theA[Z]
|
||||
<< " XS(b)= " << cross/barn
|
||||
<< G4endl;
|
||||
}
|
||||
return cross;
|
||||
}
|
||||
@@ -149,23 +150,23 @@ G4BGGPionInelasticXS::GetElementCrossSection(const G4DynamicParticle* dp,
|
||||
|
||||
G4double
|
||||
G4BGGPionInelasticXS::GetIsoCrossSection(const G4DynamicParticle* dp,
|
||||
G4int Z, G4int A,
|
||||
const G4Isotope*,
|
||||
const G4Element*,
|
||||
const G4Material*)
|
||||
G4int Z, G4int A,
|
||||
const G4Isotope*,
|
||||
const G4Element*,
|
||||
const G4Material*)
|
||||
{
|
||||
// this method should be called only for Z = 1
|
||||
fHadron->HadronNucleonXscNS(dp->GetDefinition(), theProton,
|
||||
dp->GetKineticEnergy());
|
||||
dp->GetKineticEnergy());
|
||||
G4double cross = A*fHadron->GetInelasticHadronNucleonXsc();
|
||||
|
||||
if(verboseLevel > 1) {
|
||||
G4cout << "G4BGGPionInelasticXS::GetCrossSection for "
|
||||
<< dp->GetDefinition()->GetParticleName()
|
||||
<< " Ekin(GeV)= " << dp->GetKineticEnergy()
|
||||
<< " in nucleus Z= " << Z << " A= " << A
|
||||
<< " XS(b)= " << cross/barn
|
||||
<< G4endl;
|
||||
<< dp->GetDefinition()->GetParticleName()
|
||||
<< " Ekin(GeV)= " << dp->GetKineticEnergy()
|
||||
<< " in nucleus Z= " << Z << " A= " << A
|
||||
<< " XS(b)= " << cross/barn
|
||||
<< G4endl;
|
||||
}
|
||||
return cross;
|
||||
}
|
||||
@@ -174,25 +175,27 @@ G4BGGPionInelasticXS::GetIsoCrossSection(const G4DynamicParticle* dp,
|
||||
|
||||
void G4BGGPionInelasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
|
||||
{
|
||||
if(fPion) { return; }
|
||||
if(verboseLevel > 1) {
|
||||
G4cout << "G4BGGPionInelasticXS::BuildPhysicsTable for "
|
||||
<< p.GetParticleName() << G4endl;
|
||||
}
|
||||
if(&p == G4PionPlus::PionPlus() || &p == G4PionMinus::PionMinus()) {
|
||||
particle = &p;
|
||||
isPiplus = (particle == G4PionPlus::PionPlus()) ? true : false;
|
||||
isPiplus = (&p == G4PionPlus::PionPlus());
|
||||
} else {
|
||||
G4ExceptionDescription ed;
|
||||
ed << "This BGG cross section is applicable only to pions and not to "
|
||||
<< p.GetParticleName() << G4endl;
|
||||
G4Exception("G4BGGPionInelasticXS::BuildPhysicsTable", "had001",
|
||||
FatalException, ed);
|
||||
FatalException, ed);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!fPion) {
|
||||
fPion = new G4UPiNuclearCrossSection();
|
||||
fGlauber = new G4ComponentGGHadronNucleusXsc();
|
||||
fHadron = new G4HadronNucleonXsc();
|
||||
}
|
||||
fPion = new G4UPiNuclearCrossSection();
|
||||
fGlauber = new G4ComponentGGHadronNucleusXsc();
|
||||
fHadron = new G4HadronNucleonXsc();
|
||||
|
||||
fPion->BuildPhysicsTable(*particle);
|
||||
fPion->BuildPhysicsTable(p);
|
||||
|
||||
if(0 == theA[0]) {
|
||||
#ifdef G4MULTITHREADED
|
||||
@@ -204,62 +207,65 @@ void G4BGGPionInelasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
|
||||
}
|
||||
G4MUTEXUNLOCK(&pionInelasticXSMutex);
|
||||
#endif
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if(isMaster && 0 == theA[0]) {
|
||||
|
||||
theA[0] = 1;
|
||||
theA[1] = 1;
|
||||
theA[0] = theA[1] = 1;
|
||||
G4ThreeVector mom(0.0,0.0,1.0);
|
||||
G4DynamicParticle dp(particle, mom, fGlauberEnergy);
|
||||
G4DynamicParticle dp(thePiPlus, mom, fGlauberEnergy);
|
||||
|
||||
G4NistManager* nist = G4NistManager::Instance();
|
||||
G4double csup, csdn;
|
||||
|
||||
if(verboseLevel > 0) {
|
||||
G4cout << "### G4BGGPionInelasticXS::Initialise for "
|
||||
<< particle->GetParticleName()
|
||||
<< " isPiplus: " << isPiplus
|
||||
<< G4endl;
|
||||
<< p.GetParticleName()
|
||||
<< " isPiplus: " << isPiplus
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
for(G4int iz=2; iz<93; ++iz) {
|
||||
G4int A = G4lrint(nist->GetAtomicMassAmu(iz));
|
||||
theA[iz] = A;
|
||||
|
||||
dp.SetDefinition(G4PionPlus::PionPlus());
|
||||
csup = fGlauber->GetInelasticGlauberGribov(&dp, iz, A);
|
||||
csdn = fPion->GetInelasticCrossSection(&dp, iz, A);
|
||||
theGlauberFacPiPlus[iz] = csdn/csup;
|
||||
}
|
||||
|
||||
dp.SetDefinition(G4PionMinus::PionMinus());
|
||||
csup = fGlauber->GetInelasticGlauberGribov(&dp, iz, A);
|
||||
csdn = fPion->GetInelasticCrossSection(&dp, iz, A);
|
||||
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= " << A
|
||||
<< " factorPiPlus= " << theGlauberFacPiPlus[iz]
|
||||
<< " factorPiMinus= " << theGlauberFacPiMinus[iz]
|
||||
G4cout << "Z= " << iz << " A= " << theA[iz]
|
||||
<< " factorPiPlus= " << theGlauberFacPiPlus[iz]
|
||||
<< " factorPiMinus= " << theGlauberFacPiMinus[iz]
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
theLowEPiPlus[1] = 1.0;
|
||||
theLowEPiMinus[1]= 1.0;
|
||||
dp.SetKineticEnergy(fLowEnergy);
|
||||
|
||||
theLowEPiPlus[1] = theLowEPiMinus[1]= 1.0;
|
||||
dp.SetDefinition(thePiPlus);
|
||||
dp.SetKineticEnergy(fLowEnergy);
|
||||
for(G4int iz=2; iz<93; ++iz) {
|
||||
dp.SetDefinition(G4PionPlus::PionPlus());
|
||||
theLowEPiPlus[iz] = fPion->GetInelasticCrossSection(&dp, iz, theA[iz])
|
||||
/CoulombFactor(fLowEnergy, iz);
|
||||
|
||||
dp.SetDefinition(G4PionMinus::PionMinus());
|
||||
theLowEPiMinus[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);
|
||||
|
||||
if(verboseLevel > 0) {
|
||||
G4cout << "Z= " << iz << " A= " << theA[iz]
|
||||
<< " LowEtorPiPlus= " << theLowEPiPlus[iz]
|
||||
<< " LowEtorPiMinus= " << theLowEPiMinus[iz]
|
||||
G4cout << "Z= " << iz << " A= " << theA[iz]
|
||||
<< " LowEtorPiPlus= " << theLowEPiPlus[iz]
|
||||
<< " LowEtorPiMinus= " << theLowEPiMinus[iz]
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
@@ -268,26 +274,17 @@ void G4BGGPionInelasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4BGGPionInelasticXS::CoulombFactor(G4double kinEnergy, G4int Z)
|
||||
G4double G4BGGPionInelasticXS::CoulombFactorPiPlus(G4double kinEnergy, G4int Z)
|
||||
{
|
||||
G4int A = theA[Z];
|
||||
G4double res= 0.0;
|
||||
if(kinEnergy <= DBL_MIN) { return res; }
|
||||
else if(A < 2) { return kinEnergy*kinEnergy; }
|
||||
|
||||
G4double elog = fG4pow->log10A(6.7*kinEnergy/GeV);
|
||||
G4double aa = A;
|
||||
return (kinEnergy > 0.0) ?
|
||||
G4NuclearRadii::CoulombFactor(Z, theA[Z], thePiPlus, kinEnergy) : 0.0;
|
||||
}
|
||||
|
||||
// from G4ProtonInelasticCrossSection
|
||||
G4double ff1 = 0.70 - 0.002*aa; // slope of the drop at medium energies.
|
||||
G4double ff2 = 1.00 + 1/aa; // start of the slope.
|
||||
G4double ff3 = 0.8 + 18/aa - 0.002*aa; // stephight
|
||||
res = 1.0 + ff3*(1.0 - (1.0/(1+fG4pow->expA(-8*ff1*(elog + 1.37*ff2)))));
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
ff1 = 1. - 1./aa - 0.001*aa; // slope of the rise
|
||||
ff2 = 1.17 - 2.7/aa-0.0014*aa; // start of the rise
|
||||
res /= (1 + fG4pow->expA(-8.*ff1*(elog + 2*ff2)));
|
||||
return res;
|
||||
G4double G4BGGPionInelasticXS::FactorPiMinus(G4double kinEnergy)
|
||||
{
|
||||
return 1.0/std::sqrt(kinEnergy);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
@@ -140,7 +140,7 @@ G4double G4ComponentBarNucleonNucleusXsc::GetElasticIsotopeCrossSection(
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void G4ComponentBarNucleonNucleusXsc::ComputeCrossSections(
|
||||
const G4ParticleDefinition* aParticle, G4double kineticEnergy, G4int ZZ)
|
||||
const G4ParticleDefinition* aParticle, G4double kineticEnergy, G4int ZZ)
|
||||
{
|
||||
G4int Z = std::min(ZZ, 92);
|
||||
G4int it = 0;
|
||||
@@ -164,7 +164,7 @@ void G4ComponentBarNucleonNucleusXsc::ComputeCrossSections(
|
||||
fInelasticXsc = Interpolate(Z1, Z2, Z, x1, x2);
|
||||
fTotalXsc = Interpolate(Z1, Z2, Z, xt1, xt2);
|
||||
}
|
||||
|
||||
|
||||
fElasticXsc = std::max(fTotalXsc - fInelasticXsc, 0.0);
|
||||
}
|
||||
|
||||
|
||||
@@ -212,11 +212,11 @@ void G4ComponentGGHadronNucleusXsc::ComputeCrossSections(
|
||||
}
|
||||
else
|
||||
{
|
||||
sigma = Z*hnXsc->HadronNucleonXscNS(aParticle, theProton, kinEnergy);
|
||||
sigma = Z*hnXsc->HadronNucleonXsc(aParticle, theProton, kinEnergy);
|
||||
hpInXsc = hnXsc->GetInelasticHadronNucleonXsc();
|
||||
|
||||
if(N > 0) {
|
||||
sigma += N*hnXsc->HadronNucleonXscNS(aParticle, theNeutron, kinEnergy);
|
||||
sigma += N*hnXsc->HadronNucleonXsc(aParticle, theNeutron, kinEnergy);
|
||||
hnInXsc = hnXsc->GetInelasticHadronNucleonXsc();
|
||||
}
|
||||
R = G4NuclearRadii::RadiusHNGG(A);
|
||||
@@ -250,9 +250,11 @@ void G4ComponentGGHadronNucleusXsc::ComputeCrossSections(
|
||||
fTotalXsc = sigma;
|
||||
fInelasticXsc = hpInXsc;
|
||||
fElasticXsc = std::max(fTotalXsc - fInelasticXsc, 0.);
|
||||
G4double xratio = hpInXsc/nucleusSquare;
|
||||
fProductionXsc = nucleusSquare*G4Log(1. + cofInelastic*xratio)/cofInelastic;
|
||||
fProductionXsc = std::min(fProductionXsc, fInelasticXsc);
|
||||
fProductionXsc = fInelasticXsc;
|
||||
fDiffractionXsc = 0.2*fInelasticXsc;
|
||||
// G4double xratio = hpInXsc/nucleusSquare;
|
||||
// fProductionXsc = nucleusSquare*G4Log(1. + cofInelastic*xratio)/cofInelastic;
|
||||
// fProductionXsc = std::min(fProductionXsc, fInelasticXsc);
|
||||
}
|
||||
/*
|
||||
G4cout << "GGXsc: Z= " << Z << " A= " << A << " E= " << kinEnergy
|
||||
|
||||
@@ -221,7 +221,7 @@ void G4ComponentSAIDTotalXS::Initialise(G4SAIDCrossSectionType tp)
|
||||
#endif
|
||||
// check environment variable
|
||||
// Build the complete string identifying the file with the data set
|
||||
char* path = getenv("G4SAIDXSDATA");
|
||||
char* path = std::getenv("G4SAIDXSDATA");
|
||||
if (!path){
|
||||
G4Exception("G4ComponentSAIDTotalXS::Initialise(..)","had013",
|
||||
FatalException,
|
||||
|
||||
@@ -581,7 +581,7 @@ void G4CrossSectionDataStore::DumpHtml(const G4ParticleDefinition& /* pD */,
|
||||
|
||||
G4double ehi = 0;
|
||||
G4double elo = 0;
|
||||
G4String physListName(getenv("G4PhysListName"));
|
||||
G4String physListName(std::getenv("G4PhysListName"));
|
||||
for (G4int i = nDataSetList-1; i > 0; i--) {
|
||||
elo = dataSetList[i]->GetMinKinEnergy()/GeV;
|
||||
ehi = dataSetList[i]->GetMaxKinEnergy()/GeV;
|
||||
@@ -607,8 +607,8 @@ void G4CrossSectionDataStore::DumpHtml(const G4ParticleDefinition& /* pD */,
|
||||
|
||||
void G4CrossSectionDataStore::PrintCrossSectionHtml(const G4VCrossSectionDataSet *cs) const
|
||||
{
|
||||
G4String dirName(getenv("G4PhysListDocDir"));
|
||||
G4String physListName(getenv("G4PhysListName"));
|
||||
G4String dirName(std::getenv("G4PhysListDocDir"));
|
||||
G4String physListName(std::getenv("G4PhysListName"));
|
||||
|
||||
G4String pathName = dirName + "/" + physListName + "_" + HtmlFileName(cs->GetName());
|
||||
std::ofstream outCS;
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include "G4Log.hh"
|
||||
#include "G4Exp.hh"
|
||||
#include "G4Pow.hh"
|
||||
#include "G4NuclearRadii.hh"
|
||||
|
||||
#include "G4LambdacPlus.hh"
|
||||
#include "G4AntiLambdacPlus.hh"
|
||||
@@ -119,6 +120,7 @@ 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
|
||||
|
||||
G4HadronNucleonXsc::G4HadronNucleonXsc()
|
||||
: fTotalXsc(0.0), fElasticXsc(0.0), fInelasticXsc(0.0)
|
||||
@@ -222,6 +224,48 @@ void G4HadronNucleonXsc::CrossSectionDescription(std::ostream& outFile) const
|
||||
<< "is to be used to build a cross section data set.\n";
|
||||
}
|
||||
|
||||
|
||||
|
||||
G4double G4HadronNucleonXsc::HadronNucleonXsc( const G4ParticleDefinition* theParticle,
|
||||
const G4ParticleDefinition* nucleon, G4double ekin)
|
||||
{
|
||||
G4double xsc(0.);
|
||||
G4int pdg = std::abs( theParticle->GetPDGEncoding() );
|
||||
|
||||
if ( pdg == 2212 || pdg == 2112 || pdg == 211 ) // p, n, pi+-
|
||||
{
|
||||
xsc = HadronNucleonXscNS( theParticle, nucleon, ekin);
|
||||
}
|
||||
else if ( pdg == 321 || pdg == 310 || pdg == 130 ) // K+-, K0, Ks
|
||||
{
|
||||
xsc = KaonNucleonXscNS( theParticle, nucleon, ekin);
|
||||
}
|
||||
else if ( pdg == 3122 || pdg == 3222 || pdg == 3112 || pdg == 3212 || pdg == 3322 || pdg == 3312 || pdg == 3324 ||
|
||||
|
||||
pdg == 4122 || pdg == 4332 || pdg == 4122 || pdg == 4212 || pdg == 4222 || pdg == 4112 || pdg == 4232 || pdg == 4132 ||
|
||||
|
||||
pdg == 5122 || pdg == 5332 || pdg == 5122 || pdg == 5112 || pdg == 5222 || pdg == 5212 || pdg == 5132 || pdg == 5232
|
||||
|
||||
) // heavy s-,c-,b-hyperons
|
||||
{
|
||||
xsc = HyperonNucleonXscNS( theParticle, nucleon, ekin);
|
||||
}
|
||||
else if ( pdg == 511 || pdg == 421 || pdg == 531 || pdg == 541 || pdg == 431 || pdg == 411 || pdg == 521 ||
|
||||
|
||||
pdg == 221 || pdg == 331 || pdg == 441 || pdg == 443 || pdg == 543
|
||||
|
||||
) // s-,c-,b-mesons
|
||||
{
|
||||
xsc = SCBMesonNucleonXscNS( theParticle, nucleon, ekin);
|
||||
}
|
||||
else
|
||||
{
|
||||
xsc = HadronNucleonXscNS( theParticle, nucleon, ekin);
|
||||
}
|
||||
return xsc;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Returns hadron-nucleon Xsc according to PDG parametrisation (2017):
|
||||
@@ -415,8 +459,9 @@ G4double G4HadronNucleonXsc::HadronNucleonXscPDG(
|
||||
|
||||
G4double G4HadronNucleonXsc::HadronNucleonXscNS(
|
||||
const G4ParticleDefinition* theParticle,
|
||||
const G4ParticleDefinition* nucleon, G4double ekin)
|
||||
const G4ParticleDefinition* nucleon, G4double ekin0)
|
||||
{
|
||||
const G4double ekin = std::max(ekin0, ekinmin);
|
||||
/*
|
||||
G4cout<< "HadronNucleonXscNS: Ekin(GeV)= " << ekin/GeV << " "
|
||||
<< theParticle->GetParticleName() << " + "
|
||||
@@ -426,57 +471,7 @@ G4double G4HadronNucleonXsc::HadronNucleonXscNS(
|
||||
return HadronNucleonXscPDG(theParticle, nucleon, ekin);
|
||||
}
|
||||
|
||||
G4double pM = theParticle->GetPDGMass();
|
||||
|
||||
///////////////////////////// strange hyperons
|
||||
if(pM > CLHEP::GeV) {
|
||||
if( theParticle == theL || theParticle == theSPlus ||
|
||||
theParticle == theSMinus || theParticle == theS0) {
|
||||
fTotalXsc = HadronNucleonXscNS( theProton, nucleon, ekin);
|
||||
fTotalXsc *= fHypTotXscCof;
|
||||
fInelasticXsc *= fHypTotXscCof;
|
||||
fElasticXsc *= fHypTotXscCof;
|
||||
return fTotalXsc;
|
||||
} else if( theParticle == theAntiL || theParticle == theASPlus ||
|
||||
theParticle == theASMinus || theParticle == theAS0) {
|
||||
fTotalXsc = HadronNucleonXscNS( theProton, nucleon, ekin);
|
||||
fTotalXsc *= fHypTotXscCof;
|
||||
fInelasticXsc *= fHypTotXscCof;
|
||||
fElasticXsc *= fHypTotXscCof;
|
||||
return fTotalXsc;
|
||||
} else if( theParticle == theXiMinus || theParticle == theXi0) {
|
||||
fTotalXsc = HadronNucleonXscNS( theProton, nucleon, ekin);
|
||||
G4double cof2 = fHypTotXscCof*fHypTotXscCof;
|
||||
fTotalXsc *= cof2;
|
||||
fInelasticXsc *= cof2;
|
||||
fElasticXsc *= cof2;
|
||||
return fTotalXsc;
|
||||
} else if( theParticle == theAXiMinus || theParticle == theAXi0) {
|
||||
fTotalXsc = HadronNucleonXscNS( theProton, nucleon, ekin);
|
||||
G4double cof2 = fHypTotXscCof*fHypTotXscCof;
|
||||
fTotalXsc *= cof2;
|
||||
fInelasticXsc *= cof2;
|
||||
fElasticXsc *= cof2;
|
||||
return fTotalXsc;
|
||||
} else if( theParticle == theOmega ) {
|
||||
fTotalXsc = HadronNucleonXscNS( theProton, nucleon, ekin);
|
||||
G4double cof3 = fHypTotXscCof*fHypTotXscCof*fHypTotXscCof;
|
||||
fTotalXsc *= cof3;
|
||||
fInelasticXsc *= cof3;
|
||||
fElasticXsc *= cof3;
|
||||
return fTotalXsc;
|
||||
} else if( theParticle == theAOmega ) {
|
||||
fTotalXsc = HadronNucleonXscNS( theProton, nucleon, ekin);
|
||||
G4double cof3 = fHypTotXscCof*fHypTotXscCof*fHypTotXscCof;
|
||||
fTotalXsc *= cof3;
|
||||
fInelasticXsc *= cof3;
|
||||
fElasticXsc *= cof3;
|
||||
return fTotalXsc;
|
||||
} else {
|
||||
return HadronNucleonXscPDG( theProton, nucleon, ekin);
|
||||
}
|
||||
}
|
||||
|
||||
G4double pM = theParticle->GetPDGMass();
|
||||
G4double tM = nucleon->GetPDGMass();
|
||||
G4double pE = ekin + pM;
|
||||
G4double pLab = std::sqrt(ekin*(ekin + 2*pM));
|
||||
@@ -489,6 +484,7 @@ G4double G4HadronNucleonXsc::HadronNucleonXscNS(
|
||||
if(pLab >= 10.) {
|
||||
fTotalXsc = HadronNucleonXscPDG(theParticle, nucleon, ekin)/CLHEP::millibarn;
|
||||
} else { fTotalXsc = 0.0; }
|
||||
fElasticXsc = 0.0;
|
||||
//G4cout << "Stot(mb)= " << fTotalXsc << " pLab= " << pLab
|
||||
// << " Smand= " << sMand <<G4endl;
|
||||
G4double logP = G4Log(pLab);
|
||||
@@ -643,7 +639,7 @@ G4double G4HadronNucleonXsc::HadronNucleonXscNS(
|
||||
}
|
||||
else if( pLab < 0.68 )
|
||||
{
|
||||
fTotalXsc = 14./( (logP + 1.273)*(logP + 1.273) + 0.07);
|
||||
fTotalXsc = 14./((logP + 1.273)*(logP + 1.273) + 0.07);
|
||||
fElasticXsc = fTotalXsc;
|
||||
}
|
||||
else if( pLab < 0.85 )
|
||||
@@ -880,16 +876,15 @@ G4double G4HadronNucleonXsc::HadronNucleonXscNS(
|
||||
}
|
||||
fTotalXsc *= CLHEP::millibarn;
|
||||
fElasticXsc *= CLHEP::millibarn;
|
||||
fElasticXsc = std::min(fElasticXsc, fTotalXsc);
|
||||
fInelasticXsc = std::max(fTotalXsc - fElasticXsc,0.0);
|
||||
fElasticXsc = std::min(fElasticXsc, fTotalXsc);
|
||||
|
||||
if( proton && theParticle->GetPDGCharge() > 0. && ekin < 100*MeV)
|
||||
{
|
||||
G4double cB = CoulombBarrier(theParticle, nucleon, ekin);
|
||||
G4double cB = G4NuclearRadii::CoulombFactor(theParticle, nucleon, ekin);
|
||||
fTotalXsc *= cB;
|
||||
fElasticXsc *= cB;
|
||||
fInelasticXsc *= cB;
|
||||
}
|
||||
fInelasticXsc = std::max(fTotalXsc - fElasticXsc,0.0);
|
||||
/*
|
||||
G4cout<< "HNXsc: Ekin(GeV)= " << ekin/GeV << "; tot(mb)= " << fTotalXsc/millibarn
|
||||
<<"; el(mb)= " <<fElasticXsc/millibarn
|
||||
@@ -1075,11 +1070,10 @@ G4double G4HadronNucleonXsc::KaonNucleonXscVG(
|
||||
G4double sp = std::sqrt(pLab);
|
||||
G4double p2 = pLab*pLab;
|
||||
G4double p4 = p2*p2;
|
||||
G4double lm = pLab - 0.8; // vg version
|
||||
G4double md = lm*lm + .652; // vg version
|
||||
G4double lm = pLab - 0.94;
|
||||
G4double md = lm*lm + .392;
|
||||
fElasticXsc = (cofLogE*ld2 + 2.23)/(1. - .7/sp + .1/p4) + 2./md;
|
||||
fTotalXsc = (cofLogT*ld2 + 19.5)/(1. + .46/sp + 1.6/p4)
|
||||
+ 7.6/md; // vg version
|
||||
fTotalXsc = (cofLogT*ld2 + 19.5)/(1. + .46/sp + 1.6/p4) + 4.6/md;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1088,7 +1082,7 @@ G4double G4HadronNucleonXsc::KaonNucleonXscVG(
|
||||
|
||||
if( proton && theParticle->GetPDGCharge() > 0. )
|
||||
{
|
||||
G4double cB = CoulombBarrier(theParticle, nucleon, ekin);
|
||||
G4double cB = G4NuclearRadii::CoulombFactor(theParticle, nucleon, ekin);
|
||||
fTotalXsc *= cB;
|
||||
fElasticXsc *= cB;
|
||||
}
|
||||
@@ -1108,18 +1102,18 @@ G4double G4HadronNucleonXsc::KaonNucleonXscVG(
|
||||
// Returns hyperon-nucleon cross-section using NS x-section for protons
|
||||
|
||||
G4double G4HadronNucleonXsc::HyperonNucleonXscNS(
|
||||
const G4ParticleDefinition* theParticle,
|
||||
const G4ParticleDefinition* nucleon, G4double ekin)
|
||||
const G4ParticleDefinition* theParticle,
|
||||
const G4ParticleDefinition* nucleon, G4double ekin)
|
||||
{
|
||||
G4double coeff = 1.0;
|
||||
|
||||
static const G4double lBarCof1S = 0.88;
|
||||
static const G4double lBarCof1S = 0.88;
|
||||
static const G4double lBarCof2S = 0.76;
|
||||
static const G4double lBarCof3S = 0.64;
|
||||
static const G4double lBarCof1C = 0.784378;
|
||||
static const G4double lBarCofSC = 0.664378;
|
||||
static const G4double lBarCof2SC = 0.544378;
|
||||
static const G4double lBarCof1B = 0.740659;
|
||||
static const G4double lBarCof1B = 0.740659;
|
||||
static const G4double lBarCofSB = 0.620659;
|
||||
static const G4double lBarCof2SB = 0.500659;
|
||||
|
||||
@@ -1184,8 +1178,9 @@ G4double G4HadronNucleonXsc::HyperonNucleonXscNS(
|
||||
//
|
||||
// Returns hyperon-nucleon cross-section using NS x-section for protons
|
||||
|
||||
G4double G4HadronNucleonXsc::SCBMesonNucleonXscNS( const G4ParticleDefinition* theParticle,
|
||||
const G4ParticleDefinition* nucleon, G4double ekin )
|
||||
G4double G4HadronNucleonXsc::SCBMesonNucleonXscNS(
|
||||
const G4ParticleDefinition* theParticle,
|
||||
const G4ParticleDefinition* nucleon, G4double ekin )
|
||||
{
|
||||
G4double coeff(1.0);
|
||||
// static const G4double lMesCof1S = 0.82; // Kp/piP
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class file
|
||||
@@ -41,11 +40,12 @@
|
||||
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4NeutronCaptureXS.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4Element.hh"
|
||||
#include "G4ElementTable.hh"
|
||||
#include "G4PhysicsLogVector.hh"
|
||||
#include "G4PhysicsVector.hh"
|
||||
#include "G4DynamicParticle.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4Log.hh"
|
||||
|
||||
@@ -82,6 +82,7 @@ const G4int G4NeutronCaptureXS::amax[] = {
|
||||
0, 238};
|
||||
|
||||
G4ElementData* G4NeutronCaptureXS::data = nullptr;
|
||||
G4String G4NeutronCaptureXS::gDataDirectory = "";
|
||||
|
||||
#ifdef G4MULTITHREADED
|
||||
G4Mutex G4NeutronCaptureXS::neutronCaptureXSMutex = G4MUTEX_INITIALIZER;
|
||||
@@ -98,7 +99,7 @@ G4NeutronCaptureXS::G4NeutronCaptureXS()
|
||||
}
|
||||
logElimit = G4Log(elimit);
|
||||
isMaster = false;
|
||||
fIdxXSTable = 0;
|
||||
temp.resize(13,0.0);
|
||||
}
|
||||
|
||||
G4NeutronCaptureXS::~G4NeutronCaptureXS()
|
||||
@@ -142,19 +143,19 @@ G4NeutronCaptureXS::GetElementCrossSection(const G4DynamicParticle* aParticle,
|
||||
G4double logEkin = aParticle->GetLogKineticEnergy();
|
||||
if(ekin < elimit) { ekin = elimit; logEkin = logElimit; }
|
||||
|
||||
// element was not initialised
|
||||
G4PhysicsVector* pv = data->GetElementData(Z);
|
||||
auto pv = GetPhysicsVector(Z);
|
||||
if(!pv) { return xs; }
|
||||
|
||||
G4double e1 = pv->Energy(0);
|
||||
if(ekin < e1) {
|
||||
xs = (*pv)[0]*std::sqrt(e1/ekin);
|
||||
} else if(ekin <= pv->GetMaxEnergy()) {
|
||||
xs = pv->Value(ekin, logEkin, fIdxXSTable);
|
||||
xs = pv->LogVectorValue(ekin, logEkin);
|
||||
}
|
||||
|
||||
if(verboseLevel > 0){
|
||||
G4cout << "ekin= " << ekin << ", xs= " << xs << G4endl;
|
||||
if(verboseLevel > 1){
|
||||
G4cout << "Ekin= " << ekin/CLHEP::MeV
|
||||
<< " ElmXScap(b)= " << xs/CLHEP::barn << G4endl;
|
||||
}
|
||||
return xs;
|
||||
}
|
||||
@@ -184,34 +185,37 @@ G4double G4NeutronCaptureXS::IsoCrossSection(G4double eKin, G4double logE,
|
||||
logEkin = logElimit;
|
||||
}
|
||||
|
||||
if(amin[Z] > 0) {
|
||||
if(A >= amin[Z] && A <= amax[Z]) {
|
||||
G4PhysicsVector* pviso = data->GetComponentDataByID(Z, A - amin[Z]);
|
||||
if(pviso) {
|
||||
G4double e1 = pviso->Energy(1);
|
||||
if(ekin < e1) {
|
||||
xs = (*pviso)[1]*std::sqrt(e1/ekin);
|
||||
} else if(ekin <= pviso->GetMaxEnergy()) {
|
||||
xs = pviso->Value(ekin, logEkin, fIdxXSTable);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// isotope data are not available or applicable
|
||||
G4PhysicsVector* pv = data->GetElementData(Z);
|
||||
if(pv) {
|
||||
G4double e1 = pv->Energy(1);
|
||||
auto pv = GetPhysicsVector(Z);
|
||||
if(!pv) { return xs; }
|
||||
|
||||
if(amin[Z] > 0 && A >= amin[Z] && A <= amax[Z]) {
|
||||
G4PhysicsVector* pviso = data->GetComponentDataByID(Z, A - amin[Z]);
|
||||
if(pviso) {
|
||||
G4double e1 = pviso->Energy(1);
|
||||
if(ekin < e1) {
|
||||
xs = (*pv)[1]*std::sqrt(e1/ekin);
|
||||
} else if(ekin <= pv->GetMaxEnergy()) {
|
||||
xs = pv->Value(ekin, logEkin, fIdxXSTable);
|
||||
xs = (*pviso)[1]*std::sqrt(e1/ekin);
|
||||
} else if(ekin <= pviso->GetMaxEnergy()) {
|
||||
xs = pviso->LogVectorValue(ekin, logEkin);
|
||||
}
|
||||
if(verboseLevel > 0) {
|
||||
G4cout << "G4NeutronCaptureXS::IsoXS: Ekin(MeV)= " << ekin/MeV
|
||||
<< " xs(b)= " << xs/barn
|
||||
<< " Z= " << Z << " A= " << A << G4endl;
|
||||
}
|
||||
return xs;
|
||||
}
|
||||
}
|
||||
// isotope data are not available or applicable
|
||||
G4double e1 = pv->Energy(1);
|
||||
if(ekin < e1) {
|
||||
xs = (*pv)[1]*std::sqrt(e1/ekin);
|
||||
} else if(ekin <= pv->GetMaxEnergy()) {
|
||||
xs = pv->LogVectorValue(ekin, logEkin);
|
||||
}
|
||||
if(verboseLevel > 0) {
|
||||
G4cout << "G4NeutronCaptureXS::IsoXS: Ekin(MeV)= " << ekin/MeV
|
||||
<< " xs(b)= " << xs/barn
|
||||
<< " Z= " << Z << " A= " << A << G4endl;
|
||||
<< " Z= " << Z << " A= " << A << " no iso XS" << G4endl;
|
||||
}
|
||||
return xs;
|
||||
}
|
||||
@@ -223,40 +227,41 @@ G4NeutronCaptureXS::SelectIsotope(const G4Element* anElement,
|
||||
size_t nIso = anElement->GetNumberOfIsotopes();
|
||||
const G4Isotope* iso = anElement->GetIsotope(0);
|
||||
|
||||
//G4cout << "SelectIsotope NIso= " << nIso << G4endl;
|
||||
if(1 == nIso) { return iso; }
|
||||
|
||||
// more than 1 isotope
|
||||
if(1 < nIso) {
|
||||
G4int Z = anElement->GetZasInt();
|
||||
G4int Z = anElement->GetZasInt();
|
||||
|
||||
const G4double* abundVector = anElement->GetRelativeAbundanceVector();
|
||||
G4double q = G4UniformRand();
|
||||
G4double sum = 0.0;
|
||||
const G4double* abundVector = anElement->GetRelativeAbundanceVector();
|
||||
G4double q = G4UniformRand();
|
||||
G4double sum = 0.0;
|
||||
|
||||
// is there isotope wise cross section?
|
||||
size_t j;
|
||||
if(0 == amin[Z] || Z >= MAXZCAPTURE) {
|
||||
for (j = 0; j<nIso; ++j) {
|
||||
sum += abundVector[j];
|
||||
if(q <= sum) {
|
||||
iso = anElement->GetIsotope(j);
|
||||
break;
|
||||
}
|
||||
// is there isotope wise cross section?
|
||||
size_t j;
|
||||
if(0 == amin[Z] || Z >= MAXZCAPTURE) {
|
||||
for (j = 0; j<nIso; ++j) {
|
||||
sum += abundVector[j];
|
||||
if(q <= sum) {
|
||||
iso = anElement->GetIsotope(j);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
size_t nn = temp.size();
|
||||
if(nn < nIso) { temp.resize(nIso, 0.); }
|
||||
}
|
||||
return iso;
|
||||
}
|
||||
size_t nn = temp.size();
|
||||
if(nn < nIso) { temp.resize(nIso, 0.); }
|
||||
|
||||
for (j=0; j<nIso; ++j) {
|
||||
sum += abundVector[j]*IsoCrossSection(kinEnergy, logE, Z,
|
||||
anElement->GetIsotope(j)->GetN());
|
||||
temp[j] = sum;
|
||||
}
|
||||
sum *= q;
|
||||
for (j = 0; j<nIso; ++j) {
|
||||
if(temp[j] >= sum) {
|
||||
iso = anElement->GetIsotope(j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (j=0; j<nIso; ++j) {
|
||||
sum += abundVector[j]*IsoCrossSection(kinEnergy, logE, Z,
|
||||
anElement->GetIsotope(j)->GetN());
|
||||
temp[j] = sum;
|
||||
}
|
||||
sum *= q;
|
||||
for (j = 0; j<nIso; ++j) {
|
||||
if(temp[j] >= sum) {
|
||||
iso = anElement->GetIsotope(j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return iso;
|
||||
@@ -286,7 +291,7 @@ G4NeutronCaptureXS::BuildPhysicsTable(const G4ParticleDefinition& p)
|
||||
isMaster = true;
|
||||
data = new G4ElementData();
|
||||
data->SetName("NeutronCapture");
|
||||
temp.resize(13,0.0);
|
||||
FindDirectoryPath();
|
||||
#ifdef G4MULTITHREADED
|
||||
}
|
||||
G4MUTEXUNLOCK(&neutronCaptureXSMutex);
|
||||
@@ -296,39 +301,70 @@ G4NeutronCaptureXS::BuildPhysicsTable(const G4ParticleDefinition& p)
|
||||
// it is possible re-initialisation for the second run
|
||||
if(isMaster) {
|
||||
|
||||
// check environment variable
|
||||
// Build the complete string identifying the file with the data set
|
||||
char* path = getenv("G4PARTICLEXSDATA");
|
||||
|
||||
// Access to elements
|
||||
const G4ElementTable* theElmTable = G4Element::GetElementTable();
|
||||
size_t numOfElm = G4Element::GetNumberOfElements();
|
||||
for(size_t i=0; i<numOfElm; ++i) {
|
||||
G4int Z = std::min(((*theElmTable)[i])->GetZasInt(),MAXZCAPTURE-1);
|
||||
if(!data->GetElementData(Z)) { Initialise(Z, path); }
|
||||
auto theCoupleTable = G4ProductionCutsTable::GetProductionCutsTable();
|
||||
size_t numOfCouples = theCoupleTable->GetTableSize();
|
||||
for(size_t j=0; j<numOfCouples; ++j) {
|
||||
auto mat = theCoupleTable->GetMaterialCutsCouple(j)->GetMaterial();
|
||||
auto elmVec = mat->GetElementVector();
|
||||
size_t numOfElem = mat->GetNumberOfElements();
|
||||
for (size_t ie = 0; ie < numOfElem; ++ie) {
|
||||
G4int Z = std::max(1,std::min(((*elmVec)[ie])->GetZasInt(), MAXZCAPTURE-1));
|
||||
if(!data->GetElementData(Z)) { Initialise(Z); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
G4NeutronCaptureXS::Initialise(G4int Z, const char* p)
|
||||
const G4PhysicsVector* G4NeutronCaptureXS::GetPhysicsVector(G4int Z)
|
||||
{
|
||||
if(data->GetElementData(Z) || Z < 1 || Z >= MAXZCAPTURE) { return; }
|
||||
const char* path = p;
|
||||
const G4PhysicsVector* pv = data->GetElementData(Z);
|
||||
if(!pv) {
|
||||
InitialiseOnFly(Z);
|
||||
pv = data->GetElementData(Z);
|
||||
}
|
||||
return pv;
|
||||
}
|
||||
|
||||
// check environment variable
|
||||
if(!p) {
|
||||
path = getenv("G4PARTICLEXSDATA");
|
||||
if (!path) {
|
||||
G4Exception("G4NeutronCaptureXS::Initialise(..)","had013",FatalException,
|
||||
"Environment variable G4PARTICLEXSDATA is not defined");
|
||||
return;
|
||||
const G4String& G4NeutronCaptureXS::FindDirectoryPath()
|
||||
{
|
||||
// check environment variable
|
||||
// build the complete string identifying the file with the data set
|
||||
if(gDataDirectory.empty()) {
|
||||
char* path = std::getenv("G4PARTICLEXSDATA");
|
||||
if (path) {
|
||||
std::ostringstream ost;
|
||||
ost << path << "/neutron/cap";
|
||||
gDataDirectory = ost.str();
|
||||
} else {
|
||||
G4Exception("G4NeutronCaptureXS::Initialise(..)","had013",
|
||||
FatalException,
|
||||
"Environment variable G4PARTICLEXSDATA is not defined");
|
||||
}
|
||||
}
|
||||
return gDataDirectory;
|
||||
}
|
||||
|
||||
void G4NeutronCaptureXS::InitialiseOnFly(G4int Z)
|
||||
{
|
||||
#ifdef G4MULTITHREADED
|
||||
G4MUTEXLOCK(&neutronCaptureXSMutex);
|
||||
if(!data->GetElementData(Z)) {
|
||||
#endif
|
||||
Initialise(Z);
|
||||
#ifdef G4MULTITHREADED
|
||||
}
|
||||
G4MUTEXUNLOCK(&neutronCaptureXSMutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
void G4NeutronCaptureXS::Initialise(G4int Z)
|
||||
{
|
||||
if(data->GetElementData(Z)) { return; }
|
||||
|
||||
// upload element data
|
||||
std::ostringstream ost;
|
||||
ost << path << "/neutron/cap" << Z ;
|
||||
ost << FindDirectoryPath() << Z ;
|
||||
G4PhysicsVector* v = RetrieveVector(ost, true);
|
||||
data->InitialiseForElement(Z, v);
|
||||
|
||||
@@ -339,7 +375,7 @@ G4NeutronCaptureXS::Initialise(G4int Z, const char* p)
|
||||
|
||||
for(G4int A=amin[Z]; A<=amax[Z]; ++A) {
|
||||
std::ostringstream ost1;
|
||||
ost1 << path << "/neutron/cap" << Z << "_" << A;
|
||||
ost1 << gDataDirectory << Z << "_" << A;
|
||||
v = RetrieveVector(ost1, false);
|
||||
data->AddComponent(Z, A, v);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class file
|
||||
@@ -39,15 +38,15 @@
|
||||
#include "G4NeutronElasticXS.hh"
|
||||
#include "G4Neutron.hh"
|
||||
#include "G4DynamicParticle.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4Element.hh"
|
||||
#include "G4ElementTable.hh"
|
||||
#include "G4PhysicsLogVector.hh"
|
||||
#include "G4PhysicsVector.hh"
|
||||
#include "G4ComponentGGHadronNucleusXsc.hh"
|
||||
#include "G4NistManager.hh"
|
||||
#include "G4Neutron.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
@@ -60,6 +59,8 @@ using namespace std;
|
||||
|
||||
G4PhysicsVector* G4NeutronElasticXS::data[] = {nullptr};
|
||||
G4double G4NeutronElasticXS::coeff[] = {0.0};
|
||||
G4double G4NeutronElasticXS::aeff[] = {1.0};
|
||||
G4String G4NeutronElasticXS::gDataDirectory = "";
|
||||
|
||||
#ifdef G4MULTITHREADED
|
||||
G4Mutex G4NeutronElasticXS::neutronElasticXSMutex = G4MUTEX_INITIALIZER;
|
||||
@@ -69,7 +70,6 @@ G4NeutronElasticXS::G4NeutronElasticXS()
|
||||
: G4VCrossSectionDataSet(Default_Name()),
|
||||
ggXsection(nullptr),
|
||||
neutron(G4Neutron::Neutron()),
|
||||
fIdxXSTable(0),
|
||||
isMaster(false)
|
||||
{
|
||||
// verboseLevel = 0;
|
||||
@@ -80,6 +80,7 @@ G4NeutronElasticXS::G4NeutronElasticXS()
|
||||
nist = G4NistManager::Instance();
|
||||
ggXsection = new G4ComponentGGHadronNucleusXsc();
|
||||
SetForAllAtomsAndEnergies(true);
|
||||
temp.resize(13,0.0);
|
||||
}
|
||||
|
||||
G4NeutronElasticXS::~G4NeutronElasticXS()
|
||||
@@ -108,6 +109,13 @@ G4NeutronElasticXS::IsElementApplicable(const G4DynamicParticle*,
|
||||
return true;
|
||||
}
|
||||
|
||||
G4bool G4NeutronElasticXS::IsIsoApplicable(const G4DynamicParticle*,
|
||||
G4int, G4int,
|
||||
const G4Element*, const G4Material*)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
G4double
|
||||
G4NeutronElasticXS::GetElementCrossSection(const G4DynamicParticle* aParticle,
|
||||
G4int ZZ, const G4Material*)
|
||||
@@ -117,30 +125,125 @@ G4NeutronElasticXS::GetElementCrossSection(const G4DynamicParticle* aParticle,
|
||||
|
||||
G4int Z = (ZZ >= MAXZEL) ? MAXZEL - 1 : ZZ;
|
||||
|
||||
G4PhysicsVector* pv = data[Z];
|
||||
auto pv = GetPhysicsVector(Z);
|
||||
if(!pv) { return xs; }
|
||||
// G4cout << "G4NeutronElasticXS::GetCrossSection e= " << ekin
|
||||
// << " Z= " << Z << G4endl;
|
||||
|
||||
// element was not initialised
|
||||
if(ekin <= pv->Energy(0)) {
|
||||
xs = (*pv)[0];
|
||||
} else if(ekin <= pv->GetMaxEnergy()) {
|
||||
xs = pv->LogVectorValue(ekin, aParticle->GetLogKineticEnergy());
|
||||
} else {
|
||||
xs = coeff[Z]*ggXsection->GetElasticElementCrossSection(neutron,
|
||||
ekin, Z, aeff[Z]);
|
||||
}
|
||||
|
||||
if(verboseLevel > 1) {
|
||||
G4cout << "Z= " << Z << " Ekin(MeV)= " << ekin/CLHEP::MeV
|
||||
<< ", nElmXSel(b)= " << xs/CLHEP::barn
|
||||
<< G4endl;
|
||||
}
|
||||
return xs;
|
||||
}
|
||||
|
||||
G4double G4NeutronElasticXS::GetIsoCrossSection(
|
||||
const G4DynamicParticle* aParticle,
|
||||
G4int Z, G4int A,
|
||||
const G4Isotope*, const G4Element*,
|
||||
const G4Material*)
|
||||
{
|
||||
return IsoCrossSection(aParticle->GetKineticEnergy(),
|
||||
aParticle->GetLogKineticEnergy(), Z, A);
|
||||
}
|
||||
|
||||
G4double
|
||||
G4NeutronElasticXS::IsoCrossSection(G4double ekin, G4double logekin,
|
||||
G4int ZZ, G4int A)
|
||||
{
|
||||
G4double xs = 0.0;
|
||||
G4int Z = (ZZ >= MAXZEL) ? MAXZEL - 1 : ZZ;
|
||||
|
||||
// tritium and He3
|
||||
if(3 == A) {
|
||||
return ggXsection->GetElasticElementCrossSection(neutron, ekin, Z, A);
|
||||
}
|
||||
/*
|
||||
G4cout << "IsoCrossSection Z= " << Z << " A= " << A
|
||||
<< " Amin= " << amin[Z] << " Amax= " << amax[Z]
|
||||
<< " E(MeV)= " << ekin << G4endl;
|
||||
*/
|
||||
auto pv = GetPhysicsVector(Z);
|
||||
if(!pv) { return xs; }
|
||||
|
||||
if(ekin <= pv->Energy(0)) {
|
||||
xs = (*pv)[0];
|
||||
} else if(ekin <= pv->GetMaxEnergy()) {
|
||||
xs = pv->Value(ekin, aParticle->GetLogKineticEnergy(), fIdxXSTable);
|
||||
xs = pv->LogVectorValue(ekin, logekin);
|
||||
} else {
|
||||
xs = coeff[Z]*ggXsection->GetElasticElementCrossSection(neutron,
|
||||
ekin, Z, nist->GetAtomicMassAmu(Z));
|
||||
ekin, Z, aeff[Z]);
|
||||
}
|
||||
|
||||
if(verboseLevel > 0){
|
||||
G4cout << "Z= " << Z << " Ekin(MeV)= " << ekin/CLHEP::MeV
|
||||
<< ", nElmXSel(bn)= " << xs/CLHEP::barn
|
||||
<< G4endl;
|
||||
xs *= A/aeff[Z];
|
||||
if(verboseLevel > 1) {
|
||||
G4cout << "G4NeutronElasticXS::IsoXS: Z= " << Z << " A= " << A
|
||||
<< " Ekin(MeV)= " << ekin/CLHEP::MeV
|
||||
<< ", ElmXS(b)= " << xs/CLHEP::barn << G4endl;
|
||||
}
|
||||
return xs;
|
||||
}
|
||||
|
||||
const G4Isotope* G4NeutronElasticXS::SelectIsotope(
|
||||
const G4Element* anElement, G4double kinEnergy, G4double logE)
|
||||
{
|
||||
size_t nIso = anElement->GetNumberOfIsotopes();
|
||||
const G4Isotope* iso = anElement->GetIsotope(0);
|
||||
|
||||
//G4cout << "SelectIsotope NIso= " << nIso << G4endl;
|
||||
if(1 == nIso) { return iso; }
|
||||
|
||||
// more than 1 isotope
|
||||
G4int Z = anElement->GetZasInt();
|
||||
//G4cout << "SelectIsotope Z= " << Z << G4endl;
|
||||
|
||||
const G4double* abundVector = anElement->GetRelativeAbundanceVector();
|
||||
G4double q = G4UniformRand();
|
||||
G4double sum = 0.0;
|
||||
size_t j;
|
||||
|
||||
// isotope wise cross section not used
|
||||
if(anElement->GetNaturalAbundanceFlag()) {
|
||||
for (j=0; j<nIso; ++j) {
|
||||
sum += abundVector[j];
|
||||
if(q <= sum) {
|
||||
iso = anElement->GetIsotope(j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return iso;
|
||||
}
|
||||
|
||||
// use isotope cross sections
|
||||
size_t nn = temp.size();
|
||||
if(nn < nIso) { temp.resize(nIso, 0.); }
|
||||
|
||||
for (j=0; j<nIso; ++j) {
|
||||
//G4cout << j << "-th isotope " << (*isoVector)[j]->GetN()
|
||||
// << " abund= " << abundVector[j] << G4endl;
|
||||
sum += abundVector[j]*IsoCrossSection(kinEnergy, logE, Z,
|
||||
anElement->GetIsotope(j)->GetN());
|
||||
temp[j] = sum;
|
||||
}
|
||||
sum *= q;
|
||||
for (j = 0; j<nIso; ++j) {
|
||||
if(temp[j] >= sum) {
|
||||
iso = anElement->GetIsotope(j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return iso;
|
||||
}
|
||||
|
||||
void
|
||||
G4NeutronElasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
|
||||
{
|
||||
@@ -161,7 +264,7 @@ G4NeutronElasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
|
||||
G4MUTEXLOCK(&neutronElasticXSMutex);
|
||||
if(0. == coeff[0]) {
|
||||
#endif
|
||||
for(G4int i=0; i<MAXZEL; ++i) { coeff[i] = 1.0; }
|
||||
coeff[0] = 1.0;
|
||||
isMaster = true;
|
||||
#ifdef G4MULTITHREADED
|
||||
}
|
||||
@@ -172,41 +275,68 @@ G4NeutronElasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
|
||||
// it is possible re-initialisation for the second run
|
||||
if(isMaster) {
|
||||
|
||||
// check environment variable
|
||||
// Build the complete string identifying the file with the data set
|
||||
char* path = getenv("G4PARTICLEXSDATA");
|
||||
|
||||
// Access to elements
|
||||
const G4ElementTable* theElmTable = G4Element::GetElementTable();
|
||||
size_t numOfElm = G4Element::GetNumberOfElements();
|
||||
for(size_t i=0; i<numOfElm; ++i) {
|
||||
G4int Z = std::min(((*theElmTable)[i])->GetZasInt(),MAXZEL-1);
|
||||
if(!data[Z]) { Initialise(Z, path); }
|
||||
auto theCoupleTable = G4ProductionCutsTable::GetProductionCutsTable();
|
||||
size_t numOfCouples = theCoupleTable->GetTableSize();
|
||||
for(size_t j=0; j<numOfCouples; ++j) {
|
||||
auto mat = theCoupleTable->GetMaterialCutsCouple(j)->GetMaterial();
|
||||
auto elmVec = mat->GetElementVector();
|
||||
size_t numOfElem = mat->GetNumberOfElements();
|
||||
for (size_t ie = 0; ie < numOfElem; ++ie) {
|
||||
G4int Z = std::max(1,std::min(((*elmVec)[ie])->GetZasInt(), MAXZEL-1));
|
||||
if(!data[Z]) { Initialise(Z); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void G4NeutronElasticXS::Initialise(G4int Z, const char* p)
|
||||
G4PhysicsVector* G4NeutronElasticXS::GetPhysicsVector(G4int Z)
|
||||
{
|
||||
if(data[Z]) { return; }
|
||||
const char* path = p;
|
||||
if(!p) {
|
||||
// check environment variable
|
||||
// Build the complete string identifying the file with the data set
|
||||
path = getenv("G4PARTICLEXSDATA");
|
||||
if (!path) {
|
||||
if(!data[Z]) { InitialiseOnFly(Z); }
|
||||
return data[Z];
|
||||
}
|
||||
|
||||
const G4String& G4NeutronElasticXS::FindDirectoryPath()
|
||||
{
|
||||
// check environment variable
|
||||
// build the complete string identifying the file with the data set
|
||||
if(gDataDirectory.empty()) {
|
||||
char* path = std::getenv("G4PARTICLEXSDATA");
|
||||
if (path) {
|
||||
std::ostringstream ost;
|
||||
ost << path << "/neutron/el";
|
||||
gDataDirectory = ost.str();
|
||||
} else {
|
||||
G4Exception("G4NeutronElasticXS::Initialise(..)","had013",
|
||||
FatalException,
|
||||
"Environment variable G4PARTICLEXSDATA is not defined");
|
||||
return;
|
||||
"Environment variable G4PARTICLEXSDATA is not defined");
|
||||
}
|
||||
}
|
||||
return gDataDirectory;
|
||||
}
|
||||
|
||||
void G4NeutronElasticXS::InitialiseOnFly(G4int Z)
|
||||
{
|
||||
#ifdef G4MULTITHREADED
|
||||
G4MUTEXLOCK(&neutronElasticXSMutex);
|
||||
if(!data[Z]) {
|
||||
#endif
|
||||
Initialise(Z);
|
||||
#ifdef G4MULTITHREADED
|
||||
}
|
||||
G4MUTEXUNLOCK(&neutronElasticXSMutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
void G4NeutronElasticXS::Initialise(G4int Z)
|
||||
{
|
||||
if(data[Z]) { return; }
|
||||
|
||||
// upload data from file
|
||||
data[Z] = new G4PhysicsLogVector();
|
||||
|
||||
std::ostringstream ost;
|
||||
ost << path << "/neutron/el" << Z ;
|
||||
ost << FindDirectoryPath() << Z ;
|
||||
std::ifstream filein(ost.str().c_str());
|
||||
if (!(filein)) {
|
||||
G4ExceptionDescription ed;
|
||||
@@ -215,26 +345,26 @@ void G4NeutronElasticXS::Initialise(G4int Z, const char* p)
|
||||
G4Exception("G4NeutronElasticXS::Initialise(..)","had014",
|
||||
FatalException, ed, "Check G4PARTICLEXSDATA");
|
||||
return;
|
||||
} else {
|
||||
if(verboseLevel > 1) {
|
||||
G4cout << "file " << ost.str()
|
||||
<< " is opened by G4NeutronElasticXS" << G4endl;
|
||||
}
|
||||
}
|
||||
if(verboseLevel > 1) {
|
||||
G4cout << "file " << ost.str()
|
||||
<< " is opened by G4NeutronElasticXS" << G4endl;
|
||||
}
|
||||
|
||||
// retrieve data from DB
|
||||
if(!data[Z]->Retrieve(filein, true)) {
|
||||
G4ExceptionDescription ed;
|
||||
ed << "Data file <" << ost.str().c_str()
|
||||
<< "> is not retrieved!";
|
||||
G4Exception("G4NeutronElasticXS::Initialise(..)","had015",
|
||||
FatalException, ed, "Check G4PARTICLEXSDATA");
|
||||
return;
|
||||
}
|
||||
// smooth transition
|
||||
G4double sig1 = (*(data[Z]))[data[Z]->GetVectorLength()-1];
|
||||
G4double ehigh = data[Z]->GetMaxEnergy();
|
||||
G4double sig2 = ggXsection->GetElasticElementCrossSection(neutron,
|
||||
ehigh, Z, nist->GetAtomicMassAmu(Z));
|
||||
if(sig2 > 0.) { coeff[Z] = sig1/sig2; }
|
||||
}
|
||||
// retrieve data from DB
|
||||
if(!data[Z]->Retrieve(filein, true)) {
|
||||
G4ExceptionDescription ed;
|
||||
ed << "Data file <" << ost.str().c_str()
|
||||
<< "> is not retrieved!";
|
||||
G4Exception("G4NeutronElasticXS::Initialise(..)","had015",
|
||||
FatalException, ed, "Check G4PARTICLEXSDATA");
|
||||
return;
|
||||
}
|
||||
// smooth transition
|
||||
G4double sig1 = (*(data[Z]))[data[Z]->GetVectorLength()-1];
|
||||
G4double ehigh = data[Z]->GetMaxEnergy();
|
||||
aeff[Z] = nist->GetAtomicMassAmu(Z);
|
||||
G4double sig2 = ggXsection->GetElasticElementCrossSection(neutron,
|
||||
ehigh, Z, aeff[Z]);
|
||||
if(sig2 > 0.) { coeff[Z] = sig1/sig2; }
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class file
|
||||
@@ -38,15 +37,16 @@
|
||||
#include "G4NeutronInelasticXS.hh"
|
||||
#include "G4Neutron.hh"
|
||||
#include "G4DynamicParticle.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4Element.hh"
|
||||
#include "G4ElementTable.hh"
|
||||
#include "G4PhysicsLogVector.hh"
|
||||
#include "G4PhysicsVector.hh"
|
||||
#include "G4ComponentGGHadronNucleusXsc.hh"
|
||||
#include "G4NistManager.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
@@ -83,8 +83,9 @@ const G4int G4NeutronInelasticXS::amax[] = {
|
||||
0, 238};
|
||||
|
||||
G4double G4NeutronInelasticXS::coeff[] = {1.0};
|
||||
|
||||
G4double G4NeutronInelasticXS::aeff[] = {1.0};
|
||||
G4ElementData* G4NeutronInelasticXS::data = nullptr;
|
||||
G4String G4NeutronInelasticXS::gDataDirectory = "";
|
||||
|
||||
#ifdef G4MULTITHREADED
|
||||
G4Mutex G4NeutronInelasticXS::neutronInelasticXSMutex = G4MUTEX_INITIALIZER;
|
||||
@@ -92,8 +93,7 @@ G4ElementData* G4NeutronInelasticXS::data = nullptr;
|
||||
|
||||
G4NeutronInelasticXS::G4NeutronInelasticXS()
|
||||
: G4VCrossSectionDataSet(Default_Name()),
|
||||
neutron(G4Neutron::Neutron()),
|
||||
emax(20*CLHEP::MeV)
|
||||
neutron(G4Neutron::Neutron())
|
||||
{
|
||||
// verboseLevel = 0;
|
||||
if(verboseLevel > 0){
|
||||
@@ -104,7 +104,7 @@ G4NeutronInelasticXS::G4NeutronInelasticXS()
|
||||
nist = G4NistManager::Instance();
|
||||
SetForAllAtomsAndEnergies(true);
|
||||
isMaster = false;
|
||||
fIdxXSTable = 0;
|
||||
temp.resize(13,0.0);
|
||||
}
|
||||
|
||||
G4NeutronInelasticXS::~G4NeutronInelasticXS()
|
||||
@@ -145,23 +145,24 @@ G4double G4NeutronInelasticXS::GetElementCrossSection(
|
||||
|
||||
G4int Z = (ZZ >= MAXZINEL) ? MAXZINEL - 1 : ZZ;
|
||||
|
||||
const G4PhysicsVector* pv = data->GetElementData(Z);
|
||||
auto pv = GetPhysicsVector(Z);
|
||||
if(!pv) { return xs; }
|
||||
// G4cout << "G4NeutronInelasticXS::GetCrossSection e= " << ekin
|
||||
// << " Z= " << Z << G4endl;
|
||||
|
||||
// element was not initialised or low energy
|
||||
if(!pv || ekin <= pv->Energy(0)) { return xs; }
|
||||
// below threshold
|
||||
if(ekin <= pv->Energy(0)) { return xs; }
|
||||
|
||||
if(ekin <= pv->GetMaxEnergy()) {
|
||||
xs = pv->Value(ekin, aParticle->GetLogKineticEnergy(), fIdxXSTable);
|
||||
xs = pv->LogVectorValue(ekin, aParticle->GetLogKineticEnergy());
|
||||
} else {
|
||||
xs = coeff[Z]*ggXsection->GetInelasticElementCrossSection(neutron,
|
||||
ekin, Z, nist->GetAtomicMassAmu(Z));
|
||||
ekin, Z, aeff[Z]);
|
||||
}
|
||||
|
||||
if(verboseLevel > 0) {
|
||||
if(verboseLevel > 1) {
|
||||
G4cout << "Z= " << Z << " Ekin(MeV)= " << ekin/CLHEP::MeV
|
||||
<< ", nElmXSinel(bn)= " << xs/CLHEP::barn
|
||||
<< ", ElmXSinel(b)= " << xs/CLHEP::barn
|
||||
<< G4endl;
|
||||
}
|
||||
return xs;
|
||||
@@ -184,26 +185,50 @@ G4NeutronInelasticXS::IsoCrossSection(G4double ekin, G4double logekin,
|
||||
G4double xs = 0.0;
|
||||
G4int Z = (ZZ >= MAXZINEL) ? MAXZINEL - 1 : ZZ;
|
||||
|
||||
// tritium and He3
|
||||
if(3 == A) {
|
||||
return ggXsection->GetInelasticElementCrossSection(neutron, ekin, Z, A);
|
||||
}
|
||||
|
||||
/*
|
||||
G4cout << "IsoCrossSection Z= " << Z << " A= " << A
|
||||
<< " Amin= " << amin[Z] << " Amax= " << amax[Z]
|
||||
<< " E(MeV)= " << ekin << G4endl;
|
||||
*/
|
||||
// compute isotope cross section if applicable
|
||||
if(ekin <= emax && amin[Z] > 0) {
|
||||
if(A >= amin[Z] && A <= amax[Z]) {
|
||||
G4PhysicsVector* pviso = data->GetComponentDataByIndex(Z, A - amin[Z]);
|
||||
if(pviso) { xs = pviso->Value(ekin, logekin, fIdxXSTable); }
|
||||
auto pv = GetPhysicsVector(Z);
|
||||
if(!pv) { return xs; }
|
||||
|
||||
// below threshold
|
||||
if(ekin <= pv->Energy(0)) { return xs; }
|
||||
|
||||
// compute isotope cross section if applicable
|
||||
G4double emax = pv->GetMaxEnergy();
|
||||
if(ekin <= emax && amin[Z] > 0 && A >= amin[Z] && A <= amax[Z]) {
|
||||
auto pviso = data->GetComponentDataByIndex(Z, A - amin[Z]);
|
||||
if(pviso) {
|
||||
xs = pviso->LogVectorValue(ekin, logekin);
|
||||
if(verboseLevel > 1) {
|
||||
G4cout << "G4NeutronInelasticXS::IsoXS: Ekin(MeV)= "
|
||||
<< ekin/CLHEP::MeV
|
||||
<< " xs(b)= " << xs/CLHEP::barn
|
||||
<< " Z= " << Z << " A= " << A << G4endl;
|
||||
}
|
||||
return xs;
|
||||
}
|
||||
} else {
|
||||
// isotope data are not available or applicable
|
||||
G4PhysicsVector* pv = data->GetElementData(Z);
|
||||
if(pv) { xs = pv->Value(ekin, logekin, fIdxXSTable); }
|
||||
}
|
||||
if(verboseLevel > 0) {
|
||||
G4cout << "IsoXS: Z= " << Z << " A= " << A
|
||||
|
||||
// use element x-section
|
||||
if(ekin <= emax) {
|
||||
xs = pv->LogVectorValue(ekin, logekin);
|
||||
} else {
|
||||
xs = coeff[Z]*ggXsection->GetInelasticElementCrossSection(neutron,
|
||||
ekin, Z, aeff[Z]);
|
||||
}
|
||||
xs *= A/aeff[Z];
|
||||
if(verboseLevel > 1) {
|
||||
G4cout << "G4NeutronInelasticXS::IsoXS: Z= " << Z << " A= " << A
|
||||
<< " Ekin(MeV)= " << ekin/CLHEP::MeV
|
||||
<< ", nElmXSinel(bn)= " << xs/CLHEP::barn << G4endl;
|
||||
<< ", ElmXS(b)= " << xs/CLHEP::barn << G4endl;
|
||||
}
|
||||
return xs;
|
||||
}
|
||||
@@ -224,11 +249,11 @@ const G4Isotope* G4NeutronInelasticXS::SelectIsotope(
|
||||
const G4double* abundVector = anElement->GetRelativeAbundanceVector();
|
||||
G4double q = G4UniformRand();
|
||||
G4double sum = 0.0;
|
||||
size_t j;
|
||||
|
||||
// isotope wise cross section not available
|
||||
size_t j;
|
||||
if(kinEnergy > emax || 0 == amin[Z] || Z >= MAXZINEL) {
|
||||
for (j = 0; j<nIso; ++j) {
|
||||
if(0 == amin[Z] || Z >= MAXZINEL) {
|
||||
for (j=0; j<nIso; ++j) {
|
||||
sum += abundVector[j];
|
||||
if(q <= sum) {
|
||||
iso = anElement->GetIsotope(j);
|
||||
@@ -262,7 +287,7 @@ const G4Isotope* G4NeutronInelasticXS::SelectIsotope(
|
||||
void
|
||||
G4NeutronInelasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
|
||||
{
|
||||
if(verboseLevel > 0){
|
||||
if(verboseLevel > 0) {
|
||||
G4cout << "G4NeutronInelasticXS::BuildPhysicsTable for "
|
||||
<< p.GetParticleName() << G4endl;
|
||||
}
|
||||
@@ -283,7 +308,7 @@ G4NeutronInelasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
|
||||
isMaster = true;
|
||||
data = new G4ElementData();
|
||||
data->SetName("NeutronInelastic");
|
||||
temp.resize(13,0.0);
|
||||
FindDirectoryPath();
|
||||
#ifdef G4MULTITHREADED
|
||||
}
|
||||
G4MUTEXUNLOCK(&neutronInelasticXSMutex);
|
||||
@@ -293,43 +318,70 @@ G4NeutronInelasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
|
||||
// it is possible re-initialisation for the new run
|
||||
if(isMaster) {
|
||||
|
||||
// check environment variable
|
||||
// Build the complete string identifying the file with the data set
|
||||
char* path = getenv("G4PARTICLEXSDATA");
|
||||
|
||||
// Access to elements
|
||||
const G4ElementTable* theElmTable = G4Element::GetElementTable();
|
||||
size_t numOfElm = G4Element::GetNumberOfElements();
|
||||
for(size_t i=0; i<numOfElm; ++i) {
|
||||
G4int Z = ((*theElmTable)[i])->GetZasInt();
|
||||
if(Z >= MAXZINEL) { Z = MAXZINEL-1; }
|
||||
// Initialisation
|
||||
if(!(data->GetElementData(Z))) {
|
||||
Initialise(Z, path);
|
||||
auto theCoupleTable = G4ProductionCutsTable::GetProductionCutsTable();
|
||||
size_t numOfCouples = theCoupleTable->GetTableSize();
|
||||
for(size_t j=0; j<numOfCouples; ++j) {
|
||||
auto mat = theCoupleTable->GetMaterialCutsCouple(j)->GetMaterial();
|
||||
auto elmVec = mat->GetElementVector();
|
||||
size_t numOfElem = mat->GetNumberOfElements();
|
||||
for (size_t ie = 0; ie < numOfElem; ++ie) {
|
||||
G4int Z = std::max(1,std::min(((*elmVec)[ie])->GetZasInt(), MAXZINEL-1));
|
||||
if(!data->GetElementData(Z)) { Initialise(Z); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
G4NeutronInelasticXS::Initialise(G4int Z, const char* p)
|
||||
const G4PhysicsVector* G4NeutronInelasticXS::GetPhysicsVector(G4int Z)
|
||||
{
|
||||
if(data->GetElementData(Z) || Z < 1 || Z >= MAXZINEL) { return; }
|
||||
const char* path = p;
|
||||
if(!p) {
|
||||
// check environment variable
|
||||
// Build the complete string identifying the file with the data set
|
||||
path = getenv("G4PARTICLEXSDATA");
|
||||
if (!path) {
|
||||
const G4PhysicsVector* pv = data->GetElementData(Z);
|
||||
if(!pv) {
|
||||
InitialiseOnFly(Z);
|
||||
pv = data->GetElementData(Z);
|
||||
}
|
||||
return pv;
|
||||
}
|
||||
|
||||
const G4String& G4NeutronInelasticXS::FindDirectoryPath()
|
||||
{
|
||||
// check environment variable
|
||||
// build the complete string identifying the file with the data set
|
||||
if(gDataDirectory.empty()) {
|
||||
char* path = std::getenv("G4PARTICLEXSDATA");
|
||||
if (path) {
|
||||
std::ostringstream ost;
|
||||
ost << path << "/neutron/inel";
|
||||
gDataDirectory = ost.str();
|
||||
} else {
|
||||
G4Exception("G4NeutronInelasticXS::Initialise(..)","had013",
|
||||
FatalException,
|
||||
"Environment variable G4PARTICLEXSDATA is not defined");
|
||||
return;
|
||||
"Environment variable G4PARTICLEXSDATA is not defined");
|
||||
}
|
||||
}
|
||||
return gDataDirectory;
|
||||
}
|
||||
|
||||
void G4NeutronInelasticXS::InitialiseOnFly(G4int Z)
|
||||
{
|
||||
#ifdef G4MULTITHREADED
|
||||
G4MUTEXLOCK(&neutronInelasticXSMutex);
|
||||
if(!data->GetElementData(Z)) {
|
||||
#endif
|
||||
Initialise(Z);
|
||||
#ifdef G4MULTITHREADED
|
||||
}
|
||||
G4MUTEXUNLOCK(&neutronInelasticXSMutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
void G4NeutronInelasticXS::Initialise(G4int Z)
|
||||
{
|
||||
if(data->GetElementData(Z)) { return; }
|
||||
|
||||
// upload element data
|
||||
std::ostringstream ost;
|
||||
ost << path << "/neutron/inel" << Z ;
|
||||
ost << FindDirectoryPath() << Z;
|
||||
G4PhysicsVector* v = RetrieveVector(ost, true);
|
||||
data->InitialiseForElement(Z, v);
|
||||
/*
|
||||
@@ -344,7 +396,7 @@ G4NeutronInelasticXS::Initialise(G4int Z, const char* p)
|
||||
|
||||
for(G4int A=amin[Z]; A<=amax[Z]; ++A) {
|
||||
std::ostringstream ost1;
|
||||
ost1 << path << "/neutron/inel" << Z << "_" << A;
|
||||
ost1 << gDataDirectory << Z << "_" << A;
|
||||
G4PhysicsVector* v1 = RetrieveVector(ost1, false);
|
||||
data->AddComponent(Z, A, v1);
|
||||
}
|
||||
@@ -353,8 +405,9 @@ G4NeutronInelasticXS::Initialise(G4int Z, const char* p)
|
||||
// smooth transition
|
||||
G4double sig1 = (*v)[v->GetVectorLength()-1];
|
||||
G4double ehigh= v->GetMaxEnergy();
|
||||
aeff[Z] = nist->GetAtomicMassAmu(Z);
|
||||
G4double sig2 = ggXsection->GetInelasticElementCrossSection(neutron,
|
||||
ehigh, Z, nist->GetAtomicMassAmu(Z));
|
||||
ehigh, Z, aeff[Z]);
|
||||
if(sig2 > 0.) { coeff[Z] = sig1/sig2; }
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class file
|
||||
@@ -39,8 +38,9 @@
|
||||
#include "G4ParticleInelasticXS.hh"
|
||||
#include "G4Neutron.hh"
|
||||
#include "G4DynamicParticle.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4Element.hh"
|
||||
#include "G4ElementTable.hh"
|
||||
#include "G4PhysicsLogVector.hh"
|
||||
#include "G4PhysicsVector.hh"
|
||||
#include "G4ComponentGGHadronNucleusXsc.hh"
|
||||
@@ -48,8 +48,8 @@
|
||||
#include "G4NistManager.hh"
|
||||
#include "G4Proton.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
@@ -81,8 +81,9 @@ const G4int G4ParticleInelasticXS::amax[] = {
|
||||
0, 238};
|
||||
|
||||
G4double G4ParticleInelasticXS::coeff[] = {1.0};
|
||||
|
||||
G4double G4ParticleInelasticXS::aeff[] = {1.0};
|
||||
G4ElementData* G4ParticleInelasticXS::data = nullptr;
|
||||
G4String G4ParticleInelasticXS::gDataDirectory = "";
|
||||
|
||||
#ifdef G4MULTITHREADED
|
||||
G4Mutex G4ParticleInelasticXS::particleInelasticXSMutex = G4MUTEX_INITIALIZER;
|
||||
@@ -94,8 +95,6 @@ G4ParticleInelasticXS::G4ParticleInelasticXS(const G4ParticleDefinition* part)
|
||||
nnXsection(nullptr),
|
||||
particle(part),
|
||||
proton(G4Proton::Proton()),
|
||||
emax(20*CLHEP::MeV),
|
||||
fIdxXSTable(0),
|
||||
isMaster(false)
|
||||
{
|
||||
if(!part) {
|
||||
@@ -116,6 +115,7 @@ G4ParticleInelasticXS::G4ParticleInelasticXS(const G4ParticleDefinition* part)
|
||||
}
|
||||
SetForAllAtomsAndEnergies(true);
|
||||
fNist = G4NistManager::Instance();
|
||||
temp.resize(13,0.0);
|
||||
}
|
||||
|
||||
G4ParticleInelasticXS::~G4ParticleInelasticXS()
|
||||
@@ -156,23 +156,23 @@ G4double G4ParticleInelasticXS::GetElementCrossSection(
|
||||
|
||||
G4int Z = (ZZ >= MAXZINELP) ? MAXZINELP - 1 : ZZ;
|
||||
|
||||
G4PhysicsVector* pv = data->GetElementData(Z);
|
||||
auto pv = GetPhysicsVector(Z);
|
||||
if(!pv) { return xs; }
|
||||
// G4cout << "G4ParticleInelasticXS::GetCrossSection e= " << ekin
|
||||
// << " Z= " << Z << G4endl;
|
||||
|
||||
// element was not initialised or below threshold
|
||||
if(!pv || ekin <= pv->Energy(0)) { return xs; }
|
||||
// below threshold
|
||||
if(ekin <= pv->Energy(0)) { return xs; }
|
||||
|
||||
if(ekin <= pv->GetMaxEnergy()) {
|
||||
xs = pv->Value(ekin, aParticle->GetLogKineticEnergy(), fIdxXSTable);
|
||||
xs = pv->LogVectorValue(ekin, aParticle->GetLogKineticEnergy());
|
||||
} else {
|
||||
G4double Amean = fNist->GetAtomicMassAmu(Z);
|
||||
if(ggXsection) {
|
||||
xs = coeff[Z]*ggXsection->GetInelasticElementCrossSection(particle,
|
||||
ekin, Z, Amean);
|
||||
ekin, Z, aeff[Z]);
|
||||
} else {
|
||||
xs = coeff[Z]*nnXsection->GetInelasticElementCrossSection(particle,
|
||||
ekin, Z, Amean);
|
||||
ekin, Z, aeff[Z]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,23 +200,56 @@ G4ParticleInelasticXS::IsoCrossSection(G4double ekin, G4double logE,
|
||||
{
|
||||
G4double xs = 0.0;
|
||||
G4int Z = (ZZ >= MAXZINELP) ? MAXZINELP - 1 : ZZ;
|
||||
|
||||
// tritium and He3
|
||||
if(3 == A) {
|
||||
if(ggXsection) {
|
||||
xs = ggXsection->GetInelasticElementCrossSection(particle, ekin, Z, A);
|
||||
} else {
|
||||
xs = nnXsection->GetInelasticElementCrossSection(particle, ekin, Z, A);
|
||||
}
|
||||
return xs;
|
||||
}
|
||||
/*
|
||||
G4cout << "IsoCrossSection Z= " << Z << " A= " << A
|
||||
<< " Amin= " << amin[Z] << " Amax= " << amax[Z]
|
||||
<< " E(MeV)= " << ekin << G4endl;
|
||||
*/
|
||||
auto pv = GetPhysicsVector(Z);
|
||||
if(!pv) { return xs; }
|
||||
|
||||
// below threshold
|
||||
if(ekin <= pv->Energy(0)) { return xs; }
|
||||
|
||||
// compute isotope cross section if applicable
|
||||
if(ekin <= emax && amin[Z]>0) {
|
||||
if(A >= amin[Z] && A <= amax[Z]) {
|
||||
G4PhysicsVector* pviso = data->GetComponentDataByIndex(Z, A - amin[Z]);
|
||||
if(pviso) { xs = pviso->Value(ekin, logE, fIdxXSTable); }
|
||||
G4double emax = pv->GetMaxEnergy();
|
||||
if(ekin <= emax && amin[Z]>0 && A >= amin[Z] && A <= amax[Z]) {
|
||||
auto pviso = data->GetComponentDataByIndex(Z, A - amin[Z]);
|
||||
if(pviso) {
|
||||
xs = pviso->LogVectorValue(ekin, logE);
|
||||
if(verboseLevel > 1) {
|
||||
G4cout << "G4ParticleInelasticXS::IsoXS: for "
|
||||
<< particle->GetParticleName() << " Ekin(MeV)= "
|
||||
<< ekin/CLHEP::MeV << " xs(b)= " << xs/CLHEP::barn
|
||||
<< " Z= " << Z << " A= " << A << G4endl;
|
||||
}
|
||||
return xs;
|
||||
}
|
||||
} else {
|
||||
// isotope data are not available or applicable
|
||||
G4PhysicsVector* pv = data->GetElementData(Z);
|
||||
if(pv) { xs = pv->Value(ekin, logE, fIdxXSTable); }
|
||||
}
|
||||
if(verboseLevel > 0) {
|
||||
// use element x-section
|
||||
if(ekin <= emax) {
|
||||
xs = pv->LogVectorValue(ekin, logE);
|
||||
} else {
|
||||
if(ggXsection) {
|
||||
xs = coeff[Z]*ggXsection->GetInelasticElementCrossSection(particle,
|
||||
ekin, Z, aeff[Z]);
|
||||
} else {
|
||||
xs = coeff[Z]*nnXsection->GetInelasticElementCrossSection(particle,
|
||||
ekin, Z, aeff[Z]);
|
||||
}
|
||||
}
|
||||
xs *= A/aeff[Z];
|
||||
if(verboseLevel > 1) {
|
||||
G4cout << "IsoXS for " << particle->GetParticleName()
|
||||
<< " Target Z= " << Z << " A= " << A
|
||||
<< " Ekin(MeV)= " << ekin/CLHEP::MeV
|
||||
@@ -241,11 +274,11 @@ const G4Isotope* G4ParticleInelasticXS::SelectIsotope(
|
||||
const G4double* abundVector = anElement->GetRelativeAbundanceVector();
|
||||
G4double q = G4UniformRand();
|
||||
G4double sum = 0.0;
|
||||
|
||||
// is there isotope wise cross section?
|
||||
size_t j;
|
||||
if(kinEnergy > emax || 0 == amin[Z] || Z >= MAXZINELP) {
|
||||
for (j = 0; j<nIso; ++j) {
|
||||
|
||||
// isotope wise cross section not available
|
||||
if(0 == amin[Z] || Z >= MAXZINELP) {
|
||||
for (j=0; j<nIso; ++j) {
|
||||
sum += abundVector[j];
|
||||
if(q <= sum) {
|
||||
iso = anElement->GetIsotope(j);
|
||||
@@ -266,7 +299,7 @@ const G4Isotope* G4ParticleInelasticXS::SelectIsotope(
|
||||
temp[j] = sum;
|
||||
}
|
||||
sum *= q;
|
||||
for (j = 0; j<nIso; ++j) {
|
||||
for (j=0; j<nIso; ++j) {
|
||||
if(temp[j] >= sum) {
|
||||
iso = anElement->GetIsotope(j);
|
||||
break;
|
||||
@@ -299,7 +332,6 @@ G4ParticleInelasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
|
||||
isMaster = true;
|
||||
data = new G4ElementData();
|
||||
data->SetName(particle->GetParticleName() + "Inelastic");
|
||||
temp.resize(13,0.0);
|
||||
#ifdef G4MULTITHREADED
|
||||
}
|
||||
G4MUTEXUNLOCK(&particleInelasticXSMutex);
|
||||
@@ -309,40 +341,70 @@ G4ParticleInelasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
|
||||
// it is possible re-initialisation for the new run
|
||||
if(isMaster) {
|
||||
|
||||
// check environment variable
|
||||
// Build the complete string identifying the file with the data set
|
||||
char* path = getenv("G4PARTICLEXSDATA");
|
||||
|
||||
// Access to elements
|
||||
const G4ElementTable* theElmTable = G4Element::GetElementTable();
|
||||
size_t numOfElm = G4Element::GetNumberOfElements();
|
||||
for(size_t i=0; i<numOfElm; ++i) {
|
||||
G4int Z = std::min(((*theElmTable)[i])->GetZasInt(), MAXZINELP-1);
|
||||
if(!(data->GetElementData(Z))) { Initialise(Z, path); }
|
||||
auto theCoupleTable = G4ProductionCutsTable::GetProductionCutsTable();
|
||||
size_t numOfCouples = theCoupleTable->GetTableSize();
|
||||
for(size_t j=0; j<numOfCouples; ++j) {
|
||||
auto mat = theCoupleTable->GetMaterialCutsCouple(j)->GetMaterial();
|
||||
auto elmVec = mat->GetElementVector();
|
||||
size_t numOfElem = mat->GetNumberOfElements();
|
||||
for (size_t ie = 0; ie < numOfElem; ++ie) {
|
||||
G4int Z = std::max(1,std::min(((*elmVec)[ie])->GetZasInt(), MAXZINELP-1));
|
||||
if(!data->GetElementData(Z)) { Initialise(Z); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void G4ParticleInelasticXS::Initialise(G4int Z, const char* p)
|
||||
const G4PhysicsVector* G4ParticleInelasticXS::GetPhysicsVector(G4int Z)
|
||||
{
|
||||
if(data->GetElementData(Z)) { return; }
|
||||
const char* path = p;
|
||||
if(!p) {
|
||||
// check environment variable
|
||||
// Build the complete string identifying the file with the data set
|
||||
path = getenv("G4PARTICLEXSDATA");
|
||||
if (!path) {
|
||||
G4Exception("G4ParticleInelasticXS::Initialise(..)","had013",
|
||||
const G4PhysicsVector* pv = data->GetElementData(Z);
|
||||
if(!pv) {
|
||||
InitialiseOnFly(Z);
|
||||
pv = data->GetElementData(Z);
|
||||
}
|
||||
return pv;
|
||||
}
|
||||
|
||||
const G4String& G4ParticleInelasticXS::FindDirectoryPath()
|
||||
{
|
||||
// check environment variable
|
||||
// build the complete string identifying the file with the data set
|
||||
if(gDataDirectory.empty()) {
|
||||
char* path = std::getenv("G4PARTICLEXSDATA");
|
||||
if (path) {
|
||||
std::ostringstream ost;
|
||||
ost << path << "/" << particle->GetParticleName() << "/inel";
|
||||
gDataDirectory = ost.str();
|
||||
} else {
|
||||
G4Exception("G4NeutronInelasticXS::Initialise(..)","had013",
|
||||
FatalException,
|
||||
"Environment variable G4PARTICLEXSDATA is not defined");
|
||||
return;
|
||||
"Environment variable G4PARTICLEXSDATA is not defined");
|
||||
}
|
||||
}
|
||||
return gDataDirectory;
|
||||
}
|
||||
|
||||
void G4ParticleInelasticXS::InitialiseOnFly(G4int Z)
|
||||
{
|
||||
#ifdef G4MULTITHREADED
|
||||
G4MUTEXLOCK(&particleInelasticXSMutex);
|
||||
if(!data->GetElementData(Z)) {
|
||||
#endif
|
||||
Initialise(Z);
|
||||
#ifdef G4MULTITHREADED
|
||||
}
|
||||
G4MUTEXUNLOCK(&particleInelasticXSMutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
void G4ParticleInelasticXS::Initialise(G4int Z)
|
||||
{
|
||||
if(data->GetElementData(Z)) { return; }
|
||||
|
||||
// upload element data
|
||||
G4String particleName = particle->GetParticleName();
|
||||
std::ostringstream ost;
|
||||
ost << path << "/" << particleName << "/inel" << Z ;
|
||||
ost << FindDirectoryPath() << Z ;
|
||||
G4PhysicsVector* v = RetrieveVector(ost, true);
|
||||
data->InitialiseForElement(Z, v);
|
||||
/*
|
||||
@@ -357,7 +419,7 @@ void G4ParticleInelasticXS::Initialise(G4int Z, const char* p)
|
||||
|
||||
for(G4int A=amin[Z]; A<=amax[Z]; ++A) {
|
||||
std::ostringstream ost1;
|
||||
ost1 << path << "/" << particleName << "/inel" << Z << "_" << A;
|
||||
ost1 << gDataDirectory << Z << "_" << A;
|
||||
G4PhysicsVector* v1 = RetrieveVector(ost1, false);
|
||||
data->AddComponent(Z, A, v1);
|
||||
}
|
||||
@@ -366,13 +428,13 @@ void G4ParticleInelasticXS::Initialise(G4int Z, const char* p)
|
||||
G4double sig1 = (*v)[v->GetVectorLength()-1];
|
||||
G4double sig2 = 0.0;
|
||||
G4double ehigh = v->GetMaxEnergy();
|
||||
G4double Amean = fNist->GetAtomicMassAmu(Z);
|
||||
aeff[Z] = fNist->GetAtomicMassAmu(Z);
|
||||
if(ggXsection) {
|
||||
sig2 = ggXsection->GetInelasticElementCrossSection(particle,
|
||||
ehigh, Z, Amean);
|
||||
ehigh, Z, aeff[Z]);
|
||||
} else {
|
||||
sig2 = nnXsection->GetInelasticElementCrossSection(particle,
|
||||
ehigh, Z, Amean);
|
||||
ehigh, Z, aeff[Z]);
|
||||
}
|
||||
if(sig2 > 0.) { coeff[Z] = sig1/sig2; }
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
|
||||
G4int G4UPiNuclearCrossSection::theZ[NZ] =
|
||||
{2,4,6,7,8,11,13,20,26,29,42,48,50,74,82,92};
|
||||
G4int G4UPiNuclearCrossSection::idxZ[93] = {0};
|
||||
G4double G4UPiNuclearCrossSection::theA[NZ] = {0.0};
|
||||
G4double G4UPiNuclearCrossSection::APower[93] = {0.0};
|
||||
|
||||
@@ -65,13 +66,7 @@ G4UPiNuclearCrossSection::G4UPiNuclearCrossSection()
|
||||
piMinus = G4PionMinus::PionMinus();
|
||||
|
||||
aPower = 0.75;
|
||||
elow = 20.0*MeV;
|
||||
elowest = MeV;
|
||||
G4NistManager* nist = G4NistManager::Instance();
|
||||
G4Pow* g4pow = G4Pow::GetInstance();
|
||||
for(G4int i=1; i<93; ++i) {
|
||||
APower[i] = g4pow->powA(nist->GetAtomicMassAmu(i),aPower);
|
||||
}
|
||||
elow = 20.0*CLHEP::MeV;
|
||||
}
|
||||
|
||||
G4UPiNuclearCrossSection::~G4UPiNuclearCrossSection()
|
||||
@@ -107,74 +102,29 @@ G4UPiNuclearCrossSection::IsElementApplicable(const G4DynamicParticle*,
|
||||
return (1 < Z);
|
||||
}
|
||||
|
||||
G4double
|
||||
G4UPiNuclearCrossSection::GetElasticCrossSection(const G4DynamicParticle* dp,
|
||||
G4int Z, G4int A) const
|
||||
{
|
||||
G4double cross = 0.0;
|
||||
const G4ParticleDefinition* part = dp->GetDefinition();
|
||||
G4PhysicsTable* table = (part == piPlus) ? piPlusElastic : piMinusElastic;
|
||||
if(table) {
|
||||
cross = Interpolate(Z, A, dp->GetKineticEnergy(),table);
|
||||
}
|
||||
return cross;
|
||||
}
|
||||
|
||||
G4double
|
||||
G4UPiNuclearCrossSection::GetInelasticCrossSection(const G4DynamicParticle* dp,
|
||||
G4int Z, G4int A) const
|
||||
{
|
||||
G4double cross = 0.0;
|
||||
G4double fact = 1.0;
|
||||
G4double ekin = dp->GetKineticEnergy();
|
||||
G4PhysicsTable* table = nullptr;
|
||||
const G4ParticleDefinition* part = dp->GetDefinition();
|
||||
|
||||
// Coulomb barrier
|
||||
if(part == piPlus) {
|
||||
if(ekin > elowest) {
|
||||
table = piPlusInelastic;
|
||||
if(ekin < elow) {
|
||||
fact = std::sqrt((ekin-elowest)/(elow-elowest));
|
||||
ekin = elow;
|
||||
}
|
||||
}
|
||||
} else if(part == piMinus) {
|
||||
table = piMinusInelastic;
|
||||
ekin = std::max(ekin,elow);
|
||||
}
|
||||
if(table) {
|
||||
cross = fact*Interpolate(Z, A, ekin, table);
|
||||
}
|
||||
return cross;
|
||||
}
|
||||
|
||||
G4double G4UPiNuclearCrossSection::Interpolate(
|
||||
G4int Z, G4int A, G4double ekin, G4PhysicsTable* table) const
|
||||
G4int Z, G4int A, G4double e, const G4PhysicsTable* table) const
|
||||
{
|
||||
G4double res = 0.0;
|
||||
G4int idx;
|
||||
G4int iz = std::min(Z, 92);
|
||||
for(idx=0; idx<NZ; ++idx) { if(theZ[idx] >= iz) break; }
|
||||
if(idx >= NZ) { idx = NZ - 1; }
|
||||
G4int iz2 = theZ[idx];
|
||||
// G4cout << "U: iz= " << iz << " iz2= " << iz2 << " "
|
||||
// << APower[iz] << " " << APower[iz2]<<G4endl;
|
||||
G4double x2 = (((*table)[idx])->Value(ekin))*APower[iz]/APower[iz2];
|
||||
|
||||
// use only one Z
|
||||
if(iz >= theZ[idx] || idx == 0) {
|
||||
res = x2;
|
||||
|
||||
// Interpolation between Z
|
||||
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);
|
||||
//G4cout << "Interpolate: Z= " << iz << " A= " << A << " idx= " << idx
|
||||
// << " jdx= " << jdx << " Ekin= " << ekin << G4endl;
|
||||
if(idx < 0 || 2 == iz) {
|
||||
res = ((*table)[std::abs(idx)])->Value(ekin, jdx);
|
||||
//G4cout << "1: jdx= " << jdx << G4endl;
|
||||
} else {
|
||||
|
||||
G4int iz2 = theZ[idx];
|
||||
G4double x2 = (((*table)[idx])->Value(ekin, jdx))*APower[iz]/APower[iz2];
|
||||
//G4cout << "2: jdx= " << jdx << G4endl;
|
||||
G4int iz1 = theZ[idx-1];
|
||||
G4double x1 = (((*table)[idx-1])->Value(ekin))*APower[iz]/APower[iz1];
|
||||
G4double w1 = G4double(A) - theA[idx-1];
|
||||
G4double w2 = theA[idx] - G4double(A);
|
||||
res = (w1*x2 + w2*x1)/(w1 + w2);
|
||||
G4double x1 = (((*table)[idx-1])->Value(ekin, jdx))*APower[iz]/APower[iz1];
|
||||
G4double w1 = ((G4double)A - theA[idx-1])/(theA[idx] - theA[idx-1]);
|
||||
res = w1*x2 + (1.0 - w1)*x1;
|
||||
}
|
||||
//G4cout << " res(nb)= " << res/CLHEP::barn << G4endl;
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -218,6 +168,8 @@ 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) {
|
||||
@@ -243,9 +195,22 @@ void G4UPiNuclearCrossSection::BuildPhysicsTable(const G4ParticleDefinition& p)
|
||||
if(!isMaster) { return; }
|
||||
|
||||
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);
|
||||
}
|
||||
G4int idx = 1;
|
||||
for(G4int i=3; i<93; ++i) {
|
||||
if(theZ[idx] == i) {
|
||||
idxZ[i] = -idx;
|
||||
++idx;
|
||||
} else {
|
||||
idxZ[i] = idx;
|
||||
}
|
||||
}
|
||||
|
||||
piPlusElastic = new G4PhysicsTable();
|
||||
piPlusInelastic = new G4PhysicsTable();
|
||||
@@ -253,6 +218,7 @@ void G4UPiNuclearCrossSection::BuildPhysicsTable(const G4ParticleDefinition& p)
|
||||
piMinusInelastic = new G4PhysicsTable();
|
||||
|
||||
LoadData();
|
||||
//G4cout << "### Initialisation done " << G4endl;
|
||||
}
|
||||
|
||||
void G4UPiNuclearCrossSection::LoadData()
|
||||
|
||||
@@ -14,6 +14,36 @@ code and to keep track of all tags.
|
||||
* Please list in reverse chronological order (last date on top)
|
||||
---------------------------------------------------------------
|
||||
|
||||
11 November 2019 A. Ribon (hadr-man-V10-05-07)
|
||||
---------------------------------------------------
|
||||
- G4HadronicProcess : in the method CheckResult, a short-lived secondary
|
||||
particle is allowed to have a dynamic mass which differ from the PDG mass
|
||||
by less than three times the particle's width.
|
||||
|
||||
17 October 2019 V. Ivanchenko (hadr-man-V10-05-06)
|
||||
---------------------------------------------------
|
||||
- G4HadronicProcess : for particle out of the mass shell correct
|
||||
kinetic energy in a way, that it is always above 10 keV;
|
||||
use std::getenv method recommended for concurrency
|
||||
|
||||
12 September 2019 V. Ivanchenko (hadr-man-V10-05-05)
|
||||
---------------------------------------------------
|
||||
- G4HadronicProcess : fixed Coverity warnings
|
||||
|
||||
21 August 2019 V. Ivanchenko (hadr-man-V10-05-04)
|
||||
---------------------------------------------------
|
||||
- G4EnergyRangeManager : move operators to be private, removed
|
||||
obsolete method, removed G4HadronicException, instead in case of
|
||||
problem return nullptr
|
||||
- G4HadronicProcess : do not use try/catch pattern to choose hadronic
|
||||
interaction; decrease limit on check of offshell mass from 1.5 MeV
|
||||
to 10 keV - fixed problem 2175; removed unused headers
|
||||
|
||||
13 July 2019 V. Ivanchenko (hadr-man-V10-05-03)
|
||||
---------------------------------------------------
|
||||
- G4EnergyRangeManager : added short cut - if only one model registered
|
||||
for a process no check is applied; implemented C++11 paterns
|
||||
|
||||
11 June 2019 A. Ribon (hadr-man-V10-05-02)
|
||||
---------------------------------------------------
|
||||
- G4EnergyRangeManager : fixed bug regarding the kinetic energy per nucleon
|
||||
|
||||
@@ -43,29 +43,13 @@ public:
|
||||
explicit G4EnergyRangeManager();
|
||||
|
||||
~G4EnergyRangeManager();
|
||||
|
||||
void RegisterMe(G4HadronicInteraction* a);
|
||||
|
||||
G4EnergyRangeManager(const G4EnergyRangeManager& right);
|
||||
|
||||
G4EnergyRangeManager& operator=( const G4EnergyRangeManager &right );
|
||||
|
||||
inline G4bool operator==( const G4EnergyRangeManager &right ) const
|
||||
{ return ( this == (G4EnergyRangeManager *) &right ); }
|
||||
|
||||
inline G4bool operator!=( const G4EnergyRangeManager &right ) const
|
||||
{ return ( this != (G4EnergyRangeManager *) &right ); }
|
||||
|
||||
void RegisterMe( G4HadronicInteraction *a );
|
||||
|
||||
G4HadronicInteraction *GetHadronicInteraction(const G4HadProjectile & aHadProjectile,
|
||||
G4HadronicInteraction* GetHadronicInteraction(const G4HadProjectile & aHadProjectile,
|
||||
G4Nucleus & aTargetNucleus,
|
||||
const G4Material *aMaterial,
|
||||
const G4Element *anElement ) const;
|
||||
// This is the new one to be used.
|
||||
|
||||
G4HadronicInteraction *GetHadronicInteraction(const G4double kineticEnergy,
|
||||
const G4Material *aMaterial,
|
||||
const G4Element *anElement ) const;
|
||||
// This is the old, deprecated one, which will be removed later on.
|
||||
|
||||
std::vector<G4HadronicInteraction*>& GetHadronicInteractionList();
|
||||
|
||||
@@ -74,6 +58,11 @@ public:
|
||||
void BuildPhysicsTable(const G4ParticleDefinition&);
|
||||
|
||||
private:
|
||||
|
||||
G4EnergyRangeManager(const G4EnergyRangeManager& right);
|
||||
G4EnergyRangeManager& operator=( const G4EnergyRangeManager &right );
|
||||
G4bool operator==( const G4EnergyRangeManager &right ) const;
|
||||
G4bool operator!=( const G4EnergyRangeManager &right ) const;
|
||||
|
||||
G4int theHadronicInteractionCounter;
|
||||
std::vector<G4HadronicInteraction*> theHadronicInteraction;
|
||||
|
||||
@@ -204,8 +204,8 @@ private:
|
||||
G4double XBiasSecondaryWeight();
|
||||
|
||||
// hide assignment operator as private
|
||||
G4HadronicProcess& operator=(const G4HadronicProcess& right) = delete;
|
||||
G4HadronicProcess(const G4HadronicProcess&) = delete;
|
||||
G4HadronicProcess& operator=(const G4HadronicProcess& right);
|
||||
G4HadronicProcess(const G4HadronicProcess&);
|
||||
|
||||
// Set E/p conservation check levels from environment variables
|
||||
void GetEnergyMomentumCheckEnvvars();
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "G4EnergyRangeManager.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4HadronicException.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
|
||||
G4EnergyRangeManager::G4EnergyRangeManager()
|
||||
: theHadronicInteractionCounter(0)
|
||||
@@ -42,22 +43,6 @@ G4EnergyRangeManager::G4EnergyRangeManager()
|
||||
G4EnergyRangeManager::~G4EnergyRangeManager()
|
||||
{}
|
||||
|
||||
G4EnergyRangeManager::G4EnergyRangeManager(const G4EnergyRangeManager& right)
|
||||
{
|
||||
theHadronicInteractionCounter = right.theHadronicInteractionCounter;
|
||||
theHadronicInteraction = right.theHadronicInteraction;
|
||||
}
|
||||
|
||||
G4EnergyRangeManager& G4EnergyRangeManager::operator=(
|
||||
const G4EnergyRangeManager& right)
|
||||
{
|
||||
if (this != &right) {
|
||||
theHadronicInteractionCounter = right.theHadronicInteractionCounter;
|
||||
theHadronicInteraction = right.theHadronicInteraction;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void G4EnergyRangeManager::RegisterMe(G4HadronicInteraction* a)
|
||||
{
|
||||
if(!a) { return; }
|
||||
@@ -70,16 +55,18 @@ void G4EnergyRangeManager::RegisterMe(G4HadronicInteraction* a)
|
||||
++theHadronicInteractionCounter;
|
||||
}
|
||||
|
||||
|
||||
G4HadronicInteraction*
|
||||
G4EnergyRangeManager::GetHadronicInteraction(const G4HadProjectile & aHadProjectile,
|
||||
G4Nucleus & aTargetNucleus,
|
||||
const G4Material* aMaterial,
|
||||
const G4Element* anElement) const
|
||||
{
|
||||
if(0 == theHadronicInteractionCounter) {
|
||||
throw G4HadronicException(__FILE__, __LINE__,
|
||||
"GetHadronicInteraction: NO MODELS STORED");
|
||||
// VI shortcut: if only one interaction is registered skip all checks
|
||||
if(1 == theHadronicInteractionCounter) { return theHadronicInteraction[0]; }
|
||||
else if(0 == theHadronicInteractionCounter) {
|
||||
G4cout << "G4EnergyRangeManager::GetHadronicInteraction: "
|
||||
<< "no models defined for a process" << G4endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
G4double kineticEnergy = aHadProjectile.GetKineticEnergy();
|
||||
@@ -94,11 +81,8 @@ G4EnergyRangeManager::GetHadronicInteraction(const G4HadProjectile & aHadProject
|
||||
for (G4int i = 0; i<theHadronicInteractionCounter; ++i) {
|
||||
if ( theHadronicInteraction[i]->IsApplicable( aHadProjectile, aTargetNucleus ) ) {
|
||||
G4double low = theHadronicInteraction[i]->GetMinEnergy( aMaterial, anElement );
|
||||
// Work-around for particles with 0 kinetic energy, which still
|
||||
// require a model to return a ParticleChange
|
||||
//if (low == 0.) low = -DBL_MIN;
|
||||
G4double high = theHadronicInteraction[i]->GetMaxEnergy( aMaterial, anElement );
|
||||
if (low <= kineticEnergy && high > kineticEnergy) {
|
||||
if (low <= kineticEnergy && high >= kineticEnergy) {
|
||||
++cou;
|
||||
emi2 = emi1;
|
||||
ema2 = ema1;
|
||||
@@ -110,158 +94,62 @@ G4EnergyRangeManager::GetHadronicInteraction(const G4HadProjectile & aHadProject
|
||||
}
|
||||
}
|
||||
|
||||
G4int mem = -1;
|
||||
G4double rand;
|
||||
G4HadronicInteraction* hi = nullptr;
|
||||
switch (cou) {
|
||||
case 0:
|
||||
G4cout<<"G4EnergyRangeManager:GetHadronicInteraction: counter="
|
||||
<<theHadronicInteractionCounter<<", Ek="
|
||||
<<kineticEnergy<<", Material = "<<aMaterial->GetName()
|
||||
<<", Element = "
|
||||
<<anElement->GetName()<<G4endl;
|
||||
for( G4int j=0; j<theHadronicInteractionCounter; ++j)
|
||||
{
|
||||
G4HadronicInteraction* HInt=theHadronicInteraction[j];
|
||||
G4cout<<"*"<<j<<"* low=" <<HInt->GetMinEnergy(aMaterial,anElement)
|
||||
<<", high="<<HInt->GetMaxEnergy(aMaterial,anElement)<<G4endl;
|
||||
}
|
||||
throw G4HadronicException(__FILE__, __LINE__,
|
||||
"GetHadronicInteraction: No Model found");
|
||||
return 0;
|
||||
G4cout << "No model found out of " << theHadronicInteractionCounter << G4endl;
|
||||
for( G4int j=0; j<theHadronicInteractionCounter; ++j) {
|
||||
G4HadronicInteraction* hint=theHadronicInteraction[j];
|
||||
G4cout << " "<< j << ". Elow= " << hint->GetMinEnergy(aMaterial,anElement)
|
||||
<<", Ehigh= " << hint->GetMaxEnergy(aMaterial,anElement)
|
||||
<<" " << hint->GetModelName() << G4endl;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
mem = memory;
|
||||
break;
|
||||
hi = theHadronicInteraction[memory];
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if( (emi2<=emi1 && ema2>=ema1) || (emi2>=emi1 && ema2<=ema1) )
|
||||
{
|
||||
G4cout<<"G4EnergyRangeManager:GetHadronicInteraction: counter="
|
||||
<<theHadronicInteractionCounter<<", Ek="
|
||||
<<kineticEnergy<<", Material = "<<aMaterial->GetName()
|
||||
<<", Element = "
|
||||
<<anElement->GetName()<<G4endl;
|
||||
for( G4int j=0; j<theHadronicInteractionCounter; ++j)
|
||||
{
|
||||
G4HadronicInteraction* HInt=theHadronicInteraction[j];
|
||||
G4cout<<"*"<<j<<"* low=" <<HInt->GetMinEnergy(aMaterial,anElement)
|
||||
<<", high="<<HInt->GetMaxEnergy(aMaterial,anElement)<<G4endl;
|
||||
}
|
||||
throw G4HadronicException(__FILE__, __LINE__,
|
||||
"GetHadronicInteraction: Energy ranges of two models fully overlapping");
|
||||
}
|
||||
rand = G4UniformRand();
|
||||
if( emi1 < emi2 )
|
||||
{
|
||||
if( (ema1-kineticEnergy) < rand*(ema1-emi2) ) {
|
||||
mem = memor2;
|
||||
} else {
|
||||
mem = memory;
|
||||
}
|
||||
} else {
|
||||
if( (ema2-kineticEnergy) < rand*(ema2-emi1) ) {
|
||||
mem = memory;
|
||||
} else {
|
||||
mem = memor2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
if( (emi2<=emi1 && ema2>=ema1) || (emi2>=emi1 && ema2<=ema1) ) {
|
||||
G4cout << "Energy ranges of two models fully overlapping " << G4endl;
|
||||
for( G4int j=0; j<theHadronicInteractionCounter; ++j) {
|
||||
G4HadronicInteraction* hint=theHadronicInteraction[j];
|
||||
G4cout << " "<< j << ". Elow= " << hint->GetMinEnergy(aMaterial,anElement)
|
||||
<<", Ehigh= " << hint->GetMaxEnergy(aMaterial,anElement)
|
||||
<<" " << hint->GetModelName() << G4endl;
|
||||
}
|
||||
} else {
|
||||
G4double rand = G4UniformRand();
|
||||
G4int mem;
|
||||
if( emi1 < emi2 ) {
|
||||
if( (ema1-kineticEnergy) < rand*(ema1-emi2) ) {
|
||||
mem = memor2;
|
||||
} else {
|
||||
mem = memory;
|
||||
}
|
||||
} else {
|
||||
if( (ema2-kineticEnergy) < rand*(ema2-emi1) ) {
|
||||
mem = memory;
|
||||
} else {
|
||||
mem = memor2;
|
||||
}
|
||||
}
|
||||
hi = theHadronicInteraction[mem];
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
throw G4HadronicException(__FILE__, __LINE__,
|
||||
"GetHadronicInteraction: More than two competing models in this energy range");
|
||||
G4cout << "More than two competing models for this energy" << G4endl;
|
||||
for( G4int j=0; j<theHadronicInteractionCounter; ++j) {
|
||||
G4HadronicInteraction* hint=theHadronicInteraction[j];
|
||||
G4cout << " "<< j << ". Elow= " << hint->GetMinEnergy(aMaterial,anElement)
|
||||
<<", Ehigh= " << hint->GetMaxEnergy(aMaterial,anElement)
|
||||
<<" " << hint->GetModelName() << G4endl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return theHadronicInteraction[mem];
|
||||
}
|
||||
|
||||
|
||||
G4HadronicInteraction*
|
||||
G4EnergyRangeManager::GetHadronicInteraction(const G4double kineticEnergy,
|
||||
const G4Material* aMaterial,
|
||||
const G4Element* anElement) const
|
||||
{
|
||||
if(0 == theHadronicInteractionCounter) {
|
||||
throw G4HadronicException(__FILE__, __LINE__,
|
||||
"GetHadronicInteraction: NO MODELS STORED");
|
||||
}
|
||||
G4int cou = 0, memory = 0, memor2 = 0;
|
||||
G4double emi1 = 0.0, ema1 = 0.0, emi2 = 0.0, ema2 = 0.0;
|
||||
|
||||
for (G4int i = 0; i<theHadronicInteractionCounter; ++i) {
|
||||
G4double low = theHadronicInteraction[i]->GetMinEnergy( aMaterial, anElement );
|
||||
// Work-around for particles with 0 kinetic energy, which still
|
||||
// require a model to return a ParticleChange
|
||||
//if (low == 0.) low = -DBL_MIN;
|
||||
G4double high = theHadronicInteraction[i]->GetMaxEnergy( aMaterial, anElement );
|
||||
if (low <= kineticEnergy && high > kineticEnergy) {
|
||||
++cou;
|
||||
emi2 = emi1;
|
||||
ema2 = ema1;
|
||||
emi1 = low;
|
||||
ema1 = high;
|
||||
memor2 = memory;
|
||||
memory = i;
|
||||
}
|
||||
}
|
||||
|
||||
G4int mem = -1;
|
||||
G4double rand;
|
||||
switch (cou) {
|
||||
case 0:
|
||||
G4cout<<"G4EnergyRangeManager:GetHadronicInteraction: counter="
|
||||
<<theHadronicInteractionCounter<<", Ek="
|
||||
<<kineticEnergy<<", Material = "<<aMaterial->GetName()
|
||||
<<", Element = "
|
||||
<<anElement->GetName()<<G4endl;
|
||||
for( G4int j=0; j<theHadronicInteractionCounter; ++j)
|
||||
{
|
||||
G4HadronicInteraction* HInt=theHadronicInteraction[j];
|
||||
G4cout<<"*"<<j<<"* low=" <<HInt->GetMinEnergy(aMaterial,anElement)
|
||||
<<", high="<<HInt->GetMaxEnergy(aMaterial,anElement)<<G4endl;
|
||||
}
|
||||
throw G4HadronicException(__FILE__, __LINE__,
|
||||
"GetHadronicInteraction: No Model found");
|
||||
return 0;
|
||||
case 1:
|
||||
mem = memory;
|
||||
break;
|
||||
case 2:
|
||||
if( (emi2<=emi1 && ema2>=ema1) || (emi2>=emi1 && ema2<=ema1) )
|
||||
{
|
||||
G4cout<<"G4EnergyRangeManager:GetHadronicInteraction: counter="
|
||||
<<theHadronicInteractionCounter<<", Ek="
|
||||
<<kineticEnergy<<", Material = "<<aMaterial->GetName()
|
||||
<<", Element = "
|
||||
<<anElement->GetName()<<G4endl;
|
||||
for( G4int j=0; j<theHadronicInteractionCounter; ++j)
|
||||
{
|
||||
G4HadronicInteraction* HInt=theHadronicInteraction[j];
|
||||
G4cout<<"*"<<j<<"* low=" <<HInt->GetMinEnergy(aMaterial,anElement)
|
||||
<<", high="<<HInt->GetMaxEnergy(aMaterial,anElement)<<G4endl;
|
||||
}
|
||||
throw G4HadronicException(__FILE__, __LINE__,
|
||||
"GetHadronicInteraction: Energy ranges of two models fully overlapping");
|
||||
}
|
||||
rand = G4UniformRand();
|
||||
if( emi1 < emi2 )
|
||||
{
|
||||
if( (ema1-kineticEnergy) < rand*(ema1-emi2) ) {
|
||||
mem = memor2;
|
||||
} else {
|
||||
mem = memory;
|
||||
}
|
||||
} else {
|
||||
if( (ema2-kineticEnergy) < rand*(ema2-emi1) ) {
|
||||
mem = memory;
|
||||
} else {
|
||||
mem = memor2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw G4HadronicException(__FILE__, __LINE__,
|
||||
"GetHadronicInteraction: More than two competing models in this energy range");
|
||||
}
|
||||
|
||||
return theHadronicInteraction[mem];
|
||||
return hi;
|
||||
}
|
||||
|
||||
std::vector<G4HadronicInteraction*>&
|
||||
@@ -270,7 +158,6 @@ G4EnergyRangeManager::GetHadronicInteractionList()
|
||||
return theHadronicInteraction;
|
||||
}
|
||||
|
||||
#include "G4SystemOfUnits.hh"
|
||||
void G4EnergyRangeManager::Dump( G4int verbose )
|
||||
{
|
||||
G4cout << "G4EnergyRangeManager " << this << G4endl;
|
||||
@@ -290,10 +177,9 @@ void G4EnergyRangeManager::Dump( G4int verbose )
|
||||
void
|
||||
G4EnergyRangeManager::BuildPhysicsTable(const G4ParticleDefinition& aParticleType)
|
||||
{
|
||||
for ( std::vector<G4HadronicInteraction*>::iterator
|
||||
it = theHadronicInteraction.begin() ; it != theHadronicInteraction.end() ; it++ ) {
|
||||
(*it)->BuildPhysicsTable( aParticleType );
|
||||
}
|
||||
for (auto & hadi : theHadronicInteraction) {
|
||||
hadi->BuildPhysicsTable( aParticleType );
|
||||
}
|
||||
}
|
||||
/* end of file */
|
||||
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
// configure base-class
|
||||
// 28-Sep-2012 Restore inheritance from G4VDiscreteProcess, remove enable-flag
|
||||
// changing, remove warning message from original ctor.
|
||||
// 21-Aug-2019 V.Ivanchenko leave try/catch only for ApplyYourself(..), cleanup
|
||||
|
||||
#include "G4HadronicProcess.hh"
|
||||
|
||||
@@ -56,19 +57,14 @@
|
||||
#include "G4Step.hh"
|
||||
#include "G4Element.hh"
|
||||
#include "G4ParticleChange.hh"
|
||||
#include "G4TransportationManager.hh"
|
||||
#include "G4Navigator.hh"
|
||||
#include "G4ProcessVector.hh"
|
||||
#include "G4ProcessManager.hh"
|
||||
#include "G4StableIsotopes.hh"
|
||||
#include "G4HadTmpUtil.hh"
|
||||
#include "G4NucleiProperties.hh"
|
||||
|
||||
#include "G4HadronicException.hh"
|
||||
#include "G4HadronicProcessStore.hh"
|
||||
#include "G4VCrossSectionDataSet.hh"
|
||||
|
||||
#include "G4AutoLock.hh"
|
||||
#include "G4NistManager.hh"
|
||||
#include "G4PhysicsModelCatalog.hh"
|
||||
#include "G4VLeadingParticleBiasing.hh"
|
||||
@@ -78,11 +74,9 @@
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
// File-scope variable to capture environment variable at startup
|
||||
|
||||
static const char* G4Hadronic_Random_File = getenv("G4HADRONIC_RANDOM_FILE");
|
||||
static const char* G4Hadronic_Random_File = std::getenv("G4HADRONIC_RANDOM_FILE");
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -134,14 +128,14 @@ void G4HadronicProcess::InitialiseLocal() {
|
||||
void G4HadronicProcess::GetEnergyMomentumCheckEnvvars() {
|
||||
levelsSetByProcess = false;
|
||||
|
||||
epReportLevel = getenv("G4Hadronic_epReportLevel") ?
|
||||
strtol(getenv("G4Hadronic_epReportLevel"),0,10) : 0;
|
||||
epReportLevel = std::getenv("G4Hadronic_epReportLevel") ?
|
||||
std::strtol(std::getenv("G4Hadronic_epReportLevel"),0,10) : 0;
|
||||
|
||||
epCheckLevels.first = getenv("G4Hadronic_epCheckRelativeLevel") ?
|
||||
strtod(getenv("G4Hadronic_epCheckRelativeLevel"),0) : DBL_MAX;
|
||||
epCheckLevels.first = std::getenv("G4Hadronic_epCheckRelativeLevel") ?
|
||||
std::strtod(std::getenv("G4Hadronic_epCheckRelativeLevel"),0) : DBL_MAX;
|
||||
|
||||
epCheckLevels.second = getenv("G4Hadronic_epCheckAbsoluteLevel") ?
|
||||
strtod(getenv("G4Hadronic_epCheckAbsoluteLevel"),0) : DBL_MAX;
|
||||
epCheckLevels.second = std::getenv("G4Hadronic_epCheckAbsoluteLevel") ?
|
||||
std::strtod(std::getenv("G4Hadronic_epCheckAbsoluteLevel"),0) : DBL_MAX;
|
||||
}
|
||||
|
||||
void G4HadronicProcess::RegisterMe( G4HadronicInteraction *a )
|
||||
@@ -185,7 +179,7 @@ G4HadronicProcess::GetElementCrossSection(const G4DynamicParticle * part,
|
||||
|
||||
void G4HadronicProcess::PreparePhysicsTable(const G4ParticleDefinition& p)
|
||||
{
|
||||
if(getenv("G4HadronicProcess_debug")) {
|
||||
if(std::getenv("G4HadronicProcess_debug")) {
|
||||
G4HadronicProcess_debug_flag = true;
|
||||
}
|
||||
theProcessStore->RegisterParticle(this, &p);
|
||||
@@ -261,27 +255,29 @@ G4HadronicProcess::PostStepDoIt(const G4Track& aTrack, const G4Step&)
|
||||
// Initialize the hadronic projectile from the track
|
||||
thePro.Initialise(aTrack);
|
||||
|
||||
try
|
||||
{
|
||||
theInteraction =
|
||||
ChooseHadronicInteraction( thePro, targetNucleus, aMaterial, anElement );
|
||||
}
|
||||
catch(G4HadronicException & aE)
|
||||
{
|
||||
theInteraction = ChooseHadronicInteraction(thePro, targetNucleus,
|
||||
aMaterial, anElement);
|
||||
if(!theInteraction) {
|
||||
G4ExceptionDescription ed;
|
||||
aE.Report(ed);
|
||||
ed << "Target element "<<anElement->GetName()<<" Z= "
|
||||
<< targetNucleus.GetZ_asInt() << " A= "
|
||||
<< targetNucleus.GetA_asInt() << G4endl;
|
||||
DumpState(aTrack,"ChooseHadronicInteraction",ed);
|
||||
ed << " No HadronicInteraction found out" << G4endl;
|
||||
G4Exception("G4HadronicProcess::PostStepDoIt", "had005", FatalException,
|
||||
ed);
|
||||
G4Exception("G4HadronicProcess::PostStepDoIt", "had005", FatalException, ed);
|
||||
return theTotalResult;
|
||||
}
|
||||
|
||||
G4HadFinalState* result = nullptr;
|
||||
G4int reentryCount = 0;
|
||||
|
||||
/*
|
||||
G4cout << "### " << aParticle->GetDefinition()->GetParticleName()
|
||||
<< " Ekin(MeV)= " << aParticle->GetKineticEnergy()
|
||||
<< " Z= " << targetNucleus.GetZ_asInt()
|
||||
<< " A= " << targetNucleus.GetA_asInt()
|
||||
<< " by " << theInteraction->GetModelName()
|
||||
<< G4endl;
|
||||
*/
|
||||
do
|
||||
{
|
||||
try
|
||||
@@ -442,8 +438,10 @@ G4HadronicProcess::FillResult(G4HadFinalState * aR, const G4Track & aT)
|
||||
const G4ParticleDefinition* part = dynParticle->GetDefinition();
|
||||
G4double mass = part->GetPDGMass();
|
||||
G4double dmass= dynParticle->GetMass();
|
||||
if(std::abs(dmass - mass) > 1.5*CLHEP::MeV) {
|
||||
G4double e = std::max(dynParticle->GetKineticEnergy() + dmass - mass, 0.0);
|
||||
const G4double delta_mass_lim = 1.0*CLHEP::keV;
|
||||
const G4double delta_ekin = 0.001*CLHEP::eV;
|
||||
if(std::abs(dmass - mass) > delta_mass_lim) {
|
||||
G4double e = std::max(dynParticle->GetKineticEnergy() + dmass - mass, delta_ekin);
|
||||
if(G4HadronicProcess_debug_flag) {
|
||||
G4ExceptionDescription ed;
|
||||
ed << "TrackID= "<< aT.GetTrackID()
|
||||
@@ -538,7 +536,12 @@ G4HadFinalState* G4HadronicProcess::CheckResult(const G4HadProjectile & aPro,
|
||||
finalE += pdyn->GetTotalEnergy();
|
||||
G4double mass_pdg=pdyn->GetDefinition()->GetPDGMass();
|
||||
G4double mass_dyn=pdyn->GetMass();
|
||||
if ( std::abs(mass_pdg - mass_dyn) > 0.1*mass_pdg + 1.*MeV){
|
||||
if ( std::abs(mass_pdg - mass_dyn) > 0.1*mass_pdg + 1.*MeV ) {
|
||||
// If it is shortlived, then a difference less than 3 times the width is acceptable
|
||||
if ( pdyn->GetDefinition()->IsShortLived() &&
|
||||
std::abs(mass_pdg - mass_dyn) < 3.0*pdyn->GetDefinition()->GetPDGWidth() ) {
|
||||
continue;
|
||||
}
|
||||
result->Clear();
|
||||
result = nullptr;
|
||||
G4ExceptionDescription desc;
|
||||
@@ -615,28 +618,27 @@ G4HadronicProcess::CheckEnergyMomentumConservation(const G4Track& aTrack,
|
||||
|
||||
G4int nSec = theTotalResult->GetNumberOfSecondaries();
|
||||
if (theTotalResult->GetTrackStatus() != fStopAndKill) { // If it is Alive
|
||||
// Either interaction didn't complete, returned "do nothing" state
|
||||
// or the primary survived the interaction (e.g. electro-nucleus )
|
||||
G4Track temp(aTrack);
|
||||
// Either interaction didn't complete, returned "do nothing" state
|
||||
// or the primary survived the interaction (e.g. electro-nucleus )
|
||||
|
||||
// Use the final energy / momentum
|
||||
temp.SetMomentumDirection(*theTotalResult->GetMomentumDirection());
|
||||
temp.SetKineticEnergy(theTotalResult->GetEnergy());
|
||||
// Interaction didn't complete, returned "do nothing" state
|
||||
// - or suppressed recoil (e.g. Neutron elastic )
|
||||
final4mom = initial4mom;
|
||||
final_A = initial_A;
|
||||
final_Z = initial_Z;
|
||||
if (nSec > 0 && aTrack.GetDynamicParticle()) {
|
||||
// The primary remains in final state (e.g. electro-nucleus )
|
||||
G4Track temp(aTrack);
|
||||
|
||||
if( nSec == 0 ){
|
||||
// Interaction didn't complete, returned "do nothing" state
|
||||
// - or suppressed recoil (e.g. Neutron elastic )
|
||||
final4mom = temp.GetDynamicParticle()->Get4Momentum() + target4mom;
|
||||
final_A = initial_A;
|
||||
final_Z = initial_Z;
|
||||
}else{
|
||||
// The primary remains in final state (e.g. electro-nucleus )
|
||||
final4mom = temp.GetDynamicParticle()->Get4Momentum();
|
||||
final_A = track_A;
|
||||
final_Z = track_Z;
|
||||
// Expect that the target nucleus will have interacted,
|
||||
// and its products, including recoil, will be included in secondaries.
|
||||
}
|
||||
// Use the final energy / momentum
|
||||
temp.SetMomentumDirection(*theTotalResult->GetMomentumDirection());
|
||||
temp.SetKineticEnergy(theTotalResult->GetEnergy());
|
||||
final4mom = temp.GetDynamicParticle()->Get4Momentum();
|
||||
final_A = track_A;
|
||||
final_Z = track_Z;
|
||||
// Expect that the target nucleus will have interacted,
|
||||
// and its products, including recoil, will be included in secondaries.
|
||||
}
|
||||
}
|
||||
if( nSec > 0 ) {
|
||||
G4Track* sec;
|
||||
|
||||
@@ -577,7 +577,7 @@ void G4HadronicProcessStore::PrintInfo(const G4ParticleDefinition* part)
|
||||
if(buildTableStart && part == particle[n_part - 1]) {
|
||||
buildTableStart = false;
|
||||
Dump(verbose);
|
||||
if (getenv("G4PhysListDocDir") ) DumpHtml();
|
||||
if (std::getenv("G4PhysListDocDir") ) DumpHtml();
|
||||
G4HadronicInteractionRegistry::Instance()->InitialiseModels();
|
||||
}
|
||||
}
|
||||
@@ -590,8 +590,8 @@ void G4HadronicProcessStore::DumpHtml()
|
||||
// List processes, models and cross sections for the most important
|
||||
// particles in descending order of importance
|
||||
|
||||
char* dirName = getenv("G4PhysListDocDir");
|
||||
char* physListName = getenv("G4PhysListName");
|
||||
char* dirName = std::getenv("G4PhysListDocDir");
|
||||
char* physListName = std::getenv("G4PhysListName");
|
||||
if (dirName && physListName) {
|
||||
|
||||
// Open output file with path name
|
||||
@@ -668,7 +668,7 @@ void G4HadronicProcessStore::PrintHtml(const G4ParticleDefinition* theParticle,
|
||||
m_map.equal_range(theProcess);
|
||||
|
||||
outFile << " <ul>\n";
|
||||
G4String physListName(getenv("G4PhysListName"));
|
||||
G4String physListName(std::getenv("G4PhysListName"));
|
||||
|
||||
for (HPHImap::iterator jt = itmod.first; jt != itmod.second; ++jt) {
|
||||
outFile << " <li><b><a href=\"" << physListName << "_"
|
||||
@@ -720,8 +720,8 @@ void G4HadronicProcessStore::PrintHtml(const G4ParticleDefinition* theParticle,
|
||||
void
|
||||
G4HadronicProcessStore::PrintModelHtml(const G4HadronicInteraction * mod) const
|
||||
{
|
||||
G4String dirName(getenv("G4PhysListDocDir"));
|
||||
G4String physListName(getenv("G4PhysListName"));
|
||||
G4String dirName(std::getenv("G4PhysListDocDir"));
|
||||
G4String physListName(std::getenv("G4PhysListName"));
|
||||
G4String pathName = dirName + "/" + physListName + "_" + HtmlFileName(mod->GetModelName());
|
||||
std::ofstream outModel;
|
||||
outModel.open(pathName);
|
||||
|
||||
@@ -95,4 +95,7 @@ GEANT4_DEFINE_MODULE(NAME G4hadronic_abla_abla
|
||||
G4track
|
||||
G4intercoms
|
||||
|
||||
SOURCES_EXCLUDE_FORMAT
|
||||
G4Abla.cc
|
||||
|
||||
LINK_LIBRARIES)# List any source specific properties here
|
||||
|
||||
@@ -68,7 +68,7 @@ G4AblaDataFile::~G4AblaDataFile()
|
||||
bool G4AblaDataFile::readData()
|
||||
{
|
||||
#ifdef ABLAXX_IN_GEANT4_MODE
|
||||
if(!getenv("G4ABLADATA")) {
|
||||
if(!std::getenv("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
|
||||
@@ -85,7 +85,7 @@ bool G4AblaDataFile::readData()
|
||||
G4Exception("G4AblaDataFile::readData()","ABLA_001",
|
||||
FatalException, ed);
|
||||
}
|
||||
G4String dataPath(getenv("G4ABLADATA"));
|
||||
G4String dataPath(std::getenv("G4ABLADATA"));
|
||||
#else
|
||||
G4String dataPath(theConfig->getABLAXXDataFilePath().c_str());
|
||||
#endif
|
||||
|
||||
@@ -13,6 +13,16 @@ code and to keep track of all tags.
|
||||
* Please list in reverse chronological order (last date on top)
|
||||
---------------------------------------------------------------
|
||||
|
||||
06-Nov-2019, Alberto Ribon had-binary-V10-05-01
|
||||
- G4GeneratorPrecompoundInterface: trivial fix.
|
||||
|
||||
15-Oct-2019, Alberto Ribon had-binary-V10-05-00
|
||||
- G4GeneratorPrecompoundInterface: extended by Vladimir Uzhinsky to
|
||||
include a simple coalescence model for nucleus-nucleus interactions
|
||||
(in the interface between string and precompound models).
|
||||
This allows to improve the nucleon spectra and produce fast deuterons
|
||||
in ion-ion collisions.
|
||||
|
||||
09-Nov-2018, Gabriele Cosmo had-binary-V10-04-00
|
||||
- G4GeneratorPrecompoundInterface: fixed printout typo.
|
||||
|
||||
|
||||
+22
-3
@@ -69,12 +69,17 @@ public:
|
||||
virtual G4ReactionProductVector*
|
||||
Propagate(G4KineticTrackVector* theSecondaries, G4V3DNucleus* theNucleus);
|
||||
|
||||
virtual G4ReactionProductVector* // Uzhi Nov. 2012
|
||||
virtual G4ReactionProductVector*
|
||||
PropagateNuclNucl(G4KineticTrackVector* theSecondaries, G4V3DNucleus* theNucleus,
|
||||
G4V3DNucleus* theProjectileNucleus);
|
||||
|
||||
inline void SetCaptureThreshold(G4double);
|
||||
|
||||
inline void SetDeltaM(G4double);
|
||||
inline void SetDeltaR(G4double);
|
||||
|
||||
void MakeCoalescence(G4KineticTrackVector* theSecondaries);
|
||||
|
||||
virtual void PropagateModelDescription(std::ostream&) const;
|
||||
|
||||
private:
|
||||
@@ -85,6 +90,9 @@ private:
|
||||
G4bool operator!=(G4GeneratorPrecompoundInterface& right) {return (this != &right);}
|
||||
|
||||
G4double CaptureThreshold;
|
||||
G4double DeltaM;
|
||||
G4double DeltaR;
|
||||
|
||||
const G4ParticleDefinition* proton;
|
||||
const G4ParticleDefinition* neutron;
|
||||
|
||||
@@ -105,9 +113,20 @@ private:
|
||||
inline
|
||||
void G4GeneratorPrecompoundInterface::SetCaptureThreshold(G4double value)
|
||||
{
|
||||
CaptureThreshold=value;
|
||||
CaptureThreshold = value;
|
||||
}
|
||||
|
||||
inline
|
||||
void G4GeneratorPrecompoundInterface::SetDeltaM(G4double value)
|
||||
{
|
||||
DeltaM = value;
|
||||
}
|
||||
|
||||
inline
|
||||
void G4GeneratorPrecompoundInterface::SetDeltaR(G4double value)
|
||||
{
|
||||
DeltaR = value;
|
||||
}
|
||||
|
||||
#endif // G4GeneratorPrecompoundInterface_h
|
||||
|
||||
|
||||
|
||||
@@ -271,7 +271,7 @@ G4HadFinalState * G4BinaryCascade::ApplyYourself(const G4HadProjectile & aTrack,
|
||||
G4Nucleus & aNucleus)
|
||||
//----------------------------------------------------------------------------
|
||||
{
|
||||
if(getenv("BCDEBUG") ) G4cerr << " ######### Binary Cascade Reaction starts ######### "<< G4endl;
|
||||
if(std::getenv("BCDEBUG") ) G4cerr << " ######### Binary Cascade Reaction starts ######### "<< G4endl;
|
||||
|
||||
G4LorentzVector initial4Momentum = aTrack.Get4Momentum();
|
||||
const G4ParticleDefinition * definition = aTrack.GetDefinition();
|
||||
@@ -290,7 +290,7 @@ G4HadFinalState * G4BinaryCascade::ApplyYourself(const G4HadProjectile & aTrack,
|
||||
G4KineticTrackVector * secondaries;// = new G4KineticTrackVector;
|
||||
G4ThreeVector initialPosition(0., 0., 0.); // will be set later
|
||||
|
||||
if(!getenv("I_Am_G4BinaryCascade_Developer") )
|
||||
if(!std::getenv("I_Am_G4BinaryCascade_Developer") )
|
||||
{
|
||||
if(definition!=G4Neutron::NeutronDefinition() &&
|
||||
definition!=G4Proton::ProtonDefinition() &&
|
||||
@@ -380,7 +380,7 @@ G4HadFinalState * G4BinaryCascade::ApplyYourself(const G4HadProjectile & aTrack,
|
||||
|
||||
|
||||
} else { // no interaction, return primary
|
||||
if(getenv("BCDEBUG") ) G4cerr << " ######### Binary Cascade Reaction void, return intial state ######### "<< G4endl;
|
||||
if(std::getenv("BCDEBUG") ) G4cerr << " ######### Binary Cascade Reaction void, return intial state ######### "<< G4endl;
|
||||
theParticleChange.SetStatusChange(isAlive);
|
||||
theParticleChange.SetEnergyChange(aTrack.GetKineticEnergy());
|
||||
theParticleChange.SetMomentumChange(aTrack.Get4Momentum().vect().unit());
|
||||
@@ -395,7 +395,7 @@ G4HadFinalState * G4BinaryCascade::ApplyYourself(const G4HadProjectile & aTrack,
|
||||
delete the3DNucleus;
|
||||
the3DNucleus = NULL;
|
||||
|
||||
if(getenv("BCDEBUG") ) G4cerr << " ######### Binary Cascade Reaction ends ######### "<< G4endl;
|
||||
if(std::getenv("BCDEBUG") ) G4cerr << " ######### Binary Cascade Reaction ends ######### "<< G4endl;
|
||||
|
||||
return &theParticleChange;
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ G4BinaryLightIonReaction::G4BinaryLightIonReaction(G4VPreCompoundModel* ptr)
|
||||
}
|
||||
|
||||
|
||||
debug_G4BinaryLightIonReactionResults=getenv("debug_G4BinaryLightIonReactionResults")!=0;
|
||||
debug_G4BinaryLightIonReactionResults=std::getenv("debug_G4BinaryLightIonReactionResults")!=0;
|
||||
}
|
||||
|
||||
G4BinaryLightIonReaction::~G4BinaryLightIonReaction()
|
||||
@@ -106,7 +106,7 @@ struct ReactionProduct4Mom
|
||||
G4HadFinalState *G4BinaryLightIonReaction::
|
||||
ApplyYourself(const G4HadProjectile &aTrack, G4Nucleus & targetNucleus )
|
||||
{
|
||||
if(getenv("BLICDEBUG") ) G4cerr << " ######### Binary Light Ion Reaction starts ######### " << G4endl;
|
||||
if(std::getenv("BLICDEBUG") ) G4cerr << " ######### Binary Light Ion Reaction starts ######### " << G4endl;
|
||||
G4ping debug("debug_G4BinaryLightIonReaction");
|
||||
pA=aTrack.GetDefinition()->GetBaryonNumber();
|
||||
pZ=G4lrint(aTrack.GetDefinition()->GetPDGCharge()/eplus);
|
||||
@@ -358,7 +358,7 @@ ApplyYourself(const G4HadProjectile &aTrack, G4Nucleus & targetNucleus )
|
||||
<< " 3mom.mag() " << (aTrack.Get4Momentum()+ G4LorentzVector(m_nucl) - ptot).vect().mag() << G4endl;
|
||||
#endif
|
||||
|
||||
if(getenv("BLICDEBUG") ) G4cerr << " ######### Binary Light Ion Reaction number ends ######### " << G4endl;
|
||||
if(std::getenv("BLICDEBUG") ) G4cerr << " ######### Binary Light Ion Reaction number ends ######### " << G4endl;
|
||||
|
||||
return &theResult;
|
||||
}
|
||||
|
||||
+68
-23
@@ -76,7 +76,7 @@
|
||||
//#define debugPrecoInt
|
||||
|
||||
G4GeneratorPrecompoundInterface::G4GeneratorPrecompoundInterface(G4VPreCompoundModel* preModel)
|
||||
: CaptureThreshold(70*MeV) // Uzhi 1.05.2015 10 ->70
|
||||
: CaptureThreshold(70*MeV), DeltaM(5.0*MeV), DeltaR(0.0)
|
||||
{
|
||||
proton = G4Proton::Proton();
|
||||
neutron = G4Neutron::Neutron();
|
||||
@@ -149,24 +149,23 @@ Propagate(G4KineticTrackVector* theSecondaries, G4V3DNucleus* theNucleus)
|
||||
G4double mass = (*iter)->Get4Momentum().mag();
|
||||
G4ThreeVector mom = (*iter)->Get4Momentum().vect();
|
||||
if((part != proton && part != neutron) ||
|
||||
// Uzhi 2.05.2015 (e > mass + CaptureThreshold) ||
|
||||
((*iter)->GetPosition().mag() > R)) {
|
||||
G4ReactionProduct * theNew = new G4ReactionProduct(part);
|
||||
theNew->SetMomentum(mom);
|
||||
theNew->SetTotalEnergy(e);
|
||||
theTotalResult->push_back(theNew);
|
||||
Secondary4Momentum += (*iter)->Get4Momentum(); // Uzhi 29 April
|
||||
Secondary4Momentum += (*iter)->Get4Momentum();
|
||||
#ifdef debugPrecoInt
|
||||
G4cout<<"Secondary 4Mom "<<part->GetParticleName()<<" "<<(*iter)->Get4Momentum()<<" "
|
||||
<<(*iter)->Get4Momentum().mag()<<G4endl;
|
||||
#endif
|
||||
} else {
|
||||
if( e-mass > -CaptureThreshold*G4Log( G4UniformRand()) ) { // Added by Uzhi 2.05.2015
|
||||
if( e-mass > -CaptureThreshold*G4Log( G4UniformRand()) ) {
|
||||
G4ReactionProduct * theNew = new G4ReactionProduct(part);
|
||||
theNew->SetMomentum(mom);
|
||||
theNew->SetTotalEnergy(e);
|
||||
theTotalResult->push_back(theNew);
|
||||
Secondary4Momentum += (*iter)->Get4Momentum(); // Uzhi 29 April
|
||||
Secondary4Momentum += (*iter)->Get4Momentum();
|
||||
#ifdef debugPrecoInt
|
||||
G4cout<<"Secondary 4Mom "<<part->GetParticleName()<<" "<<(*iter)->Get4Momentum()<<" "
|
||||
<<(*iter)->Get4Momentum().mag()<<G4endl;
|
||||
@@ -240,7 +239,7 @@ Propagate(G4KineticTrackVector* theSecondaries, G4V3DNucleus* theNucleus)
|
||||
|
||||
if(anA == 0) return theTotalResult;
|
||||
|
||||
G4LorentzVector exciton4Momentum(0.,0.,0.,0.); // Uzhi 29 April
|
||||
G4LorentzVector exciton4Momentum(0.,0.,0.,0.);
|
||||
if(anA >= aZ)
|
||||
{
|
||||
if(!QGSM)
|
||||
@@ -251,13 +250,13 @@ Propagate(G4KineticTrackVector* theSecondaries, G4V3DNucleus* theNucleus)
|
||||
exciton4Momentum = Residual4Momentum + captured4Momentum;
|
||||
//exciton4Momentum.setE(std::sqrt(exciton4Momentum.vect().mag2()+sqr(fMass)));
|
||||
G4double ActualMass = exciton4Momentum.mag();
|
||||
if(ActualMass <= fMass ) { //E*<=0, Uzhi 5.05.2015
|
||||
exciton4Momentum.setE(std::sqrt(exciton4Momentum.vect().mag2()+sqr(fMass))); // Uzhi 13.05.2015
|
||||
if(ActualMass <= fMass ) {
|
||||
exciton4Momentum.setE(std::sqrt(exciton4Momentum.vect().mag2()+sqr(fMass)));
|
||||
}
|
||||
|
||||
#ifdef debugPrecoInt
|
||||
G4double exEnergy = 0.0;
|
||||
if(ActualMass <= fMass ) {exEnergy = 0.;} // Uzhi 5.05.2015
|
||||
if(ActualMass <= fMass ) {exEnergy = 0.;}
|
||||
else {exEnergy = ActualMass - fMass;}
|
||||
G4cout<<"Ground state residual Mass "<<fMass<<" E* "<<exEnergy<<G4endl;
|
||||
#endif
|
||||
@@ -344,7 +343,7 @@ void G4GeneratorPrecompoundInterface::PropagateModelDescription(std::ostream& ou
|
||||
|
||||
}
|
||||
|
||||
// Uzhi Nov. 2012 ------------------------------------------------
|
||||
|
||||
G4ReactionProductVector* G4GeneratorPrecompoundInterface::
|
||||
PropagateNuclNucl(G4KineticTrackVector* theSecondaries, G4V3DNucleus* theNucleus,
|
||||
G4V3DNucleus* theProjectileNucleus)
|
||||
@@ -445,6 +444,9 @@ PropagateNuclNucl(G4KineticTrackVector* theSecondaries, G4V3DNucleus* theNucleus
|
||||
// decay the strong resonances
|
||||
G4ReactionProductVector * theTotalResult = new G4ReactionProductVector;
|
||||
G4DecayKineticTracks decay(theSecondaries);
|
||||
|
||||
MakeCoalescence(theSecondaries);
|
||||
|
||||
#ifdef debugPrecoInt
|
||||
G4cout<<"Secondary stable particles number "<<theSecondaries->size()<<G4endl;
|
||||
#endif
|
||||
@@ -644,24 +646,21 @@ PropagateNuclNucl(G4KineticTrackVector* theSecondaries, G4V3DNucleus* theNucleus
|
||||
|
||||
if(0!=anAb)
|
||||
{
|
||||
// G4ThreeVector bstToCM =Projectile4Momentum.findBoostToCM(); // Uzhi Apr. 2015
|
||||
// Projectile4Momentum.boost(bstToCM); // Uzhi Apr. 2015
|
||||
|
||||
G4double fMass = G4NucleiProperties::GetNuclearMass(anAb, aZb);
|
||||
G4double RemnMass=Projectile4Momentum.mag();
|
||||
|
||||
if(RemnMass < fMass)
|
||||
{
|
||||
RemnMass=fMass + exEnergyB;
|
||||
Projectile4Momentum.setE(std::sqrt(Projectile4Momentum.vect().mag2() + // Uzhi 8.05.2015
|
||||
RemnMass*RemnMass)); // Uzhi 8.05.2015
|
||||
Projectile4Momentum.setE(std::sqrt(Projectile4Momentum.vect().mag2() +
|
||||
RemnMass*RemnMass));
|
||||
} else
|
||||
{ exEnergyB=RemnMass-fMass;}
|
||||
|
||||
if( exEnergyB < 0.) exEnergyB=0.;
|
||||
|
||||
G4ThreeVector bstToCM =Projectile4Momentum.findBoostToCM(); // Uzhi Apr. 2015
|
||||
Projectile4Momentum.boost(bstToCM); // Uzhi Apr. 2015
|
||||
G4ThreeVector bstToCM =Projectile4Momentum.findBoostToCM();
|
||||
Projectile4Momentum.boost(bstToCM);
|
||||
|
||||
// Need to de-excite the remnant nucleus
|
||||
G4Fragment anInitialState(anAb, aZb, Projectile4Momentum);
|
||||
@@ -679,11 +678,11 @@ PropagateNuclNucl(G4KineticTrackVector* theSecondaries, G4V3DNucleus* theNucleus
|
||||
// fill pre-compound part into the result, and return
|
||||
for(unsigned int ll=0; ll<aPrecoResult->size(); ++ll)
|
||||
{
|
||||
G4LorentzVector tmp=G4LorentzVector(aPrecoResult->operator[](ll)->GetMomentum(), // Uzhi 2015
|
||||
aPrecoResult->operator[](ll)->GetTotalEnergy());// Uzhi 2015
|
||||
tmp.boost(-bstToCM); // Transformation to the system of original remnant // Uzhi 2015
|
||||
aPrecoResult->operator[](ll)->SetMomentum(tmp.vect()); // Uzhi 2015
|
||||
aPrecoResult->operator[](ll)->SetTotalEnergy(tmp.e()); // Uzhi 2015
|
||||
G4LorentzVector tmp=G4LorentzVector(aPrecoResult->operator[](ll)->GetMomentum(),
|
||||
aPrecoResult->operator[](ll)->GetTotalEnergy());
|
||||
tmp.boost(-bstToCM); // Transformation to the system of original remnant
|
||||
aPrecoResult->operator[](ll)->SetMomentum(tmp.vect());
|
||||
aPrecoResult->operator[](ll)->SetTotalEnergy(tmp.e());
|
||||
|
||||
if(ProjectileIsAntiNucleus)
|
||||
{
|
||||
@@ -707,7 +706,7 @@ PropagateNuclNucl(G4KineticTrackVector* theSecondaries, G4V3DNucleus* theNucleus
|
||||
<<aPrecoResult->operator[](ll)->GetTotalEnergy()<<" "
|
||||
<<aPrecoResult->operator[](ll)->GetMass()<<G4endl;
|
||||
#endif
|
||||
//Uzhi
|
||||
|
||||
theTotalResult->push_back(aPrecoResult->operator[](ll));
|
||||
}
|
||||
|
||||
@@ -718,3 +717,49 @@ PropagateNuclNucl(G4KineticTrackVector* theSecondaries, G4V3DNucleus* theNucleus
|
||||
}
|
||||
|
||||
|
||||
void G4GeneratorPrecompoundInterface::MakeCoalescence(G4KineticTrackVector *tracks) {
|
||||
|
||||
if (!tracks) return;
|
||||
|
||||
G4double MassCut = deuteron->GetPDGMass() + DeltaM; // In MeV
|
||||
|
||||
for ( size_t i = 0; i < tracks->size(); ++i ) { // search for protons
|
||||
|
||||
G4KineticTrack* trackP = (*tracks)[i];
|
||||
if ( ! trackP ) continue;
|
||||
if (trackP->GetDefinition() != proton) continue;
|
||||
|
||||
G4LorentzVector Prot4Mom = trackP->Get4Momentum();
|
||||
G4LorentzVector ProtSPposition = G4LorentzVector(trackP->GetPosition(), trackP->GetFormationTime());
|
||||
|
||||
for ( size_t j = 0; j < tracks->size(); ++j ) { // search for neutron
|
||||
|
||||
G4KineticTrack* trackN = (*tracks)[j];
|
||||
if (! trackN ) continue;
|
||||
if (trackN->GetDefinition() != neutron) continue;
|
||||
|
||||
G4LorentzVector Neut4Mom = trackN->Get4Momentum();
|
||||
G4LorentzVector NeutSPposition = G4LorentzVector( trackN->GetPosition(), trackN->GetFormationTime()*hbarc/fermi);
|
||||
G4double EffMass = (Prot4Mom + Neut4Mom).mag();
|
||||
|
||||
if ( EffMass <= MassCut ) { // && (EffDistance <= SpaceCut)) { // Create deuteron
|
||||
G4KineticTrack* aDeuteron =
|
||||
new G4KineticTrack( deuteron,
|
||||
(trackP->GetFormationTime() + trackN->GetFormationTime())/2.0,
|
||||
(trackP->GetPosition() + trackN->GetPosition() )/2.0,
|
||||
( Prot4Mom + Neut4Mom ));
|
||||
tracks->push_back(aDeuteron);
|
||||
delete trackP; delete trackN;
|
||||
(*tracks)[i] = nullptr; (*tracks)[j] = nullptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Find and remove null pointers created by decays above
|
||||
for ( int jj = tracks->size()-1; jj >= 0; --jj ) {
|
||||
if ( ! (*tracks)[jj] ) tracks->erase(tracks->begin()+jj);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,17 @@ code and to keep track of all tags.
|
||||
* Please list in reverse chronological order (last date on top)
|
||||
---------------------------------------------------------------
|
||||
|
||||
7 November 2019 Dennis Wright (hadr-casc-V10-05-02)
|
||||
-----------------------------------------------------
|
||||
- G4LightTargetCollider: fix crash when gamma energy below deuteron
|
||||
disintegration threshold and improve exception handling
|
||||
|
||||
5 November 2019 Dennis Wright (hadr-casc-V10-05-01)
|
||||
-----------------------------------------------------
|
||||
- new class G4LightTargetCollider to more accurately handle collisons
|
||||
on p, d, t, 3He. Currently only gamma on protons and deuterons is
|
||||
implemented.
|
||||
|
||||
29 May 2019 Dennis Wright (hadr-casc-V10-05-00)
|
||||
------------------------------------------------
|
||||
- fix bug found in biasing/B03 example due to FPE from unprotected sqrt
|
||||
|
||||
@@ -79,6 +79,7 @@ class G4CollisionOutput;
|
||||
class G4DynamicParticle;
|
||||
class G4HadFinalState;
|
||||
class G4InuclCollider;
|
||||
class G4LightTargetCollider;
|
||||
class G4InuclParticle;
|
||||
class G4ParticleDefinition;
|
||||
class G4V3DNucleus;
|
||||
@@ -166,6 +167,8 @@ private:
|
||||
G4InuclCollider* collider;
|
||||
G4CascadeCheckBalance* balance;
|
||||
|
||||
G4LightTargetCollider* ltcollider;
|
||||
|
||||
G4InuclParticle* bullet; // Pointers to last filled versions
|
||||
G4InuclParticle* target;
|
||||
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: G4LightTargetCollider.hh //
|
||||
// Date: 30 September 2019 //
|
||||
// Author: Dennis Wright (SLAC) //
|
||||
// //
|
||||
// Description: model for collision of elementary particles with light //
|
||||
// targets (H, D, T, 3He) //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef G4LIGHT_TARGET_COLLIDER_HH
|
||||
#define G4LIGHT_TARGET_COLLIDER_HH
|
||||
|
||||
#include "G4CascadeColliderBase.hh"
|
||||
#include "G4CascadeFinalStateGenerator.hh"
|
||||
#include "G4CollisionOutput.hh"
|
||||
|
||||
class G4CascadParticle;
|
||||
class G4ElementaryParticleCollider;
|
||||
class G4InuclParticle;
|
||||
class G4KineticTrackVector;
|
||||
|
||||
typedef std::pair<G4InuclElementaryParticle, G4InuclElementaryParticle> NucleonPair;
|
||||
typedef std::vector<G4InuclElementaryParticle> ScatteringProducts;
|
||||
|
||||
class G4LightTargetCollider : public G4CascadeColliderBase {
|
||||
public:
|
||||
G4LightTargetCollider();
|
||||
virtual ~G4LightTargetCollider();
|
||||
|
||||
void collide(G4InuclParticle* bullet, G4InuclParticle* target,
|
||||
G4CollisionOutput& globalOutput);
|
||||
|
||||
void setVerboseLevel(G4int verbose=0);
|
||||
|
||||
private:
|
||||
G4ElementaryParticleCollider* theElementaryParticleCollider;
|
||||
|
||||
G4CollisionOutput output; // Secondaries from main cascade
|
||||
|
||||
private:
|
||||
// Copying of modules is forbidden
|
||||
G4LightTargetCollider(const G4LightTargetCollider&);
|
||||
G4LightTargetCollider& operator=(const G4LightTargetCollider&);
|
||||
|
||||
G4double GammaDCrossSection(G4double /*kineticEnergy*/);
|
||||
|
||||
G4CascadeFinalStateGenerator fsGen;
|
||||
|
||||
NucleonPair AbsorptionOnDeuteron(G4InuclParticle* bullet);
|
||||
|
||||
ScatteringProducts SingleNucleonScattering(const G4InuclElementaryParticle& projectile,
|
||||
const G4InuclElementaryParticle& targetNucleon);
|
||||
|
||||
G4double mP; // proton mass
|
||||
G4double mN; // neutron mass
|
||||
G4double mD; // deuteron mass
|
||||
G4double pFermiD; // deuteron Fermi momentum (GeV/c)
|
||||
};
|
||||
|
||||
#endif /* G4LIGHT_TARGET_COLLIDER_HH */
|
||||
|
||||
|
||||
@@ -161,6 +161,7 @@ GEANT4_DEFINE_MODULE(NAME G4hadronic_bert_cascade
|
||||
G4InteractionCase.hh
|
||||
G4IntraNucleiCascader.hh
|
||||
G4InuclCollider.hh
|
||||
G4LightTargetCollider.hh
|
||||
G4InuclElementaryParticle.hh
|
||||
G4InuclEvaporation.hh
|
||||
G4InuclNuclei.hh
|
||||
@@ -274,6 +275,7 @@ GEANT4_DEFINE_MODULE(NAME G4hadronic_bert_cascade
|
||||
G4InteractionCase.cc
|
||||
G4IntraNucleiCascader.cc
|
||||
G4InuclCollider.cc
|
||||
G4LightTargetCollider.cc
|
||||
G4InuclElementaryParticle.cc
|
||||
G4InuclEvaporation.cc
|
||||
G4InuclNuclei.cc
|
||||
|
||||
@@ -116,6 +116,7 @@
|
||||
#include "G4DynamicParticle.hh"
|
||||
#include "G4HadronicException.hh"
|
||||
#include "G4InuclCollider.hh"
|
||||
#include "G4LightTargetCollider.hh"
|
||||
#include "G4InuclElementaryParticle.hh"
|
||||
#include "G4InuclNuclei.hh"
|
||||
#include "G4InuclParticle.hh"
|
||||
@@ -143,11 +144,13 @@ typedef std::vector<G4InuclNuclei>::const_iterator nucleiIterator;
|
||||
// Constructor and destrutor
|
||||
|
||||
G4CascadeInterface::G4CascadeInterface(const G4String& name)
|
||||
: G4VIntraNuclearTransportModel(name),
|
||||
randomFile(G4CascadeParameters::randomFile()),
|
||||
maximumTries(20), numberOfTries(0),
|
||||
collider(new G4InuclCollider), balance(new G4CascadeCheckBalance(name)),
|
||||
bullet(0), target(0), output(new G4CollisionOutput) {
|
||||
: G4VIntraNuclearTransportModel(name),
|
||||
randomFile(G4CascadeParameters::randomFile()),
|
||||
maximumTries(20), numberOfTries(0),
|
||||
collider(new G4InuclCollider), balance(new G4CascadeCheckBalance(name)),
|
||||
ltcollider(new G4LightTargetCollider),
|
||||
bullet(0), target(0), output(new G4CollisionOutput)
|
||||
{
|
||||
// Set up global objects for master thread or sequential build
|
||||
if (G4Threading::IsMasterThread()) Initialize();
|
||||
|
||||
@@ -278,55 +281,71 @@ G4CascadeInterface::ApplyYourself(const G4HadProjectile& aTrack,
|
||||
return NoInteraction(aTrack, theNucleus);
|
||||
}
|
||||
|
||||
// Make conversion between native Geant4 and Bertini cascade classes.
|
||||
if (!createBullet(aTrack)) {
|
||||
if (verboseLevel) G4cerr << " Unable to create usable bullet" << G4endl;
|
||||
return NoInteraction(aTrack, theNucleus);
|
||||
}
|
||||
// If target A < 3 skip all cascade machinery and do scattering on
|
||||
// nucleons
|
||||
|
||||
if (!createTarget(theNucleus)) {
|
||||
if (verboseLevel) G4cerr << " Unable to create usable target" << G4endl;
|
||||
return NoInteraction(aTrack, theNucleus);
|
||||
}
|
||||
|
||||
// Different retry conditions for proton target vs. nucleus
|
||||
const G4bool isHydrogen = (theNucleus.GetA_asInt() == 1);
|
||||
|
||||
numberOfTries = 0;
|
||||
do { // we try to create inelastic interaction
|
||||
if (verboseLevel > 1)
|
||||
G4cout << " Generating cascade attempt " << numberOfTries << G4endl;
|
||||
|
||||
if (aTrack.GetDefinition() == G4Gamma::Gamma() &&
|
||||
theNucleus.GetA_asInt() < 3) {
|
||||
output->reset();
|
||||
collider->collide(bullet, target, *output);
|
||||
balance->collide(bullet, target, *output);
|
||||
createBullet(aTrack);
|
||||
createTarget(theNucleus);
|
||||
// Due to binning, gamma-p cross sections between 130 MeV and the inelastic threshold
|
||||
// (144 for pi0 p, 152 for pi+ n) are non-zero, causing energy non-conservation
|
||||
// So, if Egamma is between 144 and 152, only pi0 p is allowed.
|
||||
|
||||
// Also, inelastic gamma-p cross section from G4PhotoNuclearCrossSection seems to be
|
||||
// non-zero below between pi0 mass (135 MeV) and threshold (144 MeV)
|
||||
ltcollider->collide(bullet, target, *output);
|
||||
|
||||
} else {
|
||||
|
||||
// Make conversion between native Geant4 and Bertini cascade classes.
|
||||
if (!createBullet(aTrack)) {
|
||||
if (verboseLevel) G4cerr << " Unable to create usable bullet" << G4endl;
|
||||
return NoInteraction(aTrack, theNucleus);
|
||||
}
|
||||
|
||||
if (!createTarget(theNucleus)) {
|
||||
if (verboseLevel) G4cerr << " Unable to create usable target" << G4endl;
|
||||
return NoInteraction(aTrack, theNucleus);
|
||||
}
|
||||
|
||||
// Different retry conditions for proton target vs. nucleus
|
||||
const G4bool isHydrogen = (theNucleus.GetA_asInt() == 1);
|
||||
|
||||
numberOfTries = 0;
|
||||
do { // we try to create inelastic interaction
|
||||
if (verboseLevel > 1)
|
||||
G4cout << " Generating cascade attempt " << numberOfTries << G4endl;
|
||||
|
||||
numberOfTries++;
|
||||
/* Loop checking 08.06.2015 MHK */
|
||||
} while ( isHydrogen ? retryInelasticProton() : retryInelasticNucleus() );
|
||||
output->reset();
|
||||
collider->collide(bullet, target, *output);
|
||||
balance->collide(bullet, target, *output);
|
||||
|
||||
numberOfTries++;
|
||||
/* Loop checking 08.06.2015 MHK */
|
||||
} while ( isHydrogen ? retryInelasticProton() : retryInelasticNucleus() );
|
||||
|
||||
// Null event if unsuccessful
|
||||
if (numberOfTries >= maximumTries) {
|
||||
if (verboseLevel)
|
||||
G4cout << " Cascade aborted after trials " << numberOfTries << G4endl;
|
||||
return NoInteraction(aTrack, theNucleus);
|
||||
}
|
||||
// Null event if unsuccessful
|
||||
if (numberOfTries >= maximumTries) {
|
||||
if (verboseLevel)
|
||||
G4cout << " Cascade aborted after trials " << numberOfTries << G4endl;
|
||||
return NoInteraction(aTrack, theNucleus);
|
||||
}
|
||||
|
||||
// Abort job if energy or momentum are not conserved
|
||||
if (!balance->okay()) {
|
||||
throwNonConservationFailure();
|
||||
return NoInteraction(aTrack, theNucleus);
|
||||
}
|
||||
// Abort job if energy or momentum are not conserved
|
||||
if (!balance->okay()) {
|
||||
throwNonConservationFailure();
|
||||
return NoInteraction(aTrack, theNucleus);
|
||||
}
|
||||
|
||||
// Successful cascade -- clean up and return
|
||||
if (verboseLevel) {
|
||||
G4cout << " Cascade output after trials " << numberOfTries << G4endl;
|
||||
if (verboseLevel > 1) output->printCollisionOutput();
|
||||
}
|
||||
// Successful cascade -- clean up and return
|
||||
if (verboseLevel) {
|
||||
G4cout << " Cascade output after trials " << numberOfTries << G4endl;
|
||||
if (verboseLevel > 1) output->printCollisionOutput();
|
||||
}
|
||||
|
||||
// Rotate event to put Z axis along original projectile direction
|
||||
// Removed by DHW to fix bug #1990
|
||||
// output->rotateEvent(bulletInLabFrame);
|
||||
} // end cascade-style collisions
|
||||
|
||||
copyOutputToHadronicResult();
|
||||
|
||||
|
||||
@@ -84,27 +84,27 @@ const G4CascadeParameters* G4CascadeParameters::Instance() {
|
||||
//#define OLD_RADIUS_UNITS (3.3836/1.2) // Used with NucModel params
|
||||
|
||||
G4CascadeParameters::G4CascadeParameters()
|
||||
: G4CASCADE_VERBOSE(getenv("G4CASCADE_VERBOSE")),
|
||||
G4CASCADE_CHECK_ECONS(getenv("G4CASCADE_CHECK_ECONS")),
|
||||
G4CASCADE_USE_PRECOMPOUND(getenv("G4CASCADE_USE_PRECOMPOUND")),
|
||||
G4CASCADE_DO_COALESCENCE(getenv("G4CASCADE_DO_COALESCENCE")),
|
||||
G4CASCADE_SHOW_HISTORY(getenv("G4CASCADE_SHOW_HISTORY")),
|
||||
G4CASCADE_USE_3BODYMOM(getenv("G4CASCADE_USE_3BODYMOM")),
|
||||
G4CASCADE_USE_PHASESPACE(getenv("G4CASCADE_USE_PHASESPACE")),
|
||||
G4CASCADE_PIN_ABSORPTION(getenv("G4CASCADE_PIN_ABSORPTION")),
|
||||
G4CASCADE_RANDOM_FILE(getenv("G4CASCADE_RANDOM_FILE")),
|
||||
G4NUCMODEL_USE_BEST(getenv("G4NUCMODEL_USE_BEST")),
|
||||
G4NUCMODEL_RAD_2PAR(getenv("G4NUCMODEL_RAD_2PAR")),
|
||||
G4NUCMODEL_RAD_SCALE(getenv("G4NUCMODEL_RAD_SCALE")),
|
||||
G4NUCMODEL_RAD_SMALL(getenv("G4NUCMODEL_RAD_SMALL")),
|
||||
G4NUCMODEL_RAD_ALPHA(getenv("G4NUCMODEL_RAD_ALPHA")),
|
||||
G4NUCMODEL_RAD_TRAILING(getenv("G4NUCMODEL_RAD_TRAILING")),
|
||||
G4NUCMODEL_FERMI_SCALE(getenv("G4NUCMODEL_FERMI_SCALE")),
|
||||
G4NUCMODEL_XSEC_SCALE(getenv("G4NUCMODEL_XSEC_SCALE")),
|
||||
G4NUCMODEL_GAMMAQD(getenv("G4NUCMODEL_GAMMAQD")),
|
||||
DPMAX_2CLUSTER(getenv("DPMAX_2CLUSTER")),
|
||||
DPMAX_3CLUSTER(getenv("DPMAX_3CLUSTER")),
|
||||
DPMAX_4CLUSTER(getenv("DPMAX_4CLUSTER")),
|
||||
: G4CASCADE_VERBOSE(std::getenv("G4CASCADE_VERBOSE")),
|
||||
G4CASCADE_CHECK_ECONS(std::getenv("G4CASCADE_CHECK_ECONS")),
|
||||
G4CASCADE_USE_PRECOMPOUND(std::getenv("G4CASCADE_USE_PRECOMPOUND")),
|
||||
G4CASCADE_DO_COALESCENCE(std::getenv("G4CASCADE_DO_COALESCENCE")),
|
||||
G4CASCADE_SHOW_HISTORY(std::getenv("G4CASCADE_SHOW_HISTORY")),
|
||||
G4CASCADE_USE_3BODYMOM(std::getenv("G4CASCADE_USE_3BODYMOM")),
|
||||
G4CASCADE_USE_PHASESPACE(std::getenv("G4CASCADE_USE_PHASESPACE")),
|
||||
G4CASCADE_PIN_ABSORPTION(std::getenv("G4CASCADE_PIN_ABSORPTION")),
|
||||
G4CASCADE_RANDOM_FILE(std::getenv("G4CASCADE_RANDOM_FILE")),
|
||||
G4NUCMODEL_USE_BEST(std::getenv("G4NUCMODEL_USE_BEST")),
|
||||
G4NUCMODEL_RAD_2PAR(std::getenv("G4NUCMODEL_RAD_2PAR")),
|
||||
G4NUCMODEL_RAD_SCALE(std::getenv("G4NUCMODEL_RAD_SCALE")),
|
||||
G4NUCMODEL_RAD_SMALL(std::getenv("G4NUCMODEL_RAD_SMALL")),
|
||||
G4NUCMODEL_RAD_ALPHA(std::getenv("G4NUCMODEL_RAD_ALPHA")),
|
||||
G4NUCMODEL_RAD_TRAILING(std::getenv("G4NUCMODEL_RAD_TRAILING")),
|
||||
G4NUCMODEL_FERMI_SCALE(std::getenv("G4NUCMODEL_FERMI_SCALE")),
|
||||
G4NUCMODEL_XSEC_SCALE(std::getenv("G4NUCMODEL_XSEC_SCALE")),
|
||||
G4NUCMODEL_GAMMAQD(std::getenv("G4NUCMODEL_GAMMAQD")),
|
||||
DPMAX_2CLUSTER(std::getenv("DPMAX_2CLUSTER")),
|
||||
DPMAX_3CLUSTER(std::getenv("DPMAX_3CLUSTER")),
|
||||
DPMAX_4CLUSTER(std::getenv("DPMAX_4CLUSTER")),
|
||||
messenger(0) {
|
||||
messenger = new G4CascadeParamMessenger(this);
|
||||
Initialize();
|
||||
|
||||
@@ -246,7 +246,7 @@ void G4InuclCollider::collide(G4InuclParticle* bullet, G4InuclParticle* target,
|
||||
output.removeRecoilFragment();
|
||||
|
||||
//*** TEMPORARY, USE ENVVAR TO ENABLE/DISABLE THIS TEST ***
|
||||
if (getenv("G4CASCADE_CHECK_PHOTONUCLEAR"))
|
||||
if (std::getenv("G4CASCADE_CHECK_PHOTONUCLEAR"))
|
||||
if (!photonuclearOkay(output)) continue;
|
||||
|
||||
if (verboseLevel > 2)
|
||||
|
||||
@@ -0,0 +1,369 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: G4LightTargetCollider.cc //
|
||||
// Date: 30 September 2019 //
|
||||
// Author: Dennis Wright (SLAC) //
|
||||
// //
|
||||
// Description: model for collision of elementary particles with light //
|
||||
// targets (H, D, T, 3He) //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "G4LightTargetCollider.hh"
|
||||
#include "G4CascadeChannel.hh"
|
||||
#include "G4CascadeChannelTables.hh"
|
||||
#include "G4CascadeCheckBalance.hh"
|
||||
#include "G4CollisionOutput.hh"
|
||||
#include "G4ElementaryParticleCollider.hh"
|
||||
#include "G4InuclElementaryParticle.hh"
|
||||
#include "G4InuclNuclei.hh"
|
||||
#include "G4NucleiModel.hh"
|
||||
#include "G4LorentzConvertor.hh"
|
||||
#include "G4Deuteron.hh"
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4PionZero.hh"
|
||||
#include "G4PionPlus.hh"
|
||||
#include "G4PionMinus.hh"
|
||||
#include "G4RandomDirection.hh"
|
||||
|
||||
|
||||
G4LightTargetCollider::G4LightTargetCollider()
|
||||
: G4CascadeColliderBase("G4LightTargetCollider"),
|
||||
theElementaryParticleCollider(new G4ElementaryParticleCollider)
|
||||
{
|
||||
mP = G4Proton::Proton()->GetPDGMass()/CLHEP::GeV;
|
||||
mN = G4Neutron::Neutron()->GetPDGMass()/CLHEP::GeV;
|
||||
mD = G4Deuteron::Deuteron()->GetPDGMass()/CLHEP::GeV;
|
||||
pFermiD = 0.045; // Fermi momentum of nucleon in deuteron Hulthen potential
|
||||
}
|
||||
|
||||
G4LightTargetCollider::~G4LightTargetCollider() {
|
||||
delete theElementaryParticleCollider;
|
||||
}
|
||||
|
||||
|
||||
// Set verbosity and pass on to member objects
|
||||
void G4LightTargetCollider::setVerboseLevel(G4int verbose) {
|
||||
G4CascadeColliderBase::setVerboseLevel(verbose);
|
||||
theElementaryParticleCollider->setVerboseLevel(verboseLevel);
|
||||
output.setVerboseLevel(verboseLevel);
|
||||
}
|
||||
|
||||
|
||||
void G4LightTargetCollider::collide(G4InuclParticle* bullet,
|
||||
G4InuclParticle* target,
|
||||
G4CollisionOutput& globalOutput)
|
||||
{
|
||||
if (verboseLevel) {
|
||||
G4cout << " >>> G4LightTargetCollider::collide" << G4endl;
|
||||
G4cout << " Projectile: " << bullet->getDefinition()->GetParticleName() << G4endl;
|
||||
G4cout << " Target: " << target->getDefinition()->GetParticleName() << G4endl;
|
||||
}
|
||||
|
||||
// Particle-on-particle collision
|
||||
// No nucleus involved, just a proton in this case
|
||||
if (useEPCollider(bullet,target)) {
|
||||
if (verboseLevel > 2)
|
||||
G4cout << " InuclCollider -> particle on particle collision" << G4endl;
|
||||
|
||||
theElementaryParticleCollider->collide(bullet, target, globalOutput);
|
||||
return;
|
||||
}
|
||||
|
||||
G4double ke = bullet->getKineticEnergy();
|
||||
if (target->getDefinition() == G4Deuteron::Deuteron()) {
|
||||
|
||||
if (ke < mP + mN - mD) {
|
||||
// Should not happen as long as inelastic cross section is zero
|
||||
G4Exception("G4LightTargetCollider::collide()","HAD_BERT_201",
|
||||
JustWarning, "Projectile energy below reaction threshold");
|
||||
globalOutput.trivialise(bullet, target);
|
||||
|
||||
} else {
|
||||
// Get p, n and deuteron cross sections; use lab energy to access
|
||||
G4double gammaPXS = G4CascadeChannelTables::GetTable(9)->getCrossSection(ke);
|
||||
G4double gammaNXS = G4CascadeChannelTables::GetTable(18)->getCrossSection(ke);
|
||||
G4double gammaDXS = GammaDCrossSection(ke);
|
||||
|
||||
G4double probP = 0.0;
|
||||
G4double probN = 0.0;
|
||||
// Highest threshold is 0.152 (for gamma p -> n pi+)
|
||||
// Because of Fermi momentum in deuteron, raise this to 0.159
|
||||
if (ke > 0.159) {
|
||||
G4double totalDXS = gammaPXS + gammaNXS + gammaDXS;
|
||||
probP = gammaPXS/totalDXS;
|
||||
probN = (gammaPXS+gammaNXS)/totalDXS;
|
||||
}
|
||||
|
||||
G4double rndm = G4UniformRand();
|
||||
if (rndm < probP) {
|
||||
// Generate Fermi momenta of bullet and target
|
||||
G4ThreeVector fermiMomentum = pFermiD*G4RandomDirection();
|
||||
G4LorentzVector protonMomentum(fermiMomentum, std::sqrt(mP*mP + pFermiD*pFermiD) );
|
||||
G4LorentzVector neutronMomentum(-fermiMomentum, std::sqrt(mN*mN + pFermiD*pFermiD) );
|
||||
|
||||
G4LorentzVector bulletMomentum = bullet->getMomentum();
|
||||
G4ThreeVector betacm = bulletMomentum.findBoostToCM(protonMomentum);
|
||||
|
||||
// First boost bullet and target so that target is at rest
|
||||
G4ThreeVector toProtonRest = -protonMomentum.boostVector();
|
||||
protonMomentum.boost(toProtonRest);
|
||||
bulletMomentum.boost(toProtonRest);
|
||||
|
||||
G4InuclElementaryParticle projectile(bulletMomentum, bullet->getDefinition() );
|
||||
G4InuclElementaryParticle targetNucleon(protonMomentum, G4Proton::Proton() );
|
||||
G4InuclElementaryParticle spectatorNucleon(neutronMomentum, G4Neutron::Neutron() );
|
||||
ScatteringProducts products = SingleNucleonScattering(projectile, targetNucleon);
|
||||
|
||||
// Particles from SingleNucleonScattering are in CM frame of projectile
|
||||
// and moving proton. Transform back to lab frame with -betacm, then
|
||||
// add them to outgoing list.
|
||||
globalOutput.reset();
|
||||
G4LorentzVector temp;
|
||||
for (G4int i = 0; i < G4int(products.size()); i++) {
|
||||
temp = products[i].getMomentum();
|
||||
temp.boost(-betacm);
|
||||
products[i].setMomentum(temp);
|
||||
globalOutput.addOutgoingParticle(products[i]);
|
||||
}
|
||||
|
||||
// Add the recoil nucleon unmodified
|
||||
globalOutput.addOutgoingParticle(spectatorNucleon);
|
||||
|
||||
} else if (rndm < probN) {
|
||||
G4ThreeVector fermiMomentum = pFermiD*G4RandomDirection();
|
||||
G4LorentzVector protonMomentum(fermiMomentum, std::sqrt(mP*mP + pFermiD*pFermiD) );
|
||||
G4LorentzVector neutronMomentum(-fermiMomentum, std::sqrt(mN*mN + pFermiD*pFermiD) );
|
||||
|
||||
G4LorentzVector bulletMomentum = bullet->getMomentum();
|
||||
G4ThreeVector betacm = bulletMomentum.findBoostToCM(neutronMomentum);
|
||||
|
||||
// First boost bullet and target so that target is at rest
|
||||
G4ThreeVector toNeutronRest = -neutronMomentum.boostVector();
|
||||
neutronMomentum.boost(toNeutronRest);
|
||||
bulletMomentum.boost(toNeutronRest);
|
||||
|
||||
G4InuclElementaryParticle projectile(bulletMomentum, bullet->getDefinition() );
|
||||
G4InuclElementaryParticle targetNucleon(neutronMomentum, G4Neutron::Neutron() );
|
||||
G4InuclElementaryParticle spectatorNucleon(protonMomentum, G4Proton::Proton() );
|
||||
|
||||
ScatteringProducts products = SingleNucleonScattering(projectile, targetNucleon);
|
||||
|
||||
// Particles from SingleNucleonScattering are in CM frame of projectile
|
||||
// and moving neutron. Transform back to lab frame with -betacm, then add
|
||||
// them to outgoing list
|
||||
globalOutput.reset();
|
||||
G4LorentzVector temp;
|
||||
for (G4int i = 0; i < G4int(products.size()); i++) {
|
||||
temp = products[i].getMomentum();
|
||||
temp.boost(-betacm);
|
||||
products[i].setMomentum(temp);
|
||||
globalOutput.addOutgoingParticle(products[i]);
|
||||
}
|
||||
|
||||
// Add the recoil nucleon unmodified
|
||||
globalOutput.addOutgoingParticle(spectatorNucleon);
|
||||
|
||||
} else {
|
||||
NucleonPair products = AbsorptionOnDeuteron(bullet);
|
||||
globalOutput.reset();
|
||||
globalOutput.addOutgoingParticle(products.first);
|
||||
globalOutput.addOutgoingParticle(products.second);
|
||||
}
|
||||
} // Energy above threshold ?
|
||||
|
||||
// Test code
|
||||
// G4int numPart = globalOutput.numberOfOutgoingParticles();
|
||||
// std::vector<G4InuclElementaryParticle> testList = globalOutput.getOutgoingParticles();
|
||||
// G4LorentzVector sumP;
|
||||
// G4cout << " Global output " << G4endl;
|
||||
// for (G4int i = 0; i < numPart; i++) {
|
||||
// sumP += testList[i].getMomentum();
|
||||
// G4cout << testList[i] << G4endl;
|
||||
// }
|
||||
// G4cout << " Global 4-momentum sum = " << sumP << G4endl;
|
||||
// G4cout << " Initial lab energy = " << mD + bullet->getEnergy() << G4endl;
|
||||
|
||||
} else {
|
||||
G4Exception("G4LightTargetCollider::collide()","HAD_BERT_203",
|
||||
FatalException, "Scattering from this target not implemented");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
G4double G4LightTargetCollider::GammaDCrossSection(G4double gammaEnergy)
|
||||
{
|
||||
// Gamma deuteron cross section in mb parameterized from JLab data
|
||||
// No parameterization needed below pi0 threshold where cross section
|
||||
// is 100% disintegration
|
||||
G4double sigma = 1000.0;
|
||||
G4double term = 0.;
|
||||
if (gammaEnergy > 0.144 && gammaEnergy < 0.42) {
|
||||
term = (gammaEnergy - 0.24)/0.155;
|
||||
sigma = 0.065*std::exp(-term*term);
|
||||
} else if (gammaEnergy >= 0.42) {
|
||||
sigma = 0.000526/gammaEnergy/gammaEnergy/gammaEnergy/gammaEnergy;
|
||||
}
|
||||
|
||||
return sigma;
|
||||
}
|
||||
|
||||
|
||||
NucleonPair G4LightTargetCollider::AbsorptionOnDeuteron(G4InuclParticle* bullet)
|
||||
{
|
||||
// Do break-up in center of mass, convert to lab frame before returning
|
||||
// particles
|
||||
|
||||
G4double bulletMass = bullet->getMass();
|
||||
G4double bulletE = bullet->getEnergy();
|
||||
|
||||
G4double S = bulletMass*bulletMass + mD*mD + 2.*mD*bulletE;
|
||||
|
||||
G4double qcm = 0.;
|
||||
G4int outType1 = 0;
|
||||
G4int outType2 = 0;
|
||||
G4LorentzVector Mom1;
|
||||
G4LorentzVector Mom2;
|
||||
|
||||
// Set up outgoing particle types
|
||||
if (bullet->getDefinition() == G4Gamma::Gamma() ||
|
||||
bullet->getDefinition() == G4PionZero::PionZero() ) {
|
||||
qcm = std::sqrt( (S - (mP + mN)*(mP + mN)) * (S - (mP - mN)*(mP - mN))/S/4.);
|
||||
Mom1.setE(std::sqrt(mP*mP + qcm*qcm) );
|
||||
outType1 = G4InuclParticleNames::proton;
|
||||
Mom2.setE(std::sqrt(mN*mN + qcm*qcm) );
|
||||
outType2 = G4InuclParticleNames::neutron;
|
||||
|
||||
} else if (bullet->getDefinition() == G4PionPlus::PionPlus() ) {
|
||||
qcm = std::sqrt( (S - 4.*mP*mP)/4.);
|
||||
Mom1.setE(std::sqrt(mP*mP + qcm*qcm) );
|
||||
outType1 = G4InuclParticleNames::proton;
|
||||
Mom2.setE(std::sqrt(mP*mP + qcm*qcm) );
|
||||
outType2 = G4InuclParticleNames::proton;
|
||||
|
||||
} else if (bullet->getDefinition() == G4PionMinus::PionMinus() ) {
|
||||
qcm = std::sqrt( (S - 4.*mN*mN)/4.);
|
||||
Mom1.setE(std::sqrt(mN*mN + qcm*qcm) );
|
||||
outType1 = G4InuclParticleNames::neutron;
|
||||
Mom2.setE(std::sqrt(mN*mN + qcm*qcm) );
|
||||
outType2 = G4InuclParticleNames::neutron;
|
||||
|
||||
} else {
|
||||
G4Exception("G4LightTargetCollider::collide()","HAD_BERT_204",
|
||||
FatalException, "Illegal bullet type");
|
||||
}
|
||||
|
||||
// Sample angular distribution, assuming 100% S wave (no D-wave)
|
||||
G4ThreeVector qVect = qcm*G4RandomDirection();
|
||||
Mom1.setVect(qVect);
|
||||
Mom2.setVect(-qVect);
|
||||
|
||||
// Boost to lab frame
|
||||
G4ThreeVector betacm(0., 0., bullet->getMomModule()/(bulletE + mD) );
|
||||
Mom1.boost(betacm);
|
||||
Mom2.boost(betacm);
|
||||
|
||||
G4InuclElementaryParticle particle1(Mom1, outType1);
|
||||
G4InuclElementaryParticle particle2(Mom2, outType2);
|
||||
NucleonPair nucleon_pair(particle1, particle2);
|
||||
|
||||
// if pion, use parameterization of B.G. Ritchie, PRC 44, 533 (1991)
|
||||
// Total cross section: 1/E + Lorentzian
|
||||
|
||||
return nucleon_pair;
|
||||
}
|
||||
|
||||
|
||||
ScatteringProducts
|
||||
G4LightTargetCollider::SingleNucleonScattering(const G4InuclElementaryParticle& projectile,
|
||||
const G4InuclElementaryParticle& nucleon)
|
||||
{
|
||||
// At this point projectile and nucleon momenta are in nucleon rest frame
|
||||
G4int reactionIndex = G4InuclElementaryParticle::type(projectile.getDefinition() )
|
||||
* G4InuclElementaryParticle::type(nucleon.getDefinition() );
|
||||
|
||||
const G4CascadeChannel* xsecTable = G4CascadeChannelTables::GetTable(reactionIndex);
|
||||
G4double ke = projectile.getKineticEnergy();
|
||||
G4int mult = xsecTable->getMultiplicity(ke);
|
||||
|
||||
std::vector<G4double> masses;
|
||||
G4double mass = 0.0;
|
||||
G4LorentzVector totalMom = projectile.getMomentum() + nucleon.getMomentum();
|
||||
G4double Ecm = totalMom.mag();
|
||||
|
||||
std::vector<G4LorentzVector> cmMomenta;
|
||||
std::vector<G4int> particle_kinds;
|
||||
G4int itry = 0;
|
||||
G4int itry_max = 200;
|
||||
G4bool generate = true;
|
||||
|
||||
while (mult > 1) {
|
||||
itry = 0;
|
||||
generate = true;
|
||||
while (generate && itry < itry_max) {
|
||||
particle_kinds.clear();
|
||||
xsecTable->getOutgoingParticleTypes(particle_kinds, mult, ke);
|
||||
masses.clear();
|
||||
for (G4int i = 0; i < mult; i++) {
|
||||
mass = G4InuclElementaryParticle::getParticleMass(particle_kinds[i]);
|
||||
masses.push_back(mass);
|
||||
}
|
||||
|
||||
fsGen.Configure(const_cast<G4InuclElementaryParticle*>(&projectile),
|
||||
const_cast<G4InuclElementaryParticle*>(&nucleon),
|
||||
particle_kinds);
|
||||
// Generate final state in CM of projectile and at-rest nucleon
|
||||
cmMomenta.clear();
|
||||
generate = !fsGen.Generate(Ecm, masses, cmMomenta);
|
||||
itry++;
|
||||
} // while
|
||||
|
||||
if (itry == itry_max) mult--;
|
||||
else break;
|
||||
|
||||
} // while mult
|
||||
|
||||
ScatteringProducts finalState;
|
||||
if (mult < 2) {
|
||||
G4Exception("G4LightTargetCollider::SingleNucleonScattering()","HAD_BERT_202",
|
||||
JustWarning, "Failed to generate final state");
|
||||
// Final state particles not in CM - just using them as dummies
|
||||
finalState.push_back(projectile);
|
||||
finalState.push_back(nucleon);
|
||||
|
||||
} else {
|
||||
for (G4int i = 0; i < mult; i++) {
|
||||
G4InuclElementaryParticle fsPart(cmMomenta[i], particle_kinds[i]);
|
||||
finalState.push_back(fsPart);
|
||||
}
|
||||
}
|
||||
|
||||
return finalState;
|
||||
}
|
||||
@@ -18,6 +18,7 @@ CPPFLAGS += -I$(G4BASE)/global/management/include \
|
||||
-I$(G4BASE)/track/include \
|
||||
-I$(G4BASE)/geometry/volumes/include \
|
||||
-I$(G4BASE)/geometry/management/include \
|
||||
-I$(G4BASE)/processes/cuts/include \
|
||||
-I$(G4BASE)/processes/management/include \
|
||||
-I$(G4BASE)/processes/hadronic/management/include/ \
|
||||
-I$(G4BASE)/processes/hadronic/util/include/ \
|
||||
|
||||
@@ -14,6 +14,41 @@ code and to keep track of all tags.
|
||||
* Please list in reverse chronological order (last date on top)
|
||||
---------------------------------------------------------------
|
||||
|
||||
26 November 2019 - V.Ivanchenko (hadr-cohe-V10-05-10)
|
||||
---------------------------------------------------------------
|
||||
- G4HadronElastic : Added limit on number of warning printouts
|
||||
|
||||
19 November 2019 - G. Folger (hadr-cohe-V10-05-09)
|
||||
---------------------------------------------------------------
|
||||
- remove using namespace std and using namespace CLHEP from header file
|
||||
G4NeutronElectronElModel.hh
|
||||
|
||||
15 November 2019 - V.Ivanchenko (hadr-cohe-V10-05-08)
|
||||
---------------------------------------------------------------
|
||||
- G4HadronElastic : Change warning printout, in the case if sampled
|
||||
t>tmax resample using simple algorithm, protect this warning
|
||||
by G4VERBOSE, this is a partial fix of #2204
|
||||
|
||||
06 November 2019 - A.Ribon (hadr-cohe-V10-05-07)
|
||||
---------------------------------------------------------------
|
||||
- G4HadronElastic : Coverity fix in the unused method GetSlopeCof.
|
||||
|
||||
31 October 2019 - V.Ivanchenko (hadr-cohe-V10-05-06)
|
||||
--------------------------------------------------------
|
||||
- G4ElasticHadrNucleusHE - reduction of size of data structure and
|
||||
time for initialisation ~2 times; general code clean-up; addition
|
||||
of protections
|
||||
|
||||
07 October 2019 - V.Grichine (hadr-cohe-V10-05-05)
|
||||
---------------------------------------------------------------
|
||||
- G4hadronElstic - new method for s-,c-,b-particle
|
||||
- ds/dt slope modifications in preparation
|
||||
|
||||
03 July 2019 - V.Ivanchenko (hadr-cohe-V10-05-04)
|
||||
--------------------------------------------------------
|
||||
- G4ElasticHadrNucleusHE - general clean-up of the code
|
||||
- G4HadronElastic - added new parameterisation of A.Yeltokov
|
||||
|
||||
14 May 2019 - A.Ribon (hadr-cohe-V10-05-03)
|
||||
--------------------------------------------------------
|
||||
- G4HadronElastic : numerically safer treatment of the very rare cases
|
||||
|
||||
+44
-75
@@ -23,15 +23,12 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
// G4ElasticHadrNucleusHe.hh
|
||||
|
||||
// The generator of high energy hadron-nucleus elastic scattering
|
||||
// The hadron kinetic energy T > 1 GeV
|
||||
// N. Starkov 2003.
|
||||
// N.Starkov 2003.
|
||||
//
|
||||
// 19.05.04 Variant for G4 6.1: The 'ApplyYourself' was changed
|
||||
// 19.11.05 The HE elastic scattering on proton is added (N.Starkov)
|
||||
// 16.11.06 General redesign (N.Starkov)
|
||||
// 23.11.06 General cleanup, ONQ0=3 (V.Ivanchenko)
|
||||
@@ -55,43 +52,39 @@
|
||||
|
||||
class G4NistManager;
|
||||
|
||||
static const G4int NHADRONS = 26; // Number of hadrons
|
||||
static const G4int ONQ0 = 5; // The initial number of steps on Q2
|
||||
static const G4int ONQ2 = 100; // The total number of steps on Q2
|
||||
static const G4int NENERGY = 30;
|
||||
static const G4int ZMAX = 93;
|
||||
static const G4int NQTABLE = NENERGY*ONQ2;
|
||||
static const G4int NHADRONS = 26; // Number of allowed hadrons
|
||||
static const G4int ONQ2 = 102; // Number of points on Q2
|
||||
static const G4int NENERGY = 24;
|
||||
static const G4int ZMAX = 93;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
class G4ElasticData
|
||||
{
|
||||
|
||||
friend class G4ElasticHadrNucleusHE;
|
||||
|
||||
public:
|
||||
|
||||
G4ElasticData(const G4ParticleDefinition* h, G4int Z, G4int A, G4double* e);
|
||||
G4ElasticData(const G4ParticleDefinition* h, G4int Z, G4int A,
|
||||
const G4double* e);
|
||||
|
||||
~G4ElasticData(){}
|
||||
|
||||
const G4ParticleDefinition* Hadron() {return hadr;}
|
||||
~G4ElasticData() {}
|
||||
|
||||
private:
|
||||
|
||||
void DefineNucleusParameters(G4int A);
|
||||
const G4ParticleDefinition* hadr;
|
||||
|
||||
// hide assignment operator
|
||||
G4ElasticData & operator=(const G4ElasticData &right);
|
||||
G4ElasticData(const G4ElasticData&);
|
||||
|
||||
public:
|
||||
G4double R1, R2, Pnucl, Aeff;
|
||||
G4double limitQ2;
|
||||
G4double dQ2;
|
||||
G4double massA;
|
||||
G4double massA2;
|
||||
G4int dnkE[NENERGY];
|
||||
G4double maxQ2[NENERGY];
|
||||
|
||||
G4double TableQ2[ONQ2];
|
||||
G4double TableCrossSec[NQTABLE];
|
||||
std::vector<G4double> fCumProb[NENERGY];
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
@@ -113,97 +106,81 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
G4double HadronNucleusQ2_2(G4ElasticData * pElD, G4int Z,
|
||||
G4double plabGeV, G4double tmax);
|
||||
G4double HadronNucleusQ2_2(const G4ElasticData *pElD, G4double plabGeV,
|
||||
G4double tmax);
|
||||
|
||||
void DefineHadronValues(G4int Z);
|
||||
G4int FillFq2(G4int A);
|
||||
|
||||
G4double GetLightFq2(G4int Z, G4int A, G4double Q);
|
||||
G4double GetHeavyFq2(G4int Z, G4int Nucleus, G4double *LineFq2);
|
||||
|
||||
G4double GetQ2_2(G4int N, G4double* Q, G4double* F, G4double R);
|
||||
G4double GetQ2_2(G4int N, G4int Nmax,
|
||||
const std::vector<G4double>& F, G4double rand);
|
||||
|
||||
G4double LineInterpol(G4double p0, G4double p2,
|
||||
G4double c1, G4double c2,
|
||||
G4double p);
|
||||
|
||||
G4double HadrNucDifferCrSec(G4int Z, G4int Nucleus, G4double Q2);
|
||||
G4double HadrNucDifferCrSec(G4int A, G4double Q2);
|
||||
|
||||
void InterpolateHN(G4int n, const G4double EnP[],
|
||||
const G4double C0P[], const G4double C1P[],
|
||||
const G4double B0P[], const G4double B1P[]);
|
||||
|
||||
// hide assignment operator
|
||||
G4ElasticHadrNucleusHE & operator=(const G4ElasticHadrNucleusHE &right);
|
||||
G4ElasticHadrNucleusHE(const G4ElasticHadrNucleusHE&);
|
||||
|
||||
G4double GetBinomCof( G4int n, G4int m );
|
||||
|
||||
G4double GetFt(G4double Q2);
|
||||
|
||||
G4double GetDistrFun(G4double Q2);
|
||||
|
||||
G4double GetQ2(G4double Ran);
|
||||
|
||||
G4double HadronProtonQ2(const G4ParticleDefinition * aHadron,
|
||||
G4double inLabMom);
|
||||
|
||||
void GetKinematics(const G4ParticleDefinition * aHadron,
|
||||
G4double MomentumH);
|
||||
G4double HadronProtonQ2(G4double plab, G4double tmax);
|
||||
|
||||
void Binom();
|
||||
|
||||
void FillData(const G4ParticleDefinition* p, G4int idx, G4int Z);
|
||||
|
||||
inline G4double LineInterpol(G4double p0, G4double p2,
|
||||
G4double c1, G4double c2, G4double p);
|
||||
|
||||
inline G4double GetBinomCof( G4int n, G4int m );
|
||||
|
||||
// hide assignment operator
|
||||
G4ElasticHadrNucleusHE & operator=(const G4ElasticHadrNucleusHE &right);
|
||||
G4ElasticHadrNucleusHE(const G4ElasticHadrNucleusHE&);
|
||||
|
||||
// fields
|
||||
G4int iHadrCode;
|
||||
G4int iHadron;
|
||||
static const G4int HadronCode[NHADRONS];
|
||||
static const G4int HadronType[NHADRONS];
|
||||
static const G4int HadronType1[NHADRONS];
|
||||
G4int iHadron1;
|
||||
static const G4int fHadronCode[NHADRONS];
|
||||
static const G4int fHadronType[NHADRONS];
|
||||
static const G4int fHadronType1[NHADRONS];
|
||||
|
||||
// momemtum limits
|
||||
G4double plabLowLimit;
|
||||
G4double dQ2;
|
||||
|
||||
// transition between internal and CLHEP units
|
||||
G4double MbToGeV2;
|
||||
G4double sqMbToGeV;
|
||||
G4double Fm2ToGeV2;
|
||||
G4double GeV2;
|
||||
G4double protonM; // GeV
|
||||
G4double protonM2; // GeV^2
|
||||
|
||||
// projectile kinematics in GeV
|
||||
G4double hMass;
|
||||
G4double hMass2;
|
||||
G4double hLabMomentum;
|
||||
G4double hLabMomentum2;
|
||||
G4double MomentumCM;
|
||||
G4double HadrEnergy;
|
||||
|
||||
// elastic parameters
|
||||
G4double HadrTot, HadrSlope, HadrReIm, TotP,
|
||||
DDSect2, DDSect3, ConstU, FmaxT;
|
||||
G4double HadrTot, HadrSlope, HadrReIm, TotP;
|
||||
G4double DDSect2, DDSect3, ConstU;
|
||||
|
||||
// momentum limits for different models of hadron/nucleon scatetring
|
||||
G4double BoundaryP[7], BoundaryTL[7], BoundaryTG[7];
|
||||
|
||||
// parameterisation of scattering
|
||||
G4double Slope1, Slope2, Coeff1, Coeff2, MaxTR;
|
||||
G4double Slope1, Slope2, Coeff1, Coeff2;
|
||||
G4double Slope0, Coeff0;
|
||||
|
||||
G4double aAIm, aDIm, Dtot11;
|
||||
|
||||
// nucleaus parameters
|
||||
G4double R1, R2, Pnucl, Aeff;
|
||||
G4int NumbN;
|
||||
G4double R1, R2, Pnucl, Aeff, Q2max;
|
||||
|
||||
static G4double Energy[NENERGY];
|
||||
static G4double LowEdgeEnergy[NENERGY];
|
||||
static G4double ABinom[240][240];
|
||||
static G4double fLineF[ONQ2];
|
||||
static G4double fEnergy[NENERGY];
|
||||
static G4double fLowEdgeEnergy[NENERGY];
|
||||
static G4double fBinom[240][240];
|
||||
|
||||
static G4ElasticData* SetOfElasticData[NHADRONS][ZMAX];
|
||||
static G4ElasticData* fElasticData[NHADRONS][ZMAX];
|
||||
G4NistManager* nistManager;
|
||||
G4bool isMaster;
|
||||
|
||||
@@ -228,15 +205,7 @@ G4double G4ElasticHadrNucleusHE::LineInterpol(G4double p1, G4double p2,
|
||||
inline
|
||||
G4double G4ElasticHadrNucleusHE::GetBinomCof(G4int numN, G4int numM)
|
||||
{
|
||||
return (numN >= numM && numN < 240) ? ABinom[numN][numM] : 0.0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
inline
|
||||
G4double G4ElasticHadrNucleusHE::GetDistrFun(G4double Q2)
|
||||
{
|
||||
return GetFt(Q2)/FmaxT;
|
||||
return (numN >= numM && numN < 240) ? fBinom[numN][numM] : 0.0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -60,6 +60,8 @@ public:
|
||||
// sample momentum transfer using Lab. momentum
|
||||
G4double SampleInvariantT(const G4ParticleDefinition* p, G4double plab,
|
||||
G4int Z, G4int A) override;
|
||||
|
||||
G4double GetSlopeCof( const G4int pdg );
|
||||
|
||||
inline void SetLowestEnergyLimit(G4double value);
|
||||
|
||||
@@ -82,6 +84,7 @@ private:
|
||||
G4ParticleDefinition* theAlpha;
|
||||
|
||||
G4double lowestEnergyLimit;
|
||||
G4int nwarn;
|
||||
};
|
||||
|
||||
inline void G4HadronElastic::SetLowestEnergyLimit(G4double value)
|
||||
|
||||
+1
-4
@@ -44,9 +44,6 @@
|
||||
#include "G4Nucleus.hh"
|
||||
#include "G4NucleiProperties.hh"
|
||||
|
||||
using namespace std;
|
||||
using namespace CLHEP;
|
||||
|
||||
class G4ParticleDefinition;
|
||||
class G4PhysicsLogVector;
|
||||
class G4PhysicsTable;
|
||||
@@ -106,7 +103,7 @@ inline G4double G4NeutronElectronElModel::CalculateAm( G4double Tkin)
|
||||
fee = (Tkin+fM)*fme/fM;
|
||||
// G4cout<<"fee = "<<fee<<" MeV"<<G4endl;
|
||||
fee2 = fee*fee;
|
||||
G4double momentum = sqrt( fee2 - fme2 );
|
||||
G4double momentum = std::sqrt( fee2 - fme2 );
|
||||
G4double k = momentum/CLHEP::hbarc;
|
||||
G4double ch = 1.13;
|
||||
G4double zn = 1.77*k*CLHEP::Bohr_radius;
|
||||
|
||||
@@ -31,6 +31,7 @@ include_directories(${CMAKE_SOURCE_DIR}/source/particles/hadrons/ions/include)
|
||||
include_directories(${CMAKE_SOURCE_DIR}/source/particles/hadrons/mesons/include)
|
||||
include_directories(${CMAKE_SOURCE_DIR}/source/particles/leptons/include)
|
||||
include_directories(${CMAKE_SOURCE_DIR}/source/particles/management/include)
|
||||
include_directories(${CMAKE_SOURCE_DIR}/source/processes/cuts/include)
|
||||
include_directories(${CMAKE_SOURCE_DIR}/source/processes/hadronic/cross_sections/include)
|
||||
include_directories(${CMAKE_SOURCE_DIR}/source/processes/hadronic/management/include)
|
||||
include_directories(${CMAKE_SOURCE_DIR}/source/processes/hadronic/models/management/include)
|
||||
@@ -84,6 +85,7 @@ GEANT4_DEFINE_MODULE(NAME G4hadronic_coherent_elastic
|
||||
GRANULAR_DEPENDENCIES
|
||||
G4baryons
|
||||
G4bosons
|
||||
G4cuts
|
||||
G4geometrymng
|
||||
G4globman
|
||||
G4had_mod_man
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -50,7 +50,9 @@ G4HadronElastic::G4HadronElastic(const G4String& name)
|
||||
{
|
||||
SetMinEnergy( 0.0*GeV );
|
||||
SetMaxEnergy( G4HadronicParameters::Instance()->GetMaxEnergy() );
|
||||
lowestEnergyLimit= 1.e-6*eV;
|
||||
lowestEnergyLimit= 1.e-6*eV;
|
||||
pLocalTmax = 0.0;
|
||||
nwarn = 0;
|
||||
|
||||
theProton = G4Proton::Proton();
|
||||
theNeutron = G4Neutron::Neutron();
|
||||
@@ -115,38 +117,31 @@ G4HadFinalState* G4HadronElastic::ApplyYourself(
|
||||
pLocalTmax = 4.0*momentumCMS*momentumCMS;
|
||||
|
||||
// Sampling in CM system
|
||||
G4double t = SampleInvariantT(theParticle, plab, Z, A);
|
||||
G4double t = SampleInvariantT(theParticle, plab, Z, A);
|
||||
|
||||
if(t < 0.0 || t > pLocalTmax) {
|
||||
// For the very rare cases where cos(theta) is greater than 1 or smaller than -1,
|
||||
// print some debugging information via a "JustWarning" exception, and resample
|
||||
// using the default algorithm
|
||||
#ifdef G4VERBOSE
|
||||
if(nwarn < 2) {
|
||||
G4ExceptionDescription ed;
|
||||
ed << GetModelName() << " wrong sampling t= " << t << " tmax= " << pLocalTmax
|
||||
<< " for " << aParticle->GetDefinition()->GetParticleName()
|
||||
<< " ekin=" << ekin << " MeV"
|
||||
<< " off (Z,A)=(" << Z << "," << A << ") - will be resampled" << G4endl;
|
||||
G4Exception( "G4HadronElastic::ApplyYourself", "hadEla001", JustWarning, ed);
|
||||
++nwarn;
|
||||
}
|
||||
#endif
|
||||
t = G4HadronElastic::SampleInvariantT(theParticle, plab, Z, A);
|
||||
}
|
||||
|
||||
G4double phi = G4UniformRand()*CLHEP::twopi;
|
||||
G4double cost = 1. - 2.0*t/pLocalTmax;
|
||||
|
||||
// For the very rare cases where cos(theta) is greater than 1 or smaller than -1,
|
||||
// print some debugging information via a "JustWarning" exception, and safely
|
||||
// return (simply setting "cost=1.0" or "cost=-1.0" can sometimes cause a crash,
|
||||
// due to numerical imprecisions, e.g. 3-momentum = (0.0, 0.0, 0.0) but
|
||||
// Ekin very small but not 0.0).
|
||||
if ( std::abs( cost ) > 1.0 ) {
|
||||
G4ExceptionDescription ed;
|
||||
ed << " LARGE cost ! cost=" << cost << " for " << aParticle->GetDefinition()->GetParticleName()
|
||||
<< " ekin=" << ekin << " MeV" << " on (Z,A)=(" << Z << "," << A << ")" << G4endl;
|
||||
if ( cost > 1.0 ) {
|
||||
// We assume here no interaction and let the projectile keep going unchanged.
|
||||
theParticleChange.SetEnergyChange( ekin );
|
||||
theParticleChange.SetMomentumChange( aParticle->Get4Momentum().vect().unit() );
|
||||
ed << "\t No interaction: the projectile keeps going unchanged!" << G4endl;
|
||||
G4Exception( "G4HadronElastic::ApplyYourself", "hadEla001", JustWarning, ed );
|
||||
return &theParticleChange;
|
||||
} else { // cost < -1.0 ) {
|
||||
// We assume here that the projectile stops and its energy is deposited locally
|
||||
// (for simplicity, given that this condition should happen rarely, we neglect
|
||||
// the recoil of the target nucleus).
|
||||
theParticleChange.SetEnergyChange( 0.0 );
|
||||
theParticleChange.SetLocalEnergyDeposit( ekin );
|
||||
ed << "\t Projectile stops and its energy is deposited locally:" << G4endl
|
||||
<< "\t neglected recoil of the target nucleus!" << G4endl;
|
||||
G4Exception( "G4HadronElastic::ApplyYourself", "hadEla002", JustWarning, ed );
|
||||
return &theParticleChange;
|
||||
}
|
||||
}
|
||||
if (cost > 1.0) { cost = 1.0; }
|
||||
else if(cost < -1.0) { cost = -1.0; }
|
||||
|
||||
G4double sint = std::sqrt((1.0-cost)*(1.0+cost));
|
||||
|
||||
@@ -207,22 +202,58 @@ G4HadFinalState* G4HadronElastic::ApplyYourself(
|
||||
|
||||
// sample momentum transfer in the CMS system
|
||||
G4double
|
||||
G4HadronElastic::SampleInvariantT(const G4ParticleDefinition*,
|
||||
G4double, G4int, G4int A)
|
||||
G4HadronElastic::SampleInvariantT(const G4ParticleDefinition* part,
|
||||
G4double mom, G4int, G4int A)
|
||||
{
|
||||
static const G4double GeV2 = GeV*GeV;
|
||||
const G4double plabLowLimit = 400.0*CLHEP::MeV;
|
||||
const G4double GeV2 = GeV*GeV;
|
||||
const G4double z07in13 = std::pow(0.7, 0.3333333333);
|
||||
|
||||
G4int pdg = std::abs(part->GetPDGEncoding());
|
||||
G4double tmax = pLocalTmax/GeV2;
|
||||
G4double aa, bb, cc;
|
||||
static const G4double dd = 10.;
|
||||
|
||||
G4double aa, bb, cc, dd;
|
||||
G4Pow* g4pow = G4Pow::GetInstance();
|
||||
if (A <= 62) {
|
||||
bb = 14.5*g4pow->Z23(A);
|
||||
aa = g4pow->powZ(A, 1.63)/bb;
|
||||
cc = 1.4*g4pow->Z13(A)/dd;
|
||||
} else {
|
||||
bb = 60.*g4pow->Z13(A);
|
||||
aa = g4pow->powZ(A, 1.33)/bb;
|
||||
cc = 0.4*g4pow->powZ(A, 0.4)/dd;
|
||||
if (pdg == 211){ //Pions
|
||||
if(mom >= plabLowLimit){ //High energy
|
||||
bb = 14.5*g4pow->Z23(A);/*14.5*/
|
||||
dd = 10.;
|
||||
cc = 0.075*g4pow->Z13(A)/dd;//1.4
|
||||
//aa = g4pow->powZ(A, 1.93)/bb;//1.63
|
||||
aa = (A*A)/bb;//1.63
|
||||
} else { //Low energy
|
||||
bb = 29.*z07in13*z07in13*g4pow->Z23(A);
|
||||
dd = 15.;
|
||||
cc = 0.04*g4pow->Z13(A)/dd;//1.4
|
||||
aa = g4pow->powZ(A, 1.63)/bb;//1.63
|
||||
}
|
||||
} else { //Other particles
|
||||
bb = 14.5*g4pow->Z23(A);
|
||||
dd = 20.;
|
||||
aa = (A*A)/bb;//1.63
|
||||
cc = 1.4*g4pow->Z13(A)/dd;
|
||||
}
|
||||
//===========================
|
||||
} else { //(A>62)
|
||||
if (pdg == 211) {
|
||||
if(mom >= plabLowLimit){ //high
|
||||
bb = 60.*z07in13*g4pow->Z13(A);//60
|
||||
dd = 30.;
|
||||
aa = 0.5*(A*A)/bb;//1.33
|
||||
cc = 4.*g4pow->powZ(A,0.4)/dd;//1:0.4 --- 2: 0.4
|
||||
} else { //low
|
||||
bb = 120.*z07in13*g4pow->Z13(A);//60
|
||||
dd = 30.;
|
||||
aa = 2.*g4pow->powZ(A,1.33)/bb;
|
||||
cc = 4.*g4pow->powZ(A,0.4)/dd;//1:0.4 --- 2: 0.4
|
||||
}
|
||||
} else {
|
||||
bb = 60.*g4pow->Z13(A);
|
||||
dd = 25.;
|
||||
aa = g4pow->powZ(A,1.33)/bb;//1.33
|
||||
cc = 0.2*g4pow->powZ(A,0.4)/dd;//1:0.4 --- 2: 0.4
|
||||
}
|
||||
}
|
||||
G4double q1 = 1.0 - G4Exp(-bb*tmax);
|
||||
G4double q2 = 1.0 - G4Exp(-dd*tmax);
|
||||
@@ -234,3 +265,119 @@ G4HadronElastic::SampleInvariantT(const G4ParticleDefinition*,
|
||||
}
|
||||
return -GeV2*G4Log(1.0 - G4UniformRand()*q1)/bb;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////
|
||||
//
|
||||
// Cofs for s-,c-,b-particles ds/dt slopes
|
||||
|
||||
G4double G4HadronElastic::GetSlopeCof(const G4int pdg )
|
||||
{
|
||||
// The input parameter "pdg" should be the absolute value of the PDG code
|
||||
// (i.e. the same value for a particle and its antiparticle).
|
||||
|
||||
G4double coeff = 1.0;
|
||||
|
||||
// heavy barions
|
||||
|
||||
static const G4double lBarCof1S = 0.88;
|
||||
static const G4double lBarCof2S = 0.76;
|
||||
static const G4double lBarCof3S = 0.64;
|
||||
static const G4double lBarCof1C = 0.784378;
|
||||
static const G4double lBarCofSC = 0.664378;
|
||||
static const G4double lBarCof2SC = 0.544378;
|
||||
static const G4double lBarCof1B = 0.740659;
|
||||
static const G4double lBarCofSB = 0.620659;
|
||||
static const G4double lBarCof2SB = 0.500659;
|
||||
|
||||
if( pdg == 3122 || pdg == 3222 || pdg == 3112 || pdg == 3212 )
|
||||
{
|
||||
coeff = lBarCof1S; // Lambda, Sigma+, Sigma-, Sigma0
|
||||
|
||||
} else if( pdg == 3322 || pdg == 3312 )
|
||||
{
|
||||
coeff = lBarCof2S; // Xi-, Xi0
|
||||
}
|
||||
else if( pdg == 3324)
|
||||
{
|
||||
coeff = lBarCof3S; // Omega
|
||||
}
|
||||
else if( pdg == 4122 || pdg == 4212 || pdg == 4222 || pdg == 4112 )
|
||||
{
|
||||
coeff = lBarCof1C; // LambdaC+, SigmaC+, SigmaC++, SigmaC0
|
||||
}
|
||||
else if( pdg == 4332 )
|
||||
{
|
||||
coeff = lBarCof2SC; // OmegaC
|
||||
}
|
||||
else if( pdg == 4232 || pdg == 4132 )
|
||||
{
|
||||
coeff = lBarCofSC; // XiC+, XiC0
|
||||
}
|
||||
else if( pdg == 5122 || pdg == 5222 || pdg == 5112 || pdg == 5212 )
|
||||
{
|
||||
coeff = lBarCof1B; // LambdaB, SigmaB+, SigmaB-, SigmaB0
|
||||
}
|
||||
else if( pdg == 5332 )
|
||||
{
|
||||
coeff = lBarCof2SB; // OmegaB-
|
||||
}
|
||||
else if( pdg == 5132 || pdg == 5232 ) // XiB-, XiB0
|
||||
{
|
||||
coeff = lBarCofSB;
|
||||
}
|
||||
// heavy mesons Kaons?
|
||||
static const G4double lMesCof1S = 0.82; // Kp/piP kaons?
|
||||
static const G4double llMesCof1C = 0.676568;
|
||||
static const G4double llMesCof1B = 0.610989;
|
||||
static const G4double llMesCof2C = 0.353135;
|
||||
static const G4double llMesCof2B = 0.221978;
|
||||
static const G4double llMesCofSC = 0.496568;
|
||||
static const G4double llMesCofSB = 0.430989;
|
||||
static const G4double llMesCofCB = 0.287557;
|
||||
static const G4double llMesCofEtaP = 0.88;
|
||||
static const G4double llMesCofEta = 0.76;
|
||||
|
||||
if( pdg == 321 || pdg == 311 || pdg == 310 )
|
||||
{
|
||||
coeff = lMesCof1S; //K+-0
|
||||
}
|
||||
else if( pdg == 511 || pdg == 521 )
|
||||
{
|
||||
coeff = llMesCof1B; // BMeson0, BMeson+
|
||||
}
|
||||
else if(pdg == 421 || pdg == 411 )
|
||||
{
|
||||
coeff = llMesCof1C; // DMeson+, DMeson0
|
||||
}
|
||||
else if( pdg == 531 )
|
||||
{
|
||||
coeff = llMesCofSB; // BSMeson0
|
||||
}
|
||||
else if( pdg == 541 )
|
||||
{
|
||||
coeff = llMesCofCB; // BCMeson+-
|
||||
}
|
||||
else if(pdg == 431 )
|
||||
{
|
||||
coeff = llMesCofSC; // DSMeson+-
|
||||
}
|
||||
else if(pdg == 441 || pdg == 443 )
|
||||
{
|
||||
coeff = llMesCof2C; // Etac, JPsi
|
||||
}
|
||||
else if(pdg == 553 )
|
||||
{
|
||||
coeff = llMesCof2B; // Upsilon
|
||||
}
|
||||
else if(pdg == 221 )
|
||||
{
|
||||
coeff = llMesCofEta; // Eta
|
||||
}
|
||||
else if(pdg == 331 )
|
||||
{
|
||||
coeff = llMesCofEtaP; // Eta'
|
||||
}
|
||||
return coeff;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -14,6 +14,118 @@ code and to keep track of all tags.
|
||||
* Please list in reverse chronological order (last date on top)
|
||||
---------------------------------------------------------------
|
||||
|
||||
25 November 2019 Vladimir Ivanchenko (hadr-deex-V10-05-21)
|
||||
- G4PhotonEvaporation - fixed Coverity problem
|
||||
|
||||
16 November 2019 Vladimir Ivanchenko (hadr-deex-V10-05-20)
|
||||
- G4PhotonEvaporation - access G4NuclearPolarizationStore only
|
||||
if correlated gamma decay is enabled
|
||||
|
||||
11 November 2019 Vladimir Ivanchenko (hadr-deex-V10-05-19)
|
||||
- G4CompetitiveFission, G4FissionBarrier, G4FissionParameters - added
|
||||
numerical protections; cleanup C++11 keywords; move headers to
|
||||
source code
|
||||
|
||||
05 November 2019 Vladimir Ivanchenko (hadr-deex-V10-05-18)
|
||||
- G4NuclearLevelData, G4LevelManager, G4GEMChannel, G4GEMProbability,
|
||||
G4GEMProbabilityVI, G4EvaporationChannel, G4EvaporationProbability
|
||||
use consistently pairing correction from G4NuclearLevelData and
|
||||
verbosity level for debigging
|
||||
- G4FermiBreakUpVI - use consistently verbosity from de-excitation
|
||||
module, simplified decay kinematics
|
||||
- G4VEmissionProbability, G4Evaporation, G4UnstableFragmentBreakUp
|
||||
consistently used decay channels in all components of the
|
||||
de-excitation module
|
||||
- G4ExcitationHandler - fixed problem seen in medical test of
|
||||
fragmentation - provide full de-excitation of excited light
|
||||
fragments
|
||||
- G4PhotonEvaporation - fixed gamma de-excitation when initial
|
||||
excitation energy is between ground and 1st levels
|
||||
|
||||
19 October 2019 Vladimir Ivanchenko (hadr-deex-V10-05-17)
|
||||
- G4ExcitationHandler, G4Evaporation - attempt to reduce CPU
|
||||
|
||||
16 October 2019 Vladimir Ivanchenko (hadr-deex-V10-05-16)
|
||||
- G4ExcitationHandler, G4Evaporation - improved debug printout
|
||||
- G4UnstableFragmentBreakUp - allowed only residual fragments, which
|
||||
are present in the nuclear level DB; those fragments which are not
|
||||
in the DB are forced to decay on fragments from the DB;
|
||||
improved debug printout
|
||||
|
||||
02 October 2019 Vladimir Ivanchenko (hadr-deex-V10-05-15)
|
||||
- G4ExcitationHandler - removed warning on high excitation
|
||||
- G4NuclearLevelData - added new public interface to enable
|
||||
upload of nuclear level data before 1st event with the signature:
|
||||
UploadNuclearLevelData(G4int maxZ)
|
||||
- G4LevelReader - small reduction of memory churn
|
||||
- G4DeexPrecoParameters - added two new parameters
|
||||
- G4DeexParametersMessenger - added UI command
|
||||
- G4VEmissionProbability - implemented option to force a residual
|
||||
nucleus to be at one of known discrete levels
|
||||
- G4FermiFragmentsPoolVI - removed unphysical fragments and corresponding
|
||||
data structures
|
||||
- G4FermiFragment - removed unused boolean members
|
||||
- G4FermiBreakUpVI - clean internal data after decay loop and not before
|
||||
|
||||
18 September 2019 Vladimir Ivanchenko (hadr-deex-V10-05-14)
|
||||
- G4ExcitationHandler - removed second photon evaporation loop,
|
||||
because since long all gamma decay are already happens in the
|
||||
1st loop; use more C++11 constructions
|
||||
- G4FermiFragmentsPoolVI - implement new method HasChannels(..)
|
||||
- G4FermiBreakUpVI - use new HasChannels(..) inside IsAPplicable(..)
|
||||
- G4Evaporation - make coherent use of IsApplicable(..)
|
||||
from FermiBreakUp and force simplified decay of exotic fragments
|
||||
with G4UnstableFragmentBreakUp
|
||||
- G4UnstableFragmentBreakUp - change logic allowing decay of an
|
||||
exotic fragment (fragment is not known in gamma level DB) and
|
||||
never release it
|
||||
|
||||
11 September 2019 Vladimir Ivanchenko (hadr-deex-V10-05-13)
|
||||
- G4ExcitationHandler - added limit on number of warnings on high
|
||||
excitation of input fragment; fixed Coverity warnings
|
||||
|
||||
14 August 2019 Vladimir Ivanchenko (hadr-deex-V10-05-12)
|
||||
- G4ExcitationHandler - added check on upper limit of excitations
|
||||
- G4DeexPrecoParameters - added upper limit 30 MeV on excitation
|
||||
per nucleon
|
||||
|
||||
08 August 2019 Vladimir Ivanchenko (hadr-deex-V10-05-11)
|
||||
- G4ExcitationHandler - fixed initialisation sequence
|
||||
|
||||
23 July 2019 Vladimir Ivanchenko (hadr-deex-V10-05-10)
|
||||
- G4ExcitationHandler, G4Evaporation - optimise initialisation reducing
|
||||
memory churn
|
||||
- G4VEvaporationChannel, G4VEmissionProbability, G4EvaporationChannel,
|
||||
G4EvaporationProbability - clean-up private and protected members and
|
||||
methods
|
||||
- G4AlphaEvaporationChannel, G4AlphaEvaporationProbability,
|
||||
G4DeuteronEvaporationChannel, G4DeuteronEvaporationProbability,
|
||||
G4He3EvaporationChannel, G4He3EvaporationProbability,
|
||||
G4NeutronEvaporationChannel, G4NeutronEvaporationProbability,
|
||||
G4ProtonEvaporationChannel, G4ProtonEvaporationProbability,
|
||||
G4TritonEvaporationChannel, G4TritonEvaporationProbability - clean-up
|
||||
- G4GEMChannelVI, G4GEMProbabilityVI - new GEM model
|
||||
|
||||
|
||||
17 July 2019 Vladimir Ivanchenko (hadr-deex-V10-05-09)
|
||||
- G4VEvaporationChannel, G4VEmissionProbability, G4VEvaporationFactory,
|
||||
G4EvaporationGEMFactory, G4EvaporationGEMFactoryVI, G4GEMChannelVI,
|
||||
G4EvaporationDefaultGEMFactory, G4EvaporationFactory,
|
||||
G4EvaporationChannel, G4EvaporationProbability,
|
||||
G4EvaporationProbabilityVI - a modification of internal interfaces
|
||||
allowing reuse code established for evaporation in the new GEM
|
||||
evaporation model, use more C++11 patterns
|
||||
- G4FermiFragmentsPoolVI, G4NuclearLevelData - reduce number of locks
|
||||
at initialisation, use more C++11 patterns
|
||||
|
||||
10 July 2019 Vladimir Ivanchenko (hadr-deex-V10-05-08)
|
||||
- G4EvaporationChannel, G4EvaporationProbability,
|
||||
G4NeutronEvaporationProbability, G4VEmissionProbability,
|
||||
G4VEvaporationChannel - preparation for development of new GEM model,
|
||||
for evaporation improved selection of final excitation level for
|
||||
residual fragment
|
||||
- G4LevelReader - attempt to reduce memory churn at initialisation
|
||||
|
||||
04 June 2019 Vladimir Ivanchenko (hadr-deex-V10-05-07)
|
||||
- G4ExcitationHandler - removed debug cout
|
||||
|
||||
|
||||
+6
-12
@@ -23,8 +23,6 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
// Hadronic Process: Nuclear De-excitations
|
||||
// by V. Lara (Nov. 1999)
|
||||
//
|
||||
@@ -34,29 +32,25 @@
|
||||
#define G4AlphaEvaporationChannel_h 1
|
||||
|
||||
#include "G4EvaporationChannel.hh"
|
||||
#include "G4AlphaCoulombBarrier.hh"
|
||||
#include "G4AlphaEvaporationProbability.hh"
|
||||
|
||||
class G4AlphaEvaporationChannel : public G4EvaporationChannel
|
||||
{
|
||||
public:
|
||||
// only available constructor
|
||||
G4AlphaEvaporationChannel();
|
||||
explicit G4AlphaEvaporationChannel();
|
||||
|
||||
// destructor
|
||||
virtual ~G4AlphaEvaporationChannel();
|
||||
~G4AlphaEvaporationChannel() override;
|
||||
|
||||
private:
|
||||
const G4AlphaEvaporationChannel & operator=(const G4AlphaEvaporationChannel & right);
|
||||
|
||||
const G4AlphaEvaporationChannel & operator=
|
||||
(const G4AlphaEvaporationChannel & right);
|
||||
G4AlphaEvaporationChannel(const G4AlphaEvaporationChannel & right);
|
||||
|
||||
G4bool operator==(const G4AlphaEvaporationChannel & right) const;
|
||||
G4bool operator!=(const G4AlphaEvaporationChannel & right) const;
|
||||
|
||||
G4AlphaCoulombBarrier theCoulombBarrier;
|
||||
|
||||
G4AlphaEvaporationProbability theEvaporationProbability;
|
||||
|
||||
G4AlphaEvaporationProbability pr;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
+6
-10
@@ -37,33 +37,29 @@
|
||||
|
||||
|
||||
#include "G4EvaporationProbability.hh"
|
||||
#include "G4AlphaCoulombBarrier.hh"
|
||||
|
||||
class G4AlphaEvaporationProbability : public G4EvaporationProbability
|
||||
{
|
||||
public:
|
||||
|
||||
G4AlphaEvaporationProbability();
|
||||
explicit G4AlphaEvaporationProbability();
|
||||
|
||||
virtual ~G4AlphaEvaporationProbability();
|
||||
~G4AlphaEvaporationProbability() override;
|
||||
|
||||
protected:
|
||||
|
||||
virtual G4double CalcAlphaParam(const G4Fragment & fragment);
|
||||
G4double CalcAlphaParam(const G4Fragment & fragment) override;
|
||||
|
||||
virtual G4double CalcBetaParam(const G4Fragment & fragment);
|
||||
G4double CalcBetaParam(const G4Fragment & fragment) override;
|
||||
|
||||
private:
|
||||
|
||||
G4AlphaEvaporationProbability(const G4AlphaEvaporationProbability &right);
|
||||
|
||||
const G4AlphaEvaporationProbability & operator=(const G4AlphaEvaporationProbability &right);
|
||||
const G4AlphaEvaporationProbability & operator=
|
||||
(const G4AlphaEvaporationProbability &right);
|
||||
G4bool operator==(const G4AlphaEvaporationProbability &right) const;
|
||||
G4bool operator!=(const G4AlphaEvaporationProbability &right) const;
|
||||
|
||||
G4AlphaCoulombBarrier theCoulombBarrier;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
+5
-11
@@ -23,8 +23,6 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
// Hadronic Process: Nuclear De-excitations
|
||||
// by V. Lara (Nov. 1999)
|
||||
//
|
||||
@@ -34,29 +32,25 @@
|
||||
#define G4DeuteronEvaporationChannel_h 1
|
||||
|
||||
#include "G4EvaporationChannel.hh"
|
||||
#include "G4DeuteronCoulombBarrier.hh"
|
||||
#include "G4DeuteronEvaporationProbability.hh"
|
||||
|
||||
class G4DeuteronEvaporationChannel : public G4EvaporationChannel
|
||||
{
|
||||
public:
|
||||
// only available constructor
|
||||
G4DeuteronEvaporationChannel();
|
||||
explicit G4DeuteronEvaporationChannel();
|
||||
|
||||
// destructor
|
||||
virtual ~G4DeuteronEvaporationChannel();
|
||||
~G4DeuteronEvaporationChannel() override;
|
||||
|
||||
private:
|
||||
const G4DeuteronEvaporationChannel & operator=(const G4DeuteronEvaporationChannel & right);
|
||||
|
||||
const G4DeuteronEvaporationChannel & operator=
|
||||
(const G4DeuteronEvaporationChannel & right);
|
||||
G4DeuteronEvaporationChannel(const G4DeuteronEvaporationChannel & right);
|
||||
|
||||
G4bool operator==(const G4DeuteronEvaporationChannel & right) const;
|
||||
G4bool operator!=(const G4DeuteronEvaporationChannel & right) const;
|
||||
|
||||
G4DeuteronCoulombBarrier theCoulombBarrier;
|
||||
|
||||
G4DeuteronEvaporationProbability theEvaporationProbability;
|
||||
G4DeuteronEvaporationProbability pr;
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
+6
-10
@@ -23,7 +23,6 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// J.M. Quesada (August2008). Based on:
|
||||
//
|
||||
// Hadronic Process: Nuclear De-excitations
|
||||
@@ -44,28 +43,25 @@ class G4DeuteronEvaporationProbability : public G4EvaporationProbability
|
||||
{
|
||||
public:
|
||||
|
||||
G4DeuteronEvaporationProbability();
|
||||
explicit G4DeuteronEvaporationProbability();
|
||||
|
||||
virtual ~G4DeuteronEvaporationProbability();
|
||||
~G4DeuteronEvaporationProbability() override;
|
||||
|
||||
protected:
|
||||
|
||||
virtual G4double CalcAlphaParam(const G4Fragment & fragment);
|
||||
G4double CalcAlphaParam(const G4Fragment & fragment) override;
|
||||
|
||||
virtual G4double CalcBetaParam(const G4Fragment & fragment);
|
||||
G4double CalcBetaParam(const G4Fragment & fragment) override;
|
||||
|
||||
private:
|
||||
|
||||
G4DeuteronEvaporationProbability(const G4DeuteronEvaporationProbability &right);
|
||||
|
||||
const G4DeuteronEvaporationProbability & operator=(const G4DeuteronEvaporationProbability &right);
|
||||
const G4DeuteronEvaporationProbability & operator=
|
||||
(const G4DeuteronEvaporationProbability &right);
|
||||
G4bool operator==(const G4DeuteronEvaporationProbability &right) const;
|
||||
G4bool operator!=(const G4DeuteronEvaporationProbability &right) const;
|
||||
|
||||
G4DeuteronCoulombBarrier theCoulombBarrier;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -56,6 +56,7 @@ class G4NistManager;
|
||||
class G4IonTable;
|
||||
class G4VFermiBreakUp;
|
||||
class G4UnstableFragmentBreakUp;
|
||||
class G4NuclearLevelData;
|
||||
|
||||
class G4Evaporation : public G4VEvaporation
|
||||
{
|
||||
@@ -74,22 +75,24 @@ public:
|
||||
|
||||
void SetDefaultChannel();
|
||||
void SetGEMChannel();
|
||||
void SetGEMVIChannel();
|
||||
void SetCombinedChannel();
|
||||
|
||||
private:
|
||||
|
||||
void InitialiseChannelFactory();
|
||||
|
||||
G4Evaporation(const G4Evaporation &right) = delete;
|
||||
const G4Evaporation & operator=(const G4Evaporation &right) = delete;
|
||||
G4bool operator==(const G4Evaporation &right) const = delete;
|
||||
G4bool operator!=(const G4Evaporation &right) const = delete;
|
||||
G4Evaporation(const G4Evaporation &right);
|
||||
const G4Evaporation & operator=(const G4Evaporation &right);
|
||||
G4bool operator==(const G4Evaporation &right) const;
|
||||
G4bool operator!=(const G4Evaporation &right) const;
|
||||
|
||||
G4int fVerbose;
|
||||
size_t nChannels;
|
||||
G4double minExcitation;
|
||||
G4NistManager* nist;
|
||||
G4IonTable* theTableOfIons;
|
||||
G4NuclearLevelData* fLevelData;
|
||||
G4UnstableFragmentBreakUp* unstableBreakUp;
|
||||
G4bool isInitialised;
|
||||
|
||||
|
||||
+23
-47
@@ -23,8 +23,6 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
//J.M. Quesada (August2008). Based on:
|
||||
//
|
||||
// Hadronic Process: Nuclear De-excitations
|
||||
@@ -33,81 +31,59 @@
|
||||
// 17-11-2010 V.Ivanchenko in constructor replace G4VEmissionProbability by
|
||||
// G4EvaporationProbability and do not new and delete probability
|
||||
// object at each call; use G4Pow
|
||||
// 16-07-2019 V.Ivanchenko use C++11
|
||||
|
||||
#ifndef G4EvaporationChannel_h
|
||||
#define G4EvaporationChannel_h 1
|
||||
|
||||
#include "G4VEvaporationChannel.hh"
|
||||
#include "G4EvaporationProbability.hh"
|
||||
#include "G4VCoulombBarrier.hh"
|
||||
|
||||
class G4PairingCorrection;
|
||||
class G4EvaporationProbability;
|
||||
class G4CoulombBarrier;
|
||||
class G4NuclearLevelData;
|
||||
|
||||
class G4EvaporationChannel : public G4VEvaporationChannel
|
||||
{
|
||||
public:
|
||||
|
||||
explicit G4EvaporationChannel(G4int A, G4int Z,
|
||||
const G4String & aName,
|
||||
G4EvaporationProbability*,
|
||||
G4VCoulombBarrier*);
|
||||
G4EvaporationProbability*);
|
||||
|
||||
virtual ~G4EvaporationChannel();
|
||||
~G4EvaporationChannel() override;
|
||||
|
||||
void Initialise();
|
||||
void Initialise() override;
|
||||
|
||||
virtual G4double GetEmissionProbability(G4Fragment* fragment);
|
||||
G4double GetEmissionProbability(G4Fragment* fragment) override;
|
||||
|
||||
virtual G4Fragment* EmittedFragment(G4Fragment* theNucleus);
|
||||
G4Fragment* EmittedFragment(G4Fragment* theNucleus) override;
|
||||
|
||||
private:
|
||||
|
||||
G4EvaporationChannel(const G4EvaporationChannel & right) = delete;
|
||||
const G4EvaporationChannel & operator=
|
||||
(const G4EvaporationChannel & right) = delete;
|
||||
G4bool operator==(const G4EvaporationChannel & right) const = delete;
|
||||
G4bool operator!=(const G4EvaporationChannel & right) const = delete;
|
||||
|
||||
private:
|
||||
G4EvaporationChannel(const G4EvaporationChannel & right);
|
||||
const G4EvaporationChannel & operator=(const G4EvaporationChannel & right);
|
||||
G4bool operator==(const G4EvaporationChannel & right) const;
|
||||
G4bool operator!=(const G4EvaporationChannel & right) const;
|
||||
|
||||
// This data member define the channel.
|
||||
// They are intializated at object creation (constructor) time.
|
||||
|
||||
G4int theA;
|
||||
G4int theZ;
|
||||
G4int resA;
|
||||
G4int resZ;
|
||||
|
||||
G4double EvapMass;
|
||||
G4double CoulombBarrier;
|
||||
G4double mass;
|
||||
G4double resMass;
|
||||
|
||||
G4double evapMass;
|
||||
G4double evapMass2;
|
||||
|
||||
// For evaporation probability calcualation
|
||||
G4EvaporationProbability * theProbability;
|
||||
G4EvaporationProbability* theProbability;
|
||||
|
||||
// For Coulomb Barrier calculation
|
||||
G4VCoulombBarrier * theCoulombBarrier;
|
||||
|
||||
// For pairing correction calculation
|
||||
G4PairingCorrection* pairingCorrection;
|
||||
|
||||
//---------------------------------------------------
|
||||
|
||||
// These values depend on the nucleus that is being evaporated.
|
||||
// They are calculated through the Initialize method which
|
||||
// takes as parameters
|
||||
// the atomic number, charge and excitation energy of nucleus.
|
||||
|
||||
G4int ResA;
|
||||
G4int ResZ;
|
||||
|
||||
G4double Mass;
|
||||
|
||||
// Emission Probability
|
||||
G4double EmissionProbability;
|
||||
|
||||
// Kinetic Energy that can be carried by fragment
|
||||
G4double MinKinEnergy;
|
||||
G4double MaxKinEnergy;
|
||||
G4CoulombBarrier* theCoulombBarrier;
|
||||
|
||||
G4NuclearLevelData* theLevelData;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
+31
-38
@@ -29,82 +29,75 @@
|
||||
// Hadronic Process: Nuclear De-excitations
|
||||
// by V. Lara (Oct 1998)
|
||||
//
|
||||
// V.Ivanchenko general clean-up since 2010
|
||||
//
|
||||
#ifndef G4EvaporationProbability_h
|
||||
#define G4EvaporationProbability_h 1
|
||||
|
||||
#include "G4VEmissionProbability.hh"
|
||||
|
||||
class G4VCoulombBarrier;
|
||||
class G4NuclearLevelData;
|
||||
|
||||
class G4EvaporationProbability : public G4VEmissionProbability
|
||||
{
|
||||
public:
|
||||
|
||||
explicit G4EvaporationProbability(G4int anA, G4int aZ,
|
||||
G4double aGamma,
|
||||
G4VCoulombBarrier *);
|
||||
G4double aGamma);
|
||||
|
||||
virtual ~G4EvaporationProbability();
|
||||
|
||||
// not used for evaporation
|
||||
virtual G4double EmissionProbability(const G4Fragment& fragment,
|
||||
G4double maxKineticEnergy);
|
||||
~G4EvaporationProbability() override;
|
||||
|
||||
// general method used for evaporation
|
||||
G4double TotalProbability(const G4Fragment& fragment,
|
||||
G4double minKineticEnergy,
|
||||
G4double maxKineticEnergy,
|
||||
G4double CoulombBarrier = 0.0);
|
||||
|
||||
virtual G4double TotalProbability(const G4Fragment& fragment,
|
||||
G4double minKinEnergy,
|
||||
G4double maxKinEnergy,
|
||||
G4double CB, G4double exEnergy);
|
||||
/*
|
||||
virtual G4double TotalProbability(const G4Fragment& fragment,
|
||||
G4double minKinEnergy,
|
||||
G4double maxKinEnergy,
|
||||
G4double CB);
|
||||
*/
|
||||
// main method to compute full probability for OPTx > 2
|
||||
virtual G4double ComputeProbability(G4double K, G4double kBarrier);
|
||||
G4double ComputeProbability(G4double K, G4double CB) override;
|
||||
|
||||
// Samples fragment kinetic energy and excitation energy
|
||||
// of the residual nucleaus
|
||||
G4double SampleKineticEnergy(G4double minKineticEnergy,
|
||||
G4double maxKineticEnergy,
|
||||
G4double CoulombBarrier = 0.0);
|
||||
G4double SampleKineticEnergy(G4double minKinEnergy,
|
||||
G4double maxKinEnergy,
|
||||
G4double CB);
|
||||
|
||||
protected:
|
||||
|
||||
virtual G4double CalcAlphaParam(const G4Fragment & fragment)=0 ;
|
||||
virtual G4double CalcAlphaParam(const G4Fragment& fragment);
|
||||
|
||||
virtual G4double CalcBetaParam(const G4Fragment & fragment)=0 ;
|
||||
virtual G4double CalcBetaParam(const G4Fragment& fragment);
|
||||
|
||||
private:
|
||||
|
||||
G4double CrossSection(G4double K, G4double CoulombBarrier);
|
||||
G4double CrossSection(G4double K, G4double CB);
|
||||
|
||||
// Copy constructor
|
||||
G4EvaporationProbability(const G4EvaporationProbability &right) = delete;
|
||||
|
||||
G4EvaporationProbability(const G4EvaporationProbability &right);
|
||||
const G4EvaporationProbability & operator=
|
||||
(const G4EvaporationProbability &right) = delete;
|
||||
G4bool operator==(const G4EvaporationProbability &right) const = delete;
|
||||
G4bool operator!=(const G4EvaporationProbability &right) const = delete;
|
||||
(const G4EvaporationProbability &right);
|
||||
G4bool operator==(const G4EvaporationProbability &right) const;
|
||||
G4bool operator!=(const G4EvaporationProbability &right) const;
|
||||
|
||||
G4NuclearLevelData* fLevelData;
|
||||
|
||||
G4int fragA;
|
||||
G4int fragZ;
|
||||
G4int resA;
|
||||
G4int resZ;
|
||||
//G4int fragA;
|
||||
//G4int fragZ;
|
||||
G4int index;
|
||||
|
||||
G4double resA13;
|
||||
G4double muu;
|
||||
G4double partMass;
|
||||
G4double resMass;
|
||||
G4double Mass;
|
||||
G4double U, delta0, delta1, a0;
|
||||
G4double freeU;
|
||||
G4double a0;
|
||||
G4double delta1;
|
||||
|
||||
// Gamma is A_f(2S_f+1) factor, where A_f is fragment atomic
|
||||
// number and S_f is fragment spin
|
||||
G4double Gamma;
|
||||
G4double fGamma;
|
||||
G4double pcoeff;
|
||||
|
||||
G4double probmax;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
+7
-12
@@ -24,40 +24,35 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
// Hadronic Process: Nuclear De-excitations
|
||||
// by V. Lara (Nov. 1999)
|
||||
//
|
||||
// 17-11-2010 V.Ivanchenko moved constructor and destructor to source and cleanup
|
||||
// 17-11-2010 V.Ivanchenko cleanup
|
||||
|
||||
#ifndef G4He3EvaporationChannel_h
|
||||
#define G4He3EvaporationChannel_h 1
|
||||
|
||||
#include "G4EvaporationChannel.hh"
|
||||
#include "G4He3CoulombBarrier.hh"
|
||||
#include "G4He3EvaporationProbability.hh"
|
||||
|
||||
class G4He3EvaporationChannel : public G4EvaporationChannel
|
||||
{
|
||||
public:
|
||||
// only available constructor
|
||||
G4He3EvaporationChannel();
|
||||
explicit G4He3EvaporationChannel();
|
||||
|
||||
// destructor
|
||||
virtual ~G4He3EvaporationChannel();
|
||||
~G4He3EvaporationChannel() override;
|
||||
|
||||
private:
|
||||
|
||||
const G4He3EvaporationChannel & operator=(const G4He3EvaporationChannel & right);
|
||||
|
||||
const G4He3EvaporationChannel & operator=
|
||||
(const G4He3EvaporationChannel & right);
|
||||
G4He3EvaporationChannel(const G4He3EvaporationChannel & right);
|
||||
|
||||
G4bool operator==(const G4He3EvaporationChannel & right) const;
|
||||
G4bool operator!=(const G4He3EvaporationChannel & right) const;
|
||||
|
||||
G4He3CoulombBarrier theCoulombBarrier;
|
||||
|
||||
G4He3EvaporationProbability theEvaporationProbability;
|
||||
|
||||
G4He3EvaporationProbability pr;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
+6
-10
@@ -35,33 +35,29 @@
|
||||
#ifndef G4He3EvaporationProbability_h
|
||||
#define G4He3EvaporationProbability_h 1
|
||||
|
||||
|
||||
#include "G4EvaporationProbability.hh"
|
||||
#include "G4He3CoulombBarrier.hh"
|
||||
|
||||
class G4He3EvaporationProbability : public G4EvaporationProbability
|
||||
{
|
||||
public:
|
||||
|
||||
G4He3EvaporationProbability();
|
||||
explicit G4He3EvaporationProbability();
|
||||
|
||||
virtual ~G4He3EvaporationProbability();
|
||||
~G4He3EvaporationProbability() override;
|
||||
|
||||
protected:
|
||||
|
||||
virtual G4double CalcAlphaParam(const G4Fragment & fragment);
|
||||
G4double CalcAlphaParam(const G4Fragment & fragment) override;
|
||||
|
||||
virtual G4double CalcBetaParam(const G4Fragment & fragment);
|
||||
G4double CalcBetaParam(const G4Fragment & fragment) override;
|
||||
|
||||
private:
|
||||
|
||||
G4He3EvaporationProbability(const G4He3EvaporationProbability &right);
|
||||
|
||||
const G4He3EvaporationProbability & operator=(const G4He3EvaporationProbability &right);
|
||||
const G4He3EvaporationProbability & operator=
|
||||
(const G4He3EvaporationProbability &right);
|
||||
G4bool operator==(const G4He3EvaporationProbability &right) const;
|
||||
G4bool operator!=(const G4He3EvaporationProbability &right) const;
|
||||
|
||||
G4He3CoulombBarrier theCoulombBarrier;
|
||||
};
|
||||
|
||||
|
||||
|
||||
+5
-10
@@ -24,7 +24,6 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
// Hadronic Process: Nuclear De-excitations
|
||||
// by V. Lara (Nov. 1999)
|
||||
//
|
||||
@@ -34,30 +33,26 @@
|
||||
#define G4NeutronEvaporationChannel_h 1
|
||||
|
||||
#include "G4EvaporationChannel.hh"
|
||||
#include "G4NeutronCoulombBarrier.hh"
|
||||
#include "G4NeutronEvaporationProbability.hh"
|
||||
|
||||
class G4NeutronEvaporationChannel : public G4EvaporationChannel
|
||||
{
|
||||
public:
|
||||
// only available constructor
|
||||
G4NeutronEvaporationChannel();
|
||||
explicit G4NeutronEvaporationChannel();
|
||||
|
||||
// destructor
|
||||
virtual ~G4NeutronEvaporationChannel();
|
||||
~G4NeutronEvaporationChannel() override;
|
||||
|
||||
private:
|
||||
|
||||
const G4NeutronEvaporationChannel & operator=(const G4NeutronEvaporationChannel & right);
|
||||
|
||||
const G4NeutronEvaporationChannel & operator=
|
||||
(const G4NeutronEvaporationChannel & right);
|
||||
G4NeutronEvaporationChannel(const G4NeutronEvaporationChannel & right);
|
||||
|
||||
G4bool operator==(const G4NeutronEvaporationChannel & right) const;
|
||||
G4bool operator!=(const G4NeutronEvaporationChannel & right) const;
|
||||
|
||||
G4NeutronCoulombBarrier theCoulombBarrier;
|
||||
|
||||
G4NeutronEvaporationProbability theEvaporationProbability;
|
||||
G4NeutronEvaporationProbability pr;
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
+6
-9
@@ -38,31 +38,28 @@
|
||||
|
||||
|
||||
#include "G4EvaporationProbability.hh"
|
||||
#include "G4NeutronCoulombBarrier.hh"
|
||||
|
||||
class G4NeutronEvaporationProbability : public G4EvaporationProbability
|
||||
{
|
||||
public:
|
||||
|
||||
G4NeutronEvaporationProbability();
|
||||
explicit G4NeutronEvaporationProbability();
|
||||
|
||||
virtual ~G4NeutronEvaporationProbability();
|
||||
~G4NeutronEvaporationProbability() override;
|
||||
|
||||
protected:
|
||||
|
||||
virtual G4double CalcAlphaParam(const G4Fragment & fragment);
|
||||
G4double CalcAlphaParam(const G4Fragment & fragment) override;
|
||||
|
||||
virtual G4double CalcBetaParam(const G4Fragment & fragment);
|
||||
G4double CalcBetaParam(const G4Fragment & fragment) override;
|
||||
|
||||
private:
|
||||
|
||||
G4NeutronEvaporationProbability(const G4NeutronEvaporationProbability &right);
|
||||
|
||||
const G4NeutronEvaporationProbability & operator=(const G4NeutronEvaporationProbability &right);
|
||||
const G4NeutronEvaporationProbability & operator=
|
||||
(const G4NeutronEvaporationProbability &right);
|
||||
G4bool operator==(const G4NeutronEvaporationProbability &right) const;
|
||||
G4bool operator!=(const G4NeutronEvaporationProbability &right) const;
|
||||
|
||||
G4NeutronCoulombBarrier theCoulombBarrier;
|
||||
};
|
||||
|
||||
|
||||
|
||||
+6
-12
@@ -24,7 +24,6 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
// Hadronic Process: Nuclear De-excitations
|
||||
// by V. Lara (Nov. 1999)
|
||||
//
|
||||
@@ -34,31 +33,26 @@
|
||||
#define G4ProtonEvaporationChannel_h 1
|
||||
|
||||
#include "G4EvaporationChannel.hh"
|
||||
#include "G4ProtonCoulombBarrier.hh"
|
||||
#include "G4ProtonEvaporationProbability.hh"
|
||||
|
||||
class G4ProtonEvaporationChannel : public G4EvaporationChannel
|
||||
{
|
||||
public:
|
||||
// only available constructor
|
||||
G4ProtonEvaporationChannel();
|
||||
explicit G4ProtonEvaporationChannel();
|
||||
|
||||
// destructor
|
||||
virtual ~G4ProtonEvaporationChannel();
|
||||
~G4ProtonEvaporationChannel() override;
|
||||
|
||||
private:
|
||||
|
||||
const G4ProtonEvaporationChannel & operator=(const G4ProtonEvaporationChannel & right);
|
||||
|
||||
const G4ProtonEvaporationChannel & operator=
|
||||
(const G4ProtonEvaporationChannel & right);
|
||||
G4ProtonEvaporationChannel(const G4ProtonEvaporationChannel & right);
|
||||
|
||||
G4bool operator==(const G4ProtonEvaporationChannel & right) const;
|
||||
G4bool operator!=(const G4ProtonEvaporationChannel & right) const;
|
||||
|
||||
G4ProtonCoulombBarrier theCoulombBarrier;
|
||||
|
||||
G4ProtonEvaporationProbability theEvaporationProbability;
|
||||
|
||||
|
||||
G4ProtonEvaporationProbability pr;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
+6
-10
@@ -37,33 +37,29 @@
|
||||
#define G4ProtonEvaporationProbability_h 1
|
||||
|
||||
#include "G4EvaporationProbability.hh"
|
||||
#include "G4ProtonCoulombBarrier.hh"
|
||||
|
||||
class G4ProtonEvaporationProbability : public G4EvaporationProbability
|
||||
{
|
||||
public:
|
||||
|
||||
G4ProtonEvaporationProbability();
|
||||
explicit G4ProtonEvaporationProbability();
|
||||
|
||||
virtual ~G4ProtonEvaporationProbability();
|
||||
~G4ProtonEvaporationProbability() override;
|
||||
|
||||
protected:
|
||||
|
||||
virtual G4double CalcAlphaParam(const G4Fragment & fragment);
|
||||
G4double CalcAlphaParam(const G4Fragment & fragment) override;
|
||||
|
||||
virtual G4double CalcBetaParam(const G4Fragment & fragment);
|
||||
G4double CalcBetaParam(const G4Fragment & fragment) override;
|
||||
|
||||
private:
|
||||
|
||||
G4ProtonEvaporationProbability(const G4ProtonEvaporationProbability &right);
|
||||
|
||||
const G4ProtonEvaporationProbability & operator=(const G4ProtonEvaporationProbability &right);
|
||||
const G4ProtonEvaporationProbability & operator=
|
||||
(const G4ProtonEvaporationProbability &right);
|
||||
G4bool operator==(const G4ProtonEvaporationProbability &right) const;
|
||||
G4bool operator!=(const G4ProtonEvaporationProbability &right) const;
|
||||
|
||||
G4ProtonCoulombBarrier theCoulombBarrier;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
+7
-10
@@ -28,7 +28,7 @@
|
||||
// Hadronic Process: Nuclear De-excitations
|
||||
// by V. Lara (Nov. 1999)
|
||||
//
|
||||
// 17-11-2010 V.Ivanchenko moved constructor and destructor to source and cleanup
|
||||
// 17-11-2010 V.Ivanchenko cleanup
|
||||
|
||||
#ifndef G4TritonEvaporationChannel_h
|
||||
#define G4TritonEvaporationChannel_h 1
|
||||
@@ -41,22 +41,19 @@ class G4TritonEvaporationChannel : public G4EvaporationChannel
|
||||
{
|
||||
public:
|
||||
// only available constructor
|
||||
G4TritonEvaporationChannel();
|
||||
explicit G4TritonEvaporationChannel();
|
||||
|
||||
// destructor
|
||||
virtual ~G4TritonEvaporationChannel();
|
||||
~G4TritonEvaporationChannel() override;
|
||||
|
||||
private:
|
||||
const G4TritonEvaporationChannel & operator=(const G4TritonEvaporationChannel & right);
|
||||
|
||||
const G4TritonEvaporationChannel & operator=
|
||||
(const G4TritonEvaporationChannel & right);
|
||||
G4TritonEvaporationChannel(const G4TritonEvaporationChannel & right);
|
||||
|
||||
G4bool operator==(const G4TritonEvaporationChannel & right) const;
|
||||
G4bool operator!=(const G4TritonEvaporationChannel & right) const;
|
||||
|
||||
G4TritonCoulombBarrier theCoulombBarrier;
|
||||
|
||||
G4TritonEvaporationProbability theEvaporationProbability;
|
||||
|
||||
G4TritonEvaporationProbability pr;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
-1
@@ -62,7 +62,6 @@ private:
|
||||
G4bool operator==(const G4TritonEvaporationProbability &right) const;
|
||||
G4bool operator!=(const G4TritonEvaporationProbability &right) const;
|
||||
|
||||
G4TritonCoulombBarrier theCoulombBarrier;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
+7
-4
@@ -66,19 +66,22 @@ public:
|
||||
|
||||
virtual G4double GetEmissionProbability(G4Fragment* fragment) final;
|
||||
|
||||
inline void SetVerbose(G4int val) { fVerbose = val; }
|
||||
|
||||
private:
|
||||
|
||||
G4UnstableFragmentBreakUp(const G4UnstableFragmentBreakUp & right) = delete;
|
||||
G4UnstableFragmentBreakUp(const G4UnstableFragmentBreakUp & right);
|
||||
const G4UnstableFragmentBreakUp & operator =
|
||||
(const G4UnstableFragmentBreakUp & right) = delete;
|
||||
G4bool operator == (const G4UnstableFragmentBreakUp & right) const = delete;
|
||||
G4bool operator != (const G4UnstableFragmentBreakUp & right) const = delete;
|
||||
(const G4UnstableFragmentBreakUp & right);
|
||||
G4bool operator == (const G4UnstableFragmentBreakUp & right) const;
|
||||
G4bool operator != (const G4UnstableFragmentBreakUp & right) const;
|
||||
|
||||
static const G4int Zfr[6];
|
||||
static const G4int Afr[6];
|
||||
G4double masses[6];
|
||||
|
||||
G4NuclearLevelData* fLevelData;
|
||||
G4int fVerbose;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
+1
-3
@@ -23,8 +23,6 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
// Hadronic Process: Nuclear De-excitations
|
||||
// by V. Lara (Nov. 1999)
|
||||
//
|
||||
@@ -33,7 +31,7 @@
|
||||
#include "G4AlphaEvaporationChannel.hh"
|
||||
|
||||
G4AlphaEvaporationChannel::G4AlphaEvaporationChannel()
|
||||
: G4EvaporationChannel(4,2,"alpha",&theEvaporationProbability,&theCoulombBarrier)
|
||||
: G4EvaporationChannel(4,2,&pr)
|
||||
{}
|
||||
|
||||
G4AlphaEvaporationChannel::~G4AlphaEvaporationChannel()
|
||||
|
||||
+1
-2
@@ -34,10 +34,9 @@
|
||||
// 17-11-2010 V.Ivanchenko integer Z and A
|
||||
|
||||
#include "G4AlphaEvaporationProbability.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
|
||||
G4AlphaEvaporationProbability::G4AlphaEvaporationProbability() :
|
||||
G4EvaporationProbability(4,2,1.0,&theCoulombBarrier)
|
||||
G4EvaporationProbability(4,2,1.0)
|
||||
{}
|
||||
|
||||
G4AlphaEvaporationProbability::~G4AlphaEvaporationProbability()
|
||||
|
||||
+1
-2
@@ -24,7 +24,6 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
// Hadronic Process: Nuclear De-excitations
|
||||
// by V. Lara (Nov. 1999)
|
||||
//
|
||||
@@ -33,7 +32,7 @@
|
||||
#include "G4DeuteronEvaporationChannel.hh"
|
||||
|
||||
G4DeuteronEvaporationChannel::G4DeuteronEvaporationChannel()
|
||||
: G4EvaporationChannel(2,1,"deuteron",&theEvaporationProbability,&theCoulombBarrier)
|
||||
: G4EvaporationChannel(2,1,&pr)
|
||||
{}
|
||||
|
||||
G4DeuteronEvaporationChannel::~G4DeuteronEvaporationChannel()
|
||||
|
||||
+1
-2
@@ -23,7 +23,6 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// J.M. Quesada (August2008). Based on:
|
||||
//
|
||||
// Hadronic Process: Nuclear De-excitations
|
||||
@@ -37,7 +36,7 @@
|
||||
#include "G4DeuteronEvaporationProbability.hh"
|
||||
|
||||
G4DeuteronEvaporationProbability::G4DeuteronEvaporationProbability() :
|
||||
G4EvaporationProbability(2,1,3.0,&theCoulombBarrier)
|
||||
G4EvaporationProbability(2,1,3.0)
|
||||
{}
|
||||
|
||||
G4DeuteronEvaporationProbability::~G4DeuteronEvaporationProbability()
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
// Hadronic Process: Nuclear De-excitations
|
||||
// by V. Lara (Oct 1998)
|
||||
//
|
||||
@@ -51,6 +50,7 @@
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4EvaporationFactory.hh"
|
||||
#include "G4EvaporationGEMFactory.hh"
|
||||
#include "G4EvaporationGEMFactoryVI.hh"
|
||||
#include "G4EvaporationDefaultGEMFactory.hh"
|
||||
#include "G4NistManager.hh"
|
||||
#include "G4VFermiBreakUp.hh"
|
||||
@@ -59,23 +59,29 @@
|
||||
#include "G4ParticleTable.hh"
|
||||
#include "G4IonTable.hh"
|
||||
#include "G4NuclearLevelData.hh"
|
||||
#include "G4LevelManager.hh"
|
||||
#include "G4UnstableFragmentBreakUp.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
G4Evaporation::G4Evaporation(G4VEvaporationChannel* photoEvaporation)
|
||||
: G4VEvaporation(),fVerbose(1),nChannels(0),minExcitation(0.1*keV),
|
||||
: G4VEvaporation(),fVerbose(0),nChannels(0),minExcitation(0.1*keV),
|
||||
isInitialised(false)
|
||||
{
|
||||
if(photoEvaporation) { SetPhotonEvaporation(photoEvaporation); }
|
||||
else { SetPhotonEvaporation(new G4PhotonEvaporation()); }
|
||||
|
||||
channelType = fEvaporation;
|
||||
theChannelFactory = new G4EvaporationFactory(thePhotonEvaporation);
|
||||
InitialiseChannelFactory();
|
||||
channelType = fDummy;
|
||||
theChannelFactory = nullptr;
|
||||
|
||||
fLevelData = G4NuclearLevelData::GetInstance();
|
||||
theTableOfIons = G4ParticleTable::GetParticleTable()->GetIonTable();
|
||||
nist = G4NistManager::Instance();
|
||||
unstableBreakUp = new G4UnstableFragmentBreakUp();
|
||||
/*
|
||||
G4cout << "G4Evaporation() " << this << " thePhotonEvaporation: "
|
||||
<< photoEvaporation << " UnstableFragmentBreakUp: "
|
||||
<< unstableBreakUp << G4endl;
|
||||
*/
|
||||
}
|
||||
|
||||
G4Evaporation::~G4Evaporation()
|
||||
@@ -87,14 +93,16 @@ void G4Evaporation::InitialiseChannels()
|
||||
{
|
||||
if(isInitialised) { return; }
|
||||
|
||||
G4DeexPrecoParameters* param =
|
||||
G4NuclearLevelData::GetInstance()->GetParameters();
|
||||
G4DeexPrecoParameters* param = fLevelData->GetParameters();
|
||||
minExcitation = param->GetMinExcitation();
|
||||
fVerbose = param->GetVerbose();
|
||||
unstableBreakUp->SetVerbose(fVerbose);
|
||||
|
||||
G4DeexChannelType type = param->GetDeexChannelsType();
|
||||
if(type == fCombined) { SetCombinedChannel(); }
|
||||
else if(type == fGEM) { SetGEMChannel(); }
|
||||
else if(type == fEvaporation) { SetDefaultChannel(); }
|
||||
else if(type == fGEMVI) { SetGEMVIChannel(); }
|
||||
|
||||
isInitialised = true;
|
||||
}
|
||||
@@ -119,8 +127,10 @@ void G4Evaporation::SetDefaultChannel()
|
||||
{
|
||||
if(fEvaporation != channelType) {
|
||||
channelType = fEvaporation;
|
||||
CleanChannels();
|
||||
delete theChannelFactory;
|
||||
if(theChannelFactory) {
|
||||
CleanChannels();
|
||||
delete theChannelFactory;
|
||||
}
|
||||
theChannelFactory = new G4EvaporationFactory(thePhotonEvaporation);
|
||||
InitialiseChannelFactory();
|
||||
}
|
||||
@@ -130,20 +140,38 @@ void G4Evaporation::SetGEMChannel()
|
||||
{
|
||||
if(fGEM != channelType) {
|
||||
channelType = fCombined;
|
||||
CleanChannels();
|
||||
delete theChannelFactory;
|
||||
if(theChannelFactory) {
|
||||
CleanChannels();
|
||||
delete theChannelFactory;
|
||||
}
|
||||
theChannelFactory = new G4EvaporationGEMFactory(thePhotonEvaporation);
|
||||
InitialiseChannelFactory();
|
||||
}
|
||||
}
|
||||
|
||||
void G4Evaporation::SetGEMVIChannel()
|
||||
{
|
||||
if(fGEMVI != channelType) {
|
||||
channelType = fGEMVI;
|
||||
if(theChannelFactory) {
|
||||
CleanChannels();
|
||||
delete theChannelFactory;
|
||||
}
|
||||
theChannelFactory = new G4EvaporationGEMFactoryVI(thePhotonEvaporation);
|
||||
InitialiseChannelFactory();
|
||||
}
|
||||
}
|
||||
|
||||
void G4Evaporation::SetCombinedChannel()
|
||||
{
|
||||
if(fCombined != channelType) {
|
||||
channelType = fCombined;
|
||||
CleanChannels();
|
||||
delete theChannelFactory;
|
||||
theChannelFactory = new G4EvaporationDefaultGEMFactory(thePhotonEvaporation);
|
||||
if(theChannelFactory) {
|
||||
CleanChannels();
|
||||
delete theChannelFactory;
|
||||
}
|
||||
theChannelFactory =
|
||||
new G4EvaporationDefaultGEMFactory(thePhotonEvaporation);
|
||||
InitialiseChannelFactory();
|
||||
}
|
||||
}
|
||||
@@ -157,6 +185,9 @@ void G4Evaporation::BreakFragment(G4FragmentVector* theResult,
|
||||
size_t maxchannel, i;
|
||||
|
||||
G4int Amax = theResidualNucleus->GetA_asInt();
|
||||
if(fVerbose > 1) {
|
||||
G4cout << "### G4Evaporation::BreakItUp loop" << G4endl;
|
||||
}
|
||||
|
||||
// Starts loop over evaporated particles, loop is limited by number
|
||||
// of nucleons
|
||||
@@ -165,6 +196,7 @@ void G4Evaporation::BreakFragment(G4FragmentVector* theResult,
|
||||
// g,n,p and light fragments - evaporation is finished
|
||||
G4int Z = theResidualNucleus->GetZ_asInt();
|
||||
G4int A = theResidualNucleus->GetA_asInt();
|
||||
if(A <= 1) { break; }
|
||||
G4double Eex = theResidualNucleus->GetExcitationEnergy();
|
||||
|
||||
// stop deecitation loop if residual can be deexcited by FBU
|
||||
@@ -172,26 +204,22 @@ void G4Evaporation::BreakFragment(G4FragmentVector* theResult,
|
||||
|
||||
// check if it is stable, then finish evaporation
|
||||
G4double abun = nist->GetIsotopeAbundance(Z, A);
|
||||
if(fVerbose > 1) {
|
||||
G4cout << "### G4Evaporation::BreakItUp step " << ia << " Z= " << Z
|
||||
<< " A= " << A << " Eex(MeV)= "
|
||||
<< theResidualNucleus->GetExcitationEnergy()
|
||||
<< " aban= " << abun << G4endl;
|
||||
}
|
||||
// stop deecitation loop in the case of a cold stable fragment
|
||||
if(Eex <= minExcitation && abun > 0.0) { break; }
|
||||
if(Eex <= minExcitation &&
|
||||
(abun > 0.0 || (A == 3 && (Z == 1 || Z == 2)))) { break; }
|
||||
|
||||
totprob = 0.0;
|
||||
maxchannel = nChannels;
|
||||
if(fVerbose > 2) {
|
||||
G4cout << "### Evaporation loop #" << ia
|
||||
<< " Fragment: " << theResidualNucleus << G4endl;
|
||||
if(fVerbose > 1) {
|
||||
G4cout << "Evaporation# " << ia << " Z= " << Z << " A= " << A
|
||||
<< " Eex(MeV)= " << theResidualNucleus->GetExcitationEnergy()
|
||||
<< " aban= " << abun << G4endl;
|
||||
}
|
||||
// loop over evaporation channels
|
||||
for(i=0; i<nChannels; ++i) {
|
||||
prob = (*theChannels)[i]->GetEmissionProbability(theResidualNucleus);
|
||||
if(fVerbose > 2 && prob > 0.0) {
|
||||
G4cout << " Channel# " << i << " prob= " << prob << G4endl;
|
||||
G4cout << " Channel# " << i << " prob= " << prob << G4endl;
|
||||
}
|
||||
totprob += prob;
|
||||
probabilities[i] = totprob;
|
||||
@@ -207,10 +235,10 @@ void G4Evaporation::BreakFragment(G4FragmentVector* theResult,
|
||||
}
|
||||
|
||||
// photon evaporation in the case of no other channels available
|
||||
// do evaporation chain and reset total probability
|
||||
// do evaporation chain and return back ground state fragment
|
||||
if(0.0 < totprob && probabilities[0] == totprob) {
|
||||
if(fVerbose > 2) {
|
||||
G4cout << "Start chain of gamma evaporation" << G4endl;
|
||||
if(fVerbose > 1) {
|
||||
G4cout << "$$$ Start chain of gamma evaporation" << G4endl;
|
||||
}
|
||||
(*theChannels)[0]->BreakUpChain(theResult, theResidualNucleus);
|
||||
totprob = 0.0;
|
||||
@@ -219,14 +247,19 @@ void G4Evaporation::BreakFragment(G4FragmentVector* theResult,
|
||||
// stable fragment - evaporation is finished
|
||||
if(0.0 == totprob) {
|
||||
|
||||
// if fragment is exotic, then force its decay
|
||||
if(0.0 == abun) {
|
||||
if(!unstableBreakUp->BreakUpChain(theResult, theResidualNucleus))
|
||||
{ break; }
|
||||
if(fVerbose > 2) { G4cout << "$$$ Decay exotic fragment" << G4endl; }
|
||||
} else {
|
||||
break;
|
||||
// release fragment known to DB
|
||||
if(fLevelData->GetLevelManager(Z, A)) { break; }
|
||||
|
||||
// if fragment is exotic, then it forced to decay
|
||||
// if success, then decay product is added to results
|
||||
if(fVerbose > 1) {
|
||||
G4cout << "$$$ Decay exotic fragment" << G4endl;
|
||||
}
|
||||
if(unstableBreakUp->BreakUpChain(theResult, theResidualNucleus)) {
|
||||
continue;
|
||||
}
|
||||
// release if it is not possible to decay
|
||||
break;
|
||||
}
|
||||
|
||||
// select channel
|
||||
@@ -234,7 +267,7 @@ void G4Evaporation::BreakFragment(G4FragmentVector* theResult,
|
||||
// loop over evaporation channels
|
||||
for(i=0; i<maxchannel; ++i) { if(probabilities[i] >= totprob) { break; } }
|
||||
|
||||
if(fVerbose > 2) { G4cout << "Channel # " << i << G4endl; }
|
||||
if(fVerbose > 1) { G4cout << "$$$ Channel # " << i << G4endl; }
|
||||
G4Fragment* frag = (*theChannels)[i]->EmittedFragment(theResidualNucleus);
|
||||
if(fVerbose > 2 && frag) { G4cout << " " << *frag << G4endl; }
|
||||
|
||||
@@ -242,6 +275,4 @@ void G4Evaporation::BreakFragment(G4FragmentVector* theResult,
|
||||
if(frag) { theResult->push_back(frag); }
|
||||
else { break; }
|
||||
}
|
||||
// loop is stopped, residual fragment is added to the results
|
||||
theResult->push_back(theResidualNucleus);
|
||||
}
|
||||
|
||||
+90
-65
@@ -23,7 +23,6 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//J.M. Quesada (August2008). Based on:
|
||||
//
|
||||
// Hadronic Process: Nuclear De-excitations
|
||||
@@ -38,7 +37,8 @@
|
||||
// object at each call; use G4Pow
|
||||
|
||||
#include "G4EvaporationChannel.hh"
|
||||
#include "G4PairingCorrection.hh"
|
||||
#include "G4EvaporationProbability.hh"
|
||||
#include "G4CoulombBarrier.hh"
|
||||
#include "G4NuclearLevelData.hh"
|
||||
#include "G4NucleiProperties.hh"
|
||||
#include "G4Pow.hh"
|
||||
@@ -51,23 +51,26 @@
|
||||
#include "G4Alpha.hh"
|
||||
|
||||
G4EvaporationChannel::G4EvaporationChannel(G4int anA, G4int aZ,
|
||||
const G4String & aName,
|
||||
G4EvaporationProbability* aprob,
|
||||
G4VCoulombBarrier* barrier):
|
||||
G4VEvaporationChannel(aName),
|
||||
G4EvaporationProbability* aprob):
|
||||
G4VEvaporationChannel(),
|
||||
theA(anA),
|
||||
theZ(aZ),
|
||||
theProbability(aprob),
|
||||
theCoulombBarrier(barrier)
|
||||
theCoulombBarrier(new G4CoulombBarrier(anA, aZ))
|
||||
{
|
||||
ResA = ResZ = 0;
|
||||
Mass = CoulombBarrier = MinKinEnergy = MaxKinEnergy = EmissionProbability = 0.0;
|
||||
EvapMass = G4NucleiProperties::GetNuclearMass(theA, theZ);
|
||||
pairingCorrection = G4NuclearLevelData::GetInstance()->GetPairingCorrection();
|
||||
resA = resZ = 0;
|
||||
mass = resMass = 0.0;
|
||||
evapMass = G4NucleiProperties::GetNuclearMass(theA, theZ);
|
||||
//G4cout << "G4EvaporationChannel: Z= " << theZ << " A= " << theA
|
||||
// << " M(GeV)= " << evapMass/GeV << G4endl;
|
||||
evapMass2 = evapMass*evapMass;
|
||||
theLevelData = G4NuclearLevelData::GetInstance();
|
||||
}
|
||||
|
||||
G4EvaporationChannel::~G4EvaporationChannel()
|
||||
{}
|
||||
{
|
||||
delete theCoulombBarrier;
|
||||
}
|
||||
|
||||
void G4EvaporationChannel::Initialise()
|
||||
{
|
||||
@@ -77,76 +80,98 @@ void G4EvaporationChannel::Initialise()
|
||||
|
||||
G4double G4EvaporationChannel::GetEmissionProbability(G4Fragment* fragment)
|
||||
{
|
||||
G4int FragA = fragment->GetA_asInt();
|
||||
G4int FragZ = fragment->GetZ_asInt();
|
||||
ResA = FragA - theA;
|
||||
ResZ = FragZ - theZ;
|
||||
|
||||
G4double FragmentMass = fragment->GetGroundStateMass();
|
||||
G4double ExEnergy = fragment->GetExcitationEnergy();
|
||||
Mass = FragmentMass + ExEnergy;
|
||||
//G4cout << "G4EvaporationChannel::Initialize Z= " << theZ << " A= " << theA
|
||||
// << " FragZ= " << FragZ << " FragA= " << FragA << G4endl;
|
||||
EmissionProbability = 0.0;
|
||||
theProbability->ResetProbability();
|
||||
G4int fragA = fragment->GetA_asInt();
|
||||
G4int fragZ = fragment->GetZ_asInt();
|
||||
resA = fragA - theA;
|
||||
resZ = fragZ - theZ;
|
||||
|
||||
// Only channels which are physically allowed are taken into account
|
||||
if (ResA >= ResZ && ResZ > 0 && ResA >= theA) {
|
||||
|
||||
//Effective excitation energy
|
||||
G4double ResMass = G4NucleiProperties::GetNuclearMass(ResA, ResZ);
|
||||
if(resA < theA || resA < resZ || resZ < 0 || (resA == theA && resZ < theZ)
|
||||
|| ((resA > 1) && (resA == resZ || resZ == 0)))
|
||||
{ return 0.0; }
|
||||
|
||||
CoulombBarrier = (0 == theZ) ? 0.0 :
|
||||
theCoulombBarrier->GetCoulombBarrier(ResA,ResZ,ExEnergy);
|
||||
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);
|
||||
G4double bCoulomb = 0.0;
|
||||
G4double elim = 0.0;
|
||||
if(theZ > 0) {
|
||||
bCoulomb = theCoulombBarrier->GetCoulombBarrier(resA,resZ,exEnergy);
|
||||
|
||||
G4double delta0 =
|
||||
std::max(0.0,pairingCorrection->GetPairingCorrection(FragA,FragZ));
|
||||
/*
|
||||
G4cout << "ExEnergy= " << ExEnergy << " Ec= " << CoulombBarrier
|
||||
<< " delta0= " << delta0 << " delta1= " << delta1
|
||||
<< " Free= " << Mass - ResMass - EvapMass
|
||||
<< G4endl;
|
||||
*/
|
||||
// for OPTxs >0 penetration under the barrier is taken into account
|
||||
G4double elim = (0 == OPTxs) ? CoulombBarrier : CoulombBarrier*0.5;
|
||||
if(ExEnergy > delta0 && Mass > ResMass + EvapMass + elim) {
|
||||
G4double twoMass = Mass + Mass;
|
||||
MaxKinEnergy = std::max(((Mass-ResMass)*(Mass+ResMass)
|
||||
+ EvapMass*EvapMass)/twoMass - EvapMass,0.0);
|
||||
MinKinEnergy = (elim == 0.0) ? 0.0
|
||||
: std::max(((EvapMass + elim)*(twoMass-EvapMass-elim)
|
||||
+ EvapMass*EvapMass)/twoMass - EvapMass,0.0);
|
||||
//G4cout << "Emin= " << MinKinEnergy << " Emax= " << MaxKinEnergy << G4endl;
|
||||
EmissionProbability = theProbability->
|
||||
TotalProbability(*fragment, MinKinEnergy, MaxKinEnergy, CoulombBarrier);
|
||||
}
|
||||
const G4double dCB = 3.5*CLHEP::MeV;
|
||||
elim = (0 != OPTxs) ?
|
||||
std::max(bCoulomb*0.5, bCoulomb - dCB*theZ) : bCoulomb;
|
||||
}
|
||||
//G4cout<<"G4EvaporationChannel: probability= "<<EmissionProbability<<G4endl;
|
||||
return EmissionProbability;
|
||||
/*
|
||||
G4cout << "exEnergy= " << exEnergy << " Ec= " << bCoulomb
|
||||
<< " d0= " << delta0
|
||||
<< " Free= " << mass - resMass - evapMass
|
||||
<< G4endl;
|
||||
*/
|
||||
if(mass <= resMass + evapMass + elim) { return 0.0; }
|
||||
|
||||
G4double twoMass = mass + mass;
|
||||
G4double ekinmax =
|
||||
((mass-resMass)*(mass+resMass) + evapMass2)/twoMass - evapMass;
|
||||
G4double ekinmin = 0.0;
|
||||
if(elim > 0.0) {
|
||||
G4double resM = std::max(mass - evapMass - elim, resMass);
|
||||
ekinmin =
|
||||
std::max(((mass-resM)*(mass+resM) + evapMass2)/twoMass - evapMass,0.0);
|
||||
}
|
||||
/*
|
||||
G4cout << "Emin= " <<ekinmin<<" Emax= "<<ekinmax
|
||||
<< " mass= " << mass << " resM= " << resMass
|
||||
<< " evapM= " << evapMass << G4endl;
|
||||
*/
|
||||
if(ekinmax <= ekinmin) { return 0.0; }
|
||||
|
||||
theProbability->SetDecayKinematics(resZ, resA, resMass, mass);
|
||||
G4double prob = theProbability->TotalProbability(*fragment, ekinmin,
|
||||
ekinmax, bCoulomb,
|
||||
exEnergy - delta0);
|
||||
/*
|
||||
G4cout<<"G4EvaporationChannel: prob= "<< prob << " Z= " << theZ
|
||||
<< " A= " << theA << " E1= " << ekinmin << " E2= " << ekinmax
|
||||
<< G4endl;
|
||||
*/
|
||||
return prob;
|
||||
}
|
||||
|
||||
G4Fragment* G4EvaporationChannel::EmittedFragment(G4Fragment* theNucleus)
|
||||
{
|
||||
G4Fragment* evFragment = nullptr;
|
||||
G4double ekin = 0.0;
|
||||
if(ResA <= 4 &&
|
||||
((ResA == 4 && ResZ == 2) || (ResA == 3 && ResZ == 2) ||
|
||||
(ResA == 3 && ResZ == 1) || (ResA == 2 && ResZ == 1) ||
|
||||
(ResA == 1 && ResZ == 1) || (ResA == 1 && ResZ == 0) )) {
|
||||
G4double mres = G4NucleiProperties::GetNuclearMass(ResA, ResZ);
|
||||
ekin = 0.5*(Mass*Mass - mres*mres + EvapMass*EvapMass)/Mass - EvapMass;
|
||||
G4double ekin;
|
||||
// assumed, that TotalProbability(...) was already called
|
||||
// if value iz zero no possiblity to sample final state
|
||||
if(resA <= 4 || theProbability->GetProbability() == 0.0) {
|
||||
ekin = 0.5*(mass*mass - resMass*resMass + evapMass2)/mass - evapMass;
|
||||
} else {
|
||||
ekin = theProbability->SampleKineticEnergy(MinKinEnergy, MaxKinEnergy,
|
||||
CoulombBarrier);
|
||||
ekin = theProbability->SampleEnergy();
|
||||
}
|
||||
ekin = std::max(ekin, 0.0);
|
||||
G4LorentzVector lv0 = theNucleus->GetMomentum();
|
||||
G4LorentzVector lv(std::sqrt(ekin*(ekin + 2.0*EvapMass))*G4RandomDirection(),
|
||||
ekin + EvapMass);
|
||||
G4LorentzVector lv(std::sqrt(ekin*(ekin + 2.0*evapMass))*G4RandomDirection(),
|
||||
ekin + evapMass);
|
||||
lv.boost(lv0.boostVector());
|
||||
|
||||
evFragment = new G4Fragment(theA, theZ, lv);
|
||||
G4Fragment* evFragment = new G4Fragment(theA, theZ, lv);
|
||||
lv0 -= lv;
|
||||
theNucleus->SetZandA_asInt(ResZ, ResA);
|
||||
theNucleus->SetZandA_asInt(resZ, resA);
|
||||
theNucleus->SetMomentum(lv0);
|
||||
|
||||
//G4cout << "Residual: Z= " << resZ << " A= " << resA << " Eex= "
|
||||
// << theNucleus->GetExcitationEnergy() << G4endl;
|
||||
return evFragment;
|
||||
}
|
||||
|
||||
-6
@@ -23,8 +23,6 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
// Hadronic Process: Nuclear De-excitations
|
||||
// by J. M. Quesada (July 2009) on base of V. Lara code
|
||||
// V.Ivanchenko cleanup
|
||||
@@ -196,10 +194,6 @@ std::vector<G4VEvaporationChannel*>* G4EvaporationDefaultGEMFactory::GetChannel(
|
||||
theChannel->push_back( new G4Mg27GEMChannel() ); // Mg27
|
||||
theChannel->push_back( new G4Mg28GEMChannel() ); // Mg28
|
||||
|
||||
size_t nn = theChannel->size();
|
||||
for(size_t i=1; i<nn; ++i) {
|
||||
(*theChannel)[i]->SetPhotonEvaporation(thePhotonEvaporation);
|
||||
}
|
||||
return theChannel;
|
||||
}
|
||||
|
||||
|
||||
-10
@@ -23,8 +23,6 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
// Hadronic Process: Nuclear De-excitations
|
||||
// by V. Lara
|
||||
//
|
||||
@@ -66,14 +64,6 @@ std::vector<G4VEvaporationChannel*>* G4EvaporationFactory::GetChannel()
|
||||
theChannel->push_back( new G4He3EvaporationChannel() ); // He3
|
||||
theChannel->push_back( new G4AlphaEvaporationChannel() ); // Alpha
|
||||
|
||||
size_t nn = theChannel->size();
|
||||
for(size_t i=1; i<nn; ++i) {
|
||||
(*theChannel)[i]->SetPhotonEvaporation(thePhotonEvaporation);
|
||||
}
|
||||
|
||||
return theChannel;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
+66
-75
@@ -36,6 +36,8 @@
|
||||
// JMQ (14 february 2009) bug fixed in emission width: hbarc instead of
|
||||
// hbar_Planck in the denominator
|
||||
//
|
||||
// V.Ivanchenko general clean-up since 2010
|
||||
//
|
||||
#include "G4EvaporationProbability.hh"
|
||||
#include "G4NuclearLevelData.hh"
|
||||
#include "G4VCoulombBarrier.hh"
|
||||
@@ -48,84 +50,78 @@
|
||||
#include "Randomize.hh"
|
||||
#include "G4Exp.hh"
|
||||
#include "G4Log.hh"
|
||||
#include "G4Pow.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
static const G4double explim = 160.;
|
||||
|
||||
G4EvaporationProbability::G4EvaporationProbability(G4int anA, G4int aZ,
|
||||
G4double aGamma,
|
||||
G4VCoulombBarrier*)
|
||||
: G4VEmissionProbability(aZ, anA), Gamma(aGamma)
|
||||
G4double aGamma)
|
||||
: G4VEmissionProbability(aZ, anA), fGamma(aGamma)
|
||||
{
|
||||
resZ = resA = fragA = fragZ = 0;
|
||||
resA13 = muu = resMass = Mass = U = delta0 = delta1 = a0 = probmax = 0.0;
|
||||
partMass = G4NucleiProperties::GetNuclearMass(theA, theZ);
|
||||
pcoeff = Gamma*partMass*CLHEP::millibarn
|
||||
resA13 = muu = freeU = a0 = delta1 = 0.0;
|
||||
pcoeff = fGamma*pEvapMass*CLHEP::millibarn
|
||||
/((CLHEP::pi*CLHEP::hbarc)*(CLHEP::pi*CLHEP::hbarc));
|
||||
|
||||
if(0 == theZ) { index = 0; }
|
||||
else if(1 == theZ) { index = theA; }
|
||||
else { index = theA + 1; }
|
||||
fLevelData = G4NuclearLevelData::GetInstance();
|
||||
if(0 == aZ) {
|
||||
ResetIntegrator(30, 0.25*CLHEP::MeV, 0.02);
|
||||
} else if(1 == aZ && 1 == anA) {
|
||||
ResetIntegrator(30, 0.5*CLHEP::MeV, 0.03);
|
||||
} else {
|
||||
ResetIntegrator(30, 0.5*CLHEP::MeV, 0.03);
|
||||
}
|
||||
// G4cout << "G4EvaporationProbability: Z= " << theZ << " A= " << theA
|
||||
// << " M(GeV)= " << pEvapMass/GeV << G4endl;
|
||||
}
|
||||
|
||||
G4EvaporationProbability::~G4EvaporationProbability()
|
||||
{}
|
||||
|
||||
G4double G4EvaporationProbability::EmissionProbability(
|
||||
const G4Fragment&, G4double)
|
||||
G4double G4EvaporationProbability::CalcAlphaParam(const G4Fragment&)
|
||||
{
|
||||
return 0.0;
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
G4double G4EvaporationProbability::CalcBetaParam(const G4Fragment&)
|
||||
{
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
G4double G4EvaporationProbability::TotalProbability(
|
||||
const G4Fragment & fragment, G4double minEnergy, G4double maxEnergy,
|
||||
G4double CoulombBarrier)
|
||||
const G4Fragment& fragment, G4double minEnergy, G4double maxEnergy,
|
||||
G4double CB, G4double exEnergy)
|
||||
{
|
||||
fragA = fragment.GetA_asInt();
|
||||
fragZ = fragment.GetZ_asInt();
|
||||
resA = fragA - theA;
|
||||
resZ = fragZ - theZ;
|
||||
|
||||
G4double fragMass = fragment.GetGroundStateMass();
|
||||
U = fragment.GetExcitationEnergy();
|
||||
Mass = fragMass + U;
|
||||
delta0 = std::max(0.0, fPairCorr->GetPairingCorrection(fragA,fragZ));
|
||||
delta1 = std::max(0.0, fPairCorr->GetPairingCorrection(resA,resZ));
|
||||
resMass = G4NucleiProperties::GetNuclearMass(resA, resZ);
|
||||
resA13 = fG4pow->Z13(resA);
|
||||
a0 = fLevelData->GetLevelDensity(fragZ,fragA,U);
|
||||
/*
|
||||
G4int fragA = fragment.GetA_asInt();
|
||||
G4int fragZ = fragment.GetZ_asInt();
|
||||
G4double U = fragment.GetExcitationEnergy();
|
||||
a0 = pNuclearLevelData->GetLevelDensity(fragZ,fragA,U);
|
||||
freeU = exEnergy;
|
||||
resA13 = pG4pow->Z13(resA);
|
||||
delta1 = pNuclearLevelData->GetPairingCorrection(resZ,resA);
|
||||
/*
|
||||
G4cout << "G4EvaporationProbability: Z= " << theZ << " A= " << theA
|
||||
<< " resZ= " << resZ << " resA= " << resA
|
||||
<< " fragZ= " << fragZ << " fragA= " << fragA
|
||||
<< "\n U= " << U << " d0= " << delta0 << " a0= " << a0
|
||||
<< " OPT= " << OPTxs << G4endl;
|
||||
<< "\n freeU= " << freeU
|
||||
<< " a0= " << a0 << " OPT= " << OPTxs << " emin= "
|
||||
<< minEnergy << " emax= " << maxEnergy
|
||||
<< " CB= " << CB << G4endl;
|
||||
*/
|
||||
if(U < delta0 || maxEnergy <= minEnergy) { return 0.0; }
|
||||
|
||||
G4double Width = 0.0;
|
||||
if (OPTxs==0 || (OPTxs==4 && U < 10. + delta0)) {
|
||||
if (OPTxs==0 || (OPTxs==4 && freeU < 10.)) {
|
||||
|
||||
G4double SystemEntropy = 2.0*std::sqrt(a0*(U-delta0));
|
||||
G4double SystemEntropy = 2.0*std::sqrt(a0*freeU);
|
||||
|
||||
static const G4double RN2 =
|
||||
2.25*fermi*fermi/(twopi* hbar_Planck*hbar_Planck);
|
||||
const G4double RN2 = 2.25*CLHEP::fermi*CLHEP::fermi
|
||||
/(CLHEP::twopi*CLHEP::hbar_Planck*hbar_Planck);
|
||||
|
||||
G4double Alpha = CalcAlphaParam(fragment);
|
||||
G4double Beta = CalcBetaParam(fragment);
|
||||
|
||||
// to be checked where to use a0, where - a1
|
||||
G4double a1 = fLevelData->GetLevelDensity(resZ,resA,U);
|
||||
G4double GlobalFactor = Gamma*Alpha*partMass*RN2*resA13*resA13/(a1*a1);
|
||||
G4double a1 = pNuclearLevelData->GetLevelDensity(resZ,resA,freeU);
|
||||
G4double GlobalFactor = fGamma*Alpha*pEvapMass*RN2*resA13*resA13/(a1*a1);
|
||||
|
||||
G4double maxea = maxEnergy*a1;
|
||||
G4double Term1 = Beta*a1 - 1.5 + maxea;
|
||||
@@ -137,7 +133,7 @@ G4double G4EvaporationProbability::TotalProbability(
|
||||
ExpTerm2 = std::min(ExpTerm2, explim);
|
||||
ExpTerm2 = G4Exp(ExpTerm2);
|
||||
|
||||
Width = GlobalFactor*(Term1*ExpTerm1 + Term2*ExpTerm2);
|
||||
pProbability = GlobalFactor*(Term1*ExpTerm1 + Term2*ExpTerm2);
|
||||
|
||||
} else {
|
||||
|
||||
@@ -147,49 +143,52 @@ G4double G4EvaporationProbability::TotalProbability(
|
||||
}
|
||||
// if Coulomb barrier cutoff is superimposed for all cross sections
|
||||
// then the limit is the Coulomb Barrier
|
||||
Width = IntegrateProbability(minEnergy, maxEnergy, CoulombBarrier);
|
||||
pProbability = IntegrateProbability(minEnergy, maxEnergy, CB);
|
||||
}
|
||||
return Width;
|
||||
return pProbability;
|
||||
}
|
||||
|
||||
G4double G4EvaporationProbability::ComputeProbability(G4double K, G4double cb)
|
||||
G4double G4EvaporationProbability::ComputeProbability(G4double K, G4double CB)
|
||||
{
|
||||
//G4cout << "### G4EvaporationProbability::ProbabilityDistributionFunction"
|
||||
// << G4endl;
|
||||
|
||||
G4double E0 = std::max(U - delta0, 0.0);
|
||||
G4double E1 = Mass - partMass - resMass - delta1 - K;
|
||||
/*
|
||||
G4cout << "PDF: FragZ= " << fragZ << " FragA= " << fragA
|
||||
<< " Z= " << theZ << " A= " << theA
|
||||
<< " K= " << K << " E0= " << E0 << " E1= " << E1 << G4endl;
|
||||
*/
|
||||
if(E1 < 0.0) { return 0.0; }
|
||||
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 = sqrt(m02 + m12 - 2.*pMass*(pEvapMass + K));
|
||||
|
||||
G4double a1 = fLevelData->GetLevelDensity(resZ,resA,U);
|
||||
G4double xs = CrossSection(K, cb);
|
||||
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);
|
||||
G4double prob = pcoeff*G4Exp(2.0*(std::sqrt(a1*E1) - std::sqrt(a0*E0)))*K*xs;
|
||||
/*
|
||||
G4cout << "Evap prob: " << prob << " FragZ= " << fragZ << " FragA= " << fragA
|
||||
<< " Z= " << theZ << " A= " << theA
|
||||
<< "\n K= " << K << " E0= " << E0 << " E1= " << E1
|
||||
<< " cb= " << cb << " xsec= " << xs << G4endl;
|
||||
/*
|
||||
G4cout << "PDF: Z= " << theZ << " A= " << theA
|
||||
<< " K= " << K << " E0= " << E0 << " E1= " << E1 << G4endl;
|
||||
G4cout << " prob= " << prob << " pcoeff= " << pcoeff
|
||||
<< " xs= " << xs << G4endl;
|
||||
*/
|
||||
return prob;
|
||||
}
|
||||
|
||||
G4double
|
||||
G4EvaporationProbability::CrossSection(G4double K, G4double cb)
|
||||
G4EvaporationProbability::CrossSection(G4double K, G4double CB)
|
||||
{
|
||||
G4double res;
|
||||
if(OPTxs <= 2) {
|
||||
res = G4ChatterjeeCrossSection::ComputeCrossSection(K, cb, resA13, muu,
|
||||
res = G4ChatterjeeCrossSection::ComputeCrossSection(K, CB, resA13, muu,
|
||||
index, theZ, resA);
|
||||
} else {
|
||||
res = G4KalbachCrossSection::ComputeCrossSection(K, cb, resA13, muu,
|
||||
res = G4KalbachCrossSection::ComputeCrossSection(K, CB, resA13, muu,
|
||||
index, theZ, theA, resA);
|
||||
}
|
||||
//G4cout << " K= " << K << " res= " << res << " muu= " << muu << G4endl;
|
||||
//G4cout << "XS: K= "<<K<<" res= "<<res<<" cb= "<<CB<<" muu= "
|
||||
// <<muu<<" index= " << index<< G4endl;
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -205,8 +204,7 @@ G4EvaporationProbability::SampleKineticEnergy(G4double minKinEnergy,
|
||||
*/
|
||||
G4double T = 0.0;
|
||||
CLHEP::HepRandomEngine* rndm = G4Random::getTheEngine();
|
||||
static const G4int nmax = 100;
|
||||
if (OPTxs==0 || (OPTxs==4 && U < 10. + delta0)) {
|
||||
if (OPTxs==0 || (OPTxs==4 && freeU < 10.)) {
|
||||
// JMQ:
|
||||
// It uses Dostrovsky's approximation for the inverse reaction cross
|
||||
// in the probability for fragment emission
|
||||
@@ -219,6 +217,8 @@ G4EvaporationProbability::SampleKineticEnergy(G4double minKinEnergy,
|
||||
G4double Rk = 0.0;
|
||||
G4double FRk = 0.0;
|
||||
G4int nn = 0;
|
||||
const G4int nmax = 100;
|
||||
const G4double ssqr3 = 1.5*std::sqrt(3.0);
|
||||
do {
|
||||
G4double RandNumber = rndm->flat();
|
||||
Rk = 1.0 + (1./RbSqrt)*G4Log(RandNumber + (1.0-RandNumber)*PEX1);
|
||||
@@ -230,7 +230,6 @@ G4EvaporationProbability::SampleKineticEnergy(G4double minKinEnergy,
|
||||
Q2 = Q1*std::sqrt(Q1);
|
||||
}
|
||||
|
||||
static const G4double ssqr3 = 1.5*std::sqrt(3.0);
|
||||
FRk = ssqr3 * Rk * (Q1 - Rk*Rk)/Q2;
|
||||
if(nn > nmax) { break; }
|
||||
++nn;
|
||||
@@ -240,16 +239,8 @@ G4EvaporationProbability::SampleKineticEnergy(G4double minKinEnergy,
|
||||
T = std::max(maxKinEnergy * (1.0-Rk*Rk), 0.0) + minKinEnergy;
|
||||
|
||||
} else {
|
||||
|
||||
if(fVerbose > 1) {
|
||||
G4cout << "###=== SampleEnergy: " << " Z= " << theZ
|
||||
<< " A= " << theA << " FragZ= " << fragZ
|
||||
<< " FragA= " << fragA << G4endl;
|
||||
}
|
||||
T = SampleEnergy();
|
||||
|
||||
}
|
||||
//G4cout << "-- new Z= " << theZ << " A= " << theA << " ekin= " << T << G4endl;
|
||||
//G4cout<<"-- new Z= "<<theZ<<" A= "<< theA << " ekin= " << T << G4endl;
|
||||
return T;
|
||||
//return fLevelData->FindLevel(resZ, resA, resMass, Mass, partMass, T);
|
||||
}
|
||||
|
||||
+2
-3
@@ -24,16 +24,15 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
// Hadronic Process: Nuclear De-excitations
|
||||
// by V. Lara (Nov. 1999)
|
||||
//
|
||||
// 17-11-2010 V.Ivanchenko moved constructor and destructor to source and cleanup
|
||||
// 17-11-2010 V.Ivanchenko cleanup
|
||||
|
||||
#include "G4He3EvaporationChannel.hh"
|
||||
|
||||
G4He3EvaporationChannel::G4He3EvaporationChannel()
|
||||
: G4EvaporationChannel(3,2,"He3",&theEvaporationProbability,&theCoulombBarrier)
|
||||
: G4EvaporationChannel(3,2,&pr)
|
||||
{}
|
||||
|
||||
G4He3EvaporationChannel::~G4He3EvaporationChannel()
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@
|
||||
#include "G4He3EvaporationProbability.hh"
|
||||
|
||||
G4He3EvaporationProbability::G4He3EvaporationProbability() :
|
||||
G4EvaporationProbability(3,2,2.0,&theCoulombBarrier)
|
||||
G4EvaporationProbability(3,2,2.0)
|
||||
{}
|
||||
|
||||
G4He3EvaporationProbability::~G4He3EvaporationProbability()
|
||||
|
||||
+1
-2
@@ -24,7 +24,6 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
// Hadronic Process: Nuclear De-excitations
|
||||
// by V. Lara (Nov. 1999)
|
||||
//
|
||||
@@ -33,7 +32,7 @@
|
||||
#include "G4NeutronEvaporationChannel.hh"
|
||||
|
||||
G4NeutronEvaporationChannel::G4NeutronEvaporationChannel()
|
||||
: G4EvaporationChannel(1,0,"neutron",&theEvaporationProbability,&theCoulombBarrier)
|
||||
: G4EvaporationChannel(1,0,&pr)
|
||||
{}
|
||||
|
||||
G4NeutronEvaporationChannel::~G4NeutronEvaporationChannel()
|
||||
|
||||
+4
-4
@@ -35,9 +35,10 @@
|
||||
|
||||
#include "G4NeutronEvaporationProbability.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4Pow.hh"
|
||||
|
||||
G4NeutronEvaporationProbability::G4NeutronEvaporationProbability() :
|
||||
G4EvaporationProbability(1,0,2.0,&theCoulombBarrier)
|
||||
G4EvaporationProbability(1,0,2.0)
|
||||
{}
|
||||
|
||||
G4NeutronEvaporationProbability::~G4NeutronEvaporationProbability()
|
||||
@@ -45,12 +46,11 @@ G4NeutronEvaporationProbability::~G4NeutronEvaporationProbability()
|
||||
|
||||
G4double G4NeutronEvaporationProbability::CalcAlphaParam(const G4Fragment& fragment)
|
||||
{
|
||||
return 0.76+2.2/fG4pow->Z13(fragment.GetA_asInt() - 1);
|
||||
return 0.76+2.2/pG4pow->Z13(fragment.GetA_asInt() - 1);
|
||||
}
|
||||
|
||||
G4double G4NeutronEvaporationProbability::CalcBetaParam(const G4Fragment& fragment)
|
||||
{
|
||||
return (2.12/fG4pow->Z23(fragment.GetA_asInt() - 1) - 0.05)*CLHEP::MeV/
|
||||
return (2.12/pG4pow->Z23(fragment.GetA_asInt() - 1) - 0.05)*CLHEP::MeV/
|
||||
CalcAlphaParam(fragment);
|
||||
}
|
||||
|
||||
|
||||
+2
-3
@@ -24,16 +24,15 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
// Hadronic Process: Nuclear De-excitations
|
||||
// by V. Lara (Nov. 1999)
|
||||
//
|
||||
// 17-11-2010 V.Ivanchenko moved constructor and destructor to source and cleanup
|
||||
// 17-11-2010 V.Ivanchenko cleanup
|
||||
|
||||
#include "G4ProtonEvaporationChannel.hh"
|
||||
|
||||
G4ProtonEvaporationChannel::G4ProtonEvaporationChannel()
|
||||
: G4EvaporationChannel(1,1,"proton",&theEvaporationProbability,&theCoulombBarrier)
|
||||
: G4EvaporationChannel(1,1,&pr)
|
||||
{}
|
||||
|
||||
G4ProtonEvaporationChannel::~G4ProtonEvaporationChannel()
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@
|
||||
#include "G4ProtonEvaporationProbability.hh"
|
||||
|
||||
G4ProtonEvaporationProbability::G4ProtonEvaporationProbability() :
|
||||
G4EvaporationProbability(1,1,2.0,&theCoulombBarrier)
|
||||
G4EvaporationProbability(1,1,2.0)
|
||||
{}
|
||||
|
||||
G4ProtonEvaporationProbability::~G4ProtonEvaporationProbability()
|
||||
|
||||
+2
-2
@@ -28,12 +28,12 @@
|
||||
// Hadronic Process: Nuclear De-excitations
|
||||
// by V. Lara (Nov. 1999)
|
||||
//
|
||||
// 17-11-2010 V.Ivanchenko moved constructor and destructor to source and cleanup
|
||||
// 17-11-2010 V.Ivanchenko cleanup
|
||||
|
||||
#include "G4TritonEvaporationChannel.hh"
|
||||
|
||||
G4TritonEvaporationChannel::G4TritonEvaporationChannel()
|
||||
: G4EvaporationChannel(3,1,"triton",&theEvaporationProbability,&theCoulombBarrier)
|
||||
: G4EvaporationChannel(3,1,&pr)
|
||||
{}
|
||||
|
||||
G4TritonEvaporationChannel::~G4TritonEvaporationChannel()
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@
|
||||
#include "G4TritonEvaporationProbability.hh"
|
||||
|
||||
G4TritonEvaporationProbability::G4TritonEvaporationProbability() :
|
||||
G4EvaporationProbability(3,1,2.0,&theCoulombBarrier)
|
||||
G4EvaporationProbability(3,1,2.0)
|
||||
{}
|
||||
|
||||
G4TritonEvaporationProbability::~G4TritonEvaporationProbability()
|
||||
|
||||
+89
-106
@@ -50,11 +50,12 @@
|
||||
#include "G4NucleiProperties.hh"
|
||||
#include "G4NuclearLevelData.hh"
|
||||
#include "G4LevelManager.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
const G4int G4UnstableFragmentBreakUp::Zfr[] = {0, 1, 1, 1, 2, 2};
|
||||
const G4int G4UnstableFragmentBreakUp::Afr[] = {1, 1, 2, 3, 3, 4};
|
||||
|
||||
G4UnstableFragmentBreakUp::G4UnstableFragmentBreakUp()
|
||||
G4UnstableFragmentBreakUp::G4UnstableFragmentBreakUp() : fVerbose(1)
|
||||
{
|
||||
fLevelData = G4NuclearLevelData::GetInstance();
|
||||
for(G4int i=0; i<6; ++i) {
|
||||
@@ -74,125 +75,107 @@ G4bool G4UnstableFragmentBreakUp::BreakUpChain(G4FragmentVector* results,
|
||||
G4int Z = nucleus->GetZ_asInt();
|
||||
G4int A = nucleus->GetA_asInt();
|
||||
|
||||
// if the isotope is in the database it is not exotic
|
||||
// so, cannot be handled by this class
|
||||
if(fLevelData->GetLevelManager(Z, A)) { return false; }
|
||||
|
||||
G4LorentzVector lv = nucleus->GetMomentum();
|
||||
G4double time = nucleus->GetCreationTime();
|
||||
|
||||
G4double mass1(0.0), mass2(0.0);
|
||||
|
||||
// look for the decay channel with normal masses
|
||||
// without Coulomb barrier and paring corrections
|
||||
// 1 - recoil, 2 - emitted light ion
|
||||
if(fVerbose > 1) {
|
||||
G4cout << "#Unstable decay " << " Z= " << Z << " A= " << A
|
||||
<< " Eex(MeV)= " << nucleus->GetExcitationEnergy() << G4endl;
|
||||
}
|
||||
const G4double tolerance = 10*CLHEP::eV;
|
||||
const G4double dmlimit = 0.2*CLHEP::MeV;
|
||||
G4double mass = lv.mag();
|
||||
G4bool done = false;
|
||||
|
||||
G4int Amax = A;
|
||||
G4int Zres = Z;
|
||||
G4int Ares = A;
|
||||
|
||||
for(G4int k=0; k<Amax; ++k) {
|
||||
// look for the decay channel with normal masses
|
||||
// without Coulomb barrier and paring corrections
|
||||
|
||||
// 1 - recoil, 2 - emitted light ion
|
||||
|
||||
//G4cout << "Unstable decay #" << k << " Z= " << Z << " A= " << A << G4endl;
|
||||
|
||||
G4bool isChannel = false;
|
||||
G4double ekin = 0.0;
|
||||
G4int i;
|
||||
for(i=0; i<6; ++i) {
|
||||
Zres = Z - Zfr[i];
|
||||
Ares = A - Afr[i];
|
||||
for(G4int j=0; j<6; ++j) {
|
||||
if(Zres == Zfr[j] && Ares == Afr[j]) {
|
||||
/*
|
||||
G4cout << "i= " << i << " j= " << j << " Zres= " << Zres
|
||||
<< " Ares= " << Ares << " dm= " << mass - masses[i] - masses[j]
|
||||
<< G4endl;
|
||||
*/
|
||||
if(mass >= masses[i] + masses[j]) {
|
||||
mass2 = masses[i];
|
||||
mass1 = masses[j];
|
||||
ekin = 0.0;
|
||||
done = true;
|
||||
isChannel = true;
|
||||
break;
|
||||
G4double exca = -1000.0;
|
||||
G4bool isChannel = false;
|
||||
G4int idx = -1;
|
||||
for(G4int i=0; i<6; ++i) {
|
||||
G4int Zres = Z - Zfr[i];
|
||||
G4int Ares = A - Afr[i];
|
||||
if(Zres >= 0 && Ares >= Zres && Ares >= Afr[i]) {
|
||||
if(Ares <= 4) {
|
||||
for(G4int j=0; j<6; ++j) {
|
||||
if(Zres == Zfr[j] && Ares == Afr[j]) {
|
||||
/*
|
||||
G4cout << "i= " << i << " j= " << j << " Zres= " << Zres
|
||||
<< " Ares= " << Ares << " dm= " << mass - masses[i] - masses[j]
|
||||
<< G4endl;
|
||||
*/
|
||||
G4double delm = mass - masses[i] - masses[j];
|
||||
if(delm > exca) {
|
||||
mass2 = masses[i]; // emitted
|
||||
mass1 = masses[j]; // recoil
|
||||
exca = delm;
|
||||
idx = i;
|
||||
if(delm > 0.0) { isChannel = true; }
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(isChannel) { break; }
|
||||
if(Zres >= 0 && Ares >= Zres && Ares > 0) {
|
||||
G4double mres = G4NucleiProperties::GetNuclearMass(Ares, Zres);
|
||||
G4double e = mass - mres - masses[i];
|
||||
// select the most excited state
|
||||
const G4LevelManager* lman = fLevelData->GetLevelManager(Z, A);
|
||||
if(lman && e >= ekin) {
|
||||
mass2 = masses[i];
|
||||
mass1 = mres;
|
||||
ekin = lman->NearestLowEdgeLevelEnergy(e);
|
||||
isChannel = true;
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
// no simple channel
|
||||
G4double mres = G4NucleiProperties::GetNuclearMass(Ares, Zres);
|
||||
G4double e = mass - mres - masses[i];
|
||||
// select excited state
|
||||
const G4LevelManager* lman = fLevelData->GetLevelManager(Zres, Ares);
|
||||
if(lman && e >= 0.0) {
|
||||
mass2 = masses[i];
|
||||
mass1 = mres + e*G4UniformRand();
|
||||
idx = i;
|
||||
isChannel = true;
|
||||
break;
|
||||
}
|
||||
// if physical channel is not identified
|
||||
// check excitation energy
|
||||
if(e > exca) {
|
||||
mass2 = masses[i];
|
||||
mass1 = mres;
|
||||
if(e > 0.0) { mass1 += e; }
|
||||
exca = e;
|
||||
idx = i;
|
||||
}
|
||||
}
|
||||
|
||||
// no decay channel - assume that primary mass is biased
|
||||
// only energy will be conserved
|
||||
if(!isChannel) {
|
||||
for(i=0; i<6; ++i) {
|
||||
Zres = Z - Zfr[i];
|
||||
Ares = A - Afr[i];
|
||||
if(Zres >= 0 && Ares >= Zres && Ares > 0) {
|
||||
|
||||
G4double mres = proton_mass_c2*Zres + neutron_mass_c2*(Ares - Zres);
|
||||
G4double e = mass - mres - masses[i];
|
||||
if(e >= ekin) {
|
||||
mass2 = masses[i];
|
||||
mass1 = mres;
|
||||
ekin = e;
|
||||
isChannel = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!isChannel) {
|
||||
// further decay impossible
|
||||
// if no one decay sampled do not update primary
|
||||
if(0 == k) { return false; }
|
||||
else { break; }
|
||||
}
|
||||
|
||||
// useful to left max excitation for the residual
|
||||
mass1 += ekin;
|
||||
|
||||
// compute energy of light fragment
|
||||
G4double e2 = 0.5*((mass - mass1)*(mass + mass1) + mass2*mass2)/mass;
|
||||
e2 = std::max(e2, mass2);
|
||||
G4double mom = std::sqrt((e2 - mass2)*(e2 + mass2));
|
||||
|
||||
// sample decay
|
||||
G4ThreeVector bst = lv.boostVector();
|
||||
G4ThreeVector v = G4RandomDirection();
|
||||
G4LorentzVector mom2 = G4LorentzVector(v*mom, e2);
|
||||
mom2.boost(bst);
|
||||
frag = new G4Fragment(Afr[i], Zfr[i], mom2);
|
||||
frag->SetCreationTime(time);
|
||||
results->push_back(frag);
|
||||
|
||||
// residual
|
||||
lv -= mom2;
|
||||
Z -= Zfr[i];
|
||||
A -= Afr[i];
|
||||
|
||||
mass = lv.mag();
|
||||
|
||||
if(done) { break; }
|
||||
}
|
||||
G4double massmin = mass1 + mass2;
|
||||
if(mass < massmin) {
|
||||
if(mass + dmlimit < massmin) { return false; }
|
||||
if(fVerbose > 1) {
|
||||
G4cout << "#Unstable decay correction: Z= " << Z << " A= " << A
|
||||
<< " idx= " << idx
|
||||
<< " deltaM(MeV)= " << mass - massmin
|
||||
<< G4endl;
|
||||
}
|
||||
mass = massmin;
|
||||
G4double e = std::max(lv.e(), mass + tolerance);
|
||||
G4double mom = std::sqrt((e - mass)*(e + mass));
|
||||
G4ThreeVector dir = lv.vect().unit();
|
||||
lv.set(dir*mom, e);
|
||||
}
|
||||
|
||||
// updated primary
|
||||
// compute energy of light fragment
|
||||
G4double e2 = 0.5*((mass - mass1)*(mass + mass1) + mass2*mass2)/mass;
|
||||
e2 = std::max(e2, mass2);
|
||||
G4double mom = std::sqrt((e2 - mass2)*(e2 + mass2));
|
||||
|
||||
// sample decay
|
||||
G4ThreeVector bst = lv.boostVector();
|
||||
G4ThreeVector v = G4RandomDirection();
|
||||
G4LorentzVector mom2 = G4LorentzVector(v*mom, e2);
|
||||
mom2.boost(bst);
|
||||
frag = new G4Fragment(Afr[idx], Zfr[idx], mom2);
|
||||
frag->SetCreationTime(time);
|
||||
results->push_back(frag);
|
||||
|
||||
// residual
|
||||
lv -= mom2;
|
||||
Z -= Zfr[idx];
|
||||
A -= Afr[idx];
|
||||
|
||||
nucleus->SetZandA_asInt(Z, A);
|
||||
nucleus->SetMomentum(lv);
|
||||
return true;
|
||||
|
||||
+5
-6
@@ -48,22 +48,22 @@ class G4FermiBreakUpVI : public G4VFermiBreakUp
|
||||
public:
|
||||
|
||||
explicit G4FermiBreakUpVI();
|
||||
virtual ~G4FermiBreakUpVI();
|
||||
~G4FermiBreakUpVI() final;
|
||||
|
||||
virtual void Initialise() final;
|
||||
void Initialise() final;
|
||||
|
||||
// check if the Fermi Break Up model can be used
|
||||
// mass is an effective mass of a fragment
|
||||
virtual G4bool IsApplicable(G4int ZZ, G4int AA, G4double etot) const final;
|
||||
G4bool IsApplicable(G4int ZZ, G4int AA, G4double etot) const final;
|
||||
|
||||
// new interface - vector of products is added to the provided vector
|
||||
// primary fragment is deleted or is modified and added to the list
|
||||
// of products
|
||||
virtual void BreakFragment(G4FragmentVector*, G4Fragment* theNucleus) final;
|
||||
void BreakFragment(G4FragmentVector*, G4Fragment* theNucleus) final;
|
||||
|
||||
private:
|
||||
|
||||
virtual void InitialisePool() final;
|
||||
void InitialisePool();
|
||||
|
||||
G4bool SampleDecay();
|
||||
|
||||
@@ -77,7 +77,6 @@ private:
|
||||
|
||||
CLHEP::HepRandomEngine* rndmEngine;
|
||||
|
||||
G4int verbose;
|
||||
G4int maxZ;
|
||||
G4int maxA;
|
||||
|
||||
|
||||
+4
-4
@@ -57,10 +57,10 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
inline const G4FermiChannels& operator=(const G4FermiChannels&) = delete;
|
||||
inline G4FermiChannels(const G4FermiChannels &) = delete;
|
||||
inline G4bool operator==(const G4FermiChannels &) const = delete;
|
||||
inline G4bool operator!=(const G4FermiChannels &) const = delete;
|
||||
inline const G4FermiChannels& operator=(const G4FermiChannels&);
|
||||
inline G4FermiChannels(const G4FermiChannels &);
|
||||
inline G4bool operator==(const G4FermiChannels &);
|
||||
inline G4bool operator!=(const G4FermiChannels &);
|
||||
|
||||
size_t nch;
|
||||
G4double excitation;
|
||||
|
||||
+8
-24
@@ -39,8 +39,7 @@ class G4FermiFragment
|
||||
{
|
||||
public:
|
||||
|
||||
explicit G4FermiFragment(G4int anA, G4int aZ, G4int sp,
|
||||
G4double exc, G4bool stable, G4bool phys = true);
|
||||
explicit G4FermiFragment(G4int anA, G4int aZ, G4int sp, G4double exc);
|
||||
|
||||
~G4FermiFragment();
|
||||
|
||||
@@ -74,20 +73,9 @@ public:
|
||||
return (fragmentMass + excitEnergy);
|
||||
}
|
||||
|
||||
inline G4bool IsStable() const
|
||||
{
|
||||
return isStable;
|
||||
}
|
||||
|
||||
inline G4bool IsPhysical() const
|
||||
{
|
||||
return isPhysical;
|
||||
}
|
||||
|
||||
inline G4double GetCoulombBarrier(G4int Ares, G4int Zres, G4double Eex) const
|
||||
{
|
||||
return cBarrier ? cBarrier->GetCoulombBarrier(Ares, Zres, Eex)
|
||||
*cBarrier->BarrierPenetrationFactor(Z) : 0.0;
|
||||
return cBarrier->GetCoulombBarrier(Ares, Zres, Eex);
|
||||
}
|
||||
|
||||
inline G4bool operator==(const G4FermiFragment &right) const
|
||||
@@ -98,22 +86,18 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
G4int A;
|
||||
G4int Z;
|
||||
G4int spin;
|
||||
|
||||
G4bool isStable;
|
||||
G4bool isPhysical;
|
||||
|
||||
G4double excitEnergy;
|
||||
G4double fragmentMass;
|
||||
|
||||
G4CoulombBarrier* cBarrier;
|
||||
|
||||
G4FermiFragment(const G4FermiFragment &right) = delete;
|
||||
const G4FermiFragment & operator=(const G4FermiFragment &right) = delete;
|
||||
G4bool operator!=(const G4FermiFragment &right) const = delete;
|
||||
G4int A;
|
||||
G4int Z;
|
||||
G4int spin;
|
||||
|
||||
G4FermiFragment(const G4FermiFragment &right);
|
||||
const G4FermiFragment & operator=(const G4FermiFragment &right);
|
||||
G4bool operator!=(const G4FermiFragment &right) const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
+2
-13
@@ -55,11 +55,11 @@ public:
|
||||
void DumpFragment(const G4FermiFragment*) const;
|
||||
|
||||
void Dump() const;
|
||||
|
||||
G4bool IsApplicable(G4int Z, G4int A, G4double etot) const;
|
||||
|
||||
G4bool IsPhysical(G4int Z, G4int A) const;
|
||||
|
||||
G4bool HasChannels(G4int Z, G4int A, G4double exc) const;
|
||||
|
||||
inline const G4FermiDecayProbability* FermiDecayProbability() const;
|
||||
|
||||
inline G4int GetMaxZ() const;
|
||||
@@ -92,24 +92,13 @@ private:
|
||||
|
||||
// pool
|
||||
std::vector<const G4FermiFragment*> fragment_pool;
|
||||
std::vector<const G4FermiFragment*> funstable;
|
||||
|
||||
// lists of configurations sorted by A
|
||||
|
||||
// "stable" fragments
|
||||
std::vector<const G4FermiFragment*> list_f[maxA];
|
||||
// list of channels for "stable" fragments
|
||||
std::vector<G4FermiChannels*> list_c[maxA];
|
||||
// pairs of stable fragments
|
||||
std::vector<const G4FermiPair*> list_p[maxA];
|
||||
|
||||
// "unstable" fragments
|
||||
std::vector<const G4FermiFragment*> list_g[maxA];
|
||||
// list of channels of stable and unstable fragments
|
||||
std::vector<G4FermiChannels*> list_d[maxA];
|
||||
// pairs of stable and unstable fragments
|
||||
std::vector<const G4FermiPair*> list_u[maxA];
|
||||
|
||||
};
|
||||
|
||||
inline G4int G4FermiFragmentsPoolVI::GetMaxZ() const
|
||||
|
||||
+11
-5
@@ -40,7 +40,7 @@ class G4VFermiBreakUp
|
||||
{
|
||||
public:
|
||||
|
||||
explicit G4VFermiBreakUp() {};
|
||||
explicit G4VFermiBreakUp() : verbose(0) {};
|
||||
virtual ~G4VFermiBreakUp() {};
|
||||
|
||||
virtual void Initialise() = 0;
|
||||
@@ -56,12 +56,18 @@ public:
|
||||
virtual void BreakFragment(G4FragmentVector* results,
|
||||
G4Fragment* theNucleus) = 0;
|
||||
|
||||
inline void SetVerbose(G4int val) { verbose = val; }
|
||||
|
||||
protected:
|
||||
|
||||
G4int verbose;
|
||||
|
||||
private:
|
||||
|
||||
G4VFermiBreakUp(const G4VFermiBreakUp &right) = delete;
|
||||
const G4VFermiBreakUp & operator=(const G4VFermiBreakUp &right) = delete;
|
||||
G4bool operator==(const G4VFermiBreakUp &right) const = delete;
|
||||
G4bool operator!=(const G4VFermiBreakUp &right) const = delete;
|
||||
G4VFermiBreakUp(const G4VFermiBreakUp &right);
|
||||
const G4VFermiBreakUp & operator=(const G4VFermiBreakUp &right);
|
||||
G4bool operator==(const G4VFermiBreakUp &right) const;
|
||||
G4bool operator!=(const G4VFermiBreakUp &right) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
+24
-27
@@ -44,9 +44,8 @@ G4Mutex G4FermiBreakUpVI::FermiBreakUpVIMutex = G4MUTEX_INITIALIZER;
|
||||
#endif
|
||||
|
||||
G4FermiBreakUpVI::G4FermiBreakUpVI()
|
||||
: theDecay(nullptr), rndmEngine(nullptr), verbose(0), maxZ(9), maxA(17)
|
||||
: theDecay(nullptr), rndmEngine(nullptr), maxZ(9), maxA(17)
|
||||
{
|
||||
prob.reserve(10);
|
||||
frag.reserve(10);
|
||||
lvect.reserve(10);
|
||||
Z = A = spin = 0;
|
||||
@@ -67,13 +66,12 @@ G4FermiBreakUpVI::~G4FermiBreakUpVI()
|
||||
|
||||
void G4FermiBreakUpVI::Initialise()
|
||||
{
|
||||
if(verbose > 0) {
|
||||
if(verbose > 1) {
|
||||
G4cout << "### G4FermiBreakUpVI::Initialise(): " << thePool << G4endl;
|
||||
}
|
||||
if(thePool == nullptr) { InitialisePool(); }
|
||||
theDecay = thePool->FermiDecayProbability();
|
||||
elim = thePool->GetEnergyLimit();
|
||||
//tolerance = thePool->GetTolerance();
|
||||
}
|
||||
|
||||
void G4FermiBreakUpVI::InitialisePool()
|
||||
@@ -91,18 +89,18 @@ void G4FermiBreakUpVI::InitialisePool()
|
||||
|
||||
G4bool G4FermiBreakUpVI::IsApplicable(G4int ZZ, G4int AA, G4double eexc) const
|
||||
{
|
||||
return (ZZ < maxZ && AA < maxA && AA > 0 && eexc <= elim) ? true : false;
|
||||
return (ZZ < maxZ && AA < maxA && AA > 0 && eexc <= elim
|
||||
&& thePool->HasChannels(ZZ, AA, eexc));
|
||||
}
|
||||
|
||||
void G4FermiBreakUpVI::BreakFragment(G4FragmentVector* theResult,
|
||||
G4Fragment* theNucleus)
|
||||
{
|
||||
if(verbose > 0) {
|
||||
G4cout << "### G4FermiBreakUpVI::BreakFragment start new fragment " << G4endl;
|
||||
if(verbose > 1) {
|
||||
G4cout << "### G4FermiBreakUpVI::BreakFragment start new fragment "
|
||||
<< G4endl;
|
||||
G4cout << *theNucleus << G4endl;
|
||||
}
|
||||
frag.clear();
|
||||
lvect.clear();
|
||||
|
||||
// initial fragment
|
||||
Z = theNucleus->GetZ_asInt();
|
||||
@@ -110,16 +108,17 @@ void G4FermiBreakUpVI::BreakFragment(G4FragmentVector* theResult,
|
||||
excitation = theNucleus->GetExcitationEnergy();
|
||||
mass = theNucleus->GetGroundStateMass() + excitation;
|
||||
spin = -1;
|
||||
G4double time = theNucleus->GetCreationTime();
|
||||
|
||||
lv0 = theNucleus->GetMomentum();
|
||||
rndmEngine = G4Random::getTheEngine();
|
||||
|
||||
// sample first decay of an initial state
|
||||
// if not possible to decay - exit
|
||||
if(!SampleDecay()) {
|
||||
theResult->push_back(theNucleus);
|
||||
return;
|
||||
}
|
||||
|
||||
G4double time = theNucleus->GetCreationTime();
|
||||
delete theNucleus;
|
||||
|
||||
static const G4int imax = 100;
|
||||
@@ -131,18 +130,15 @@ void G4FermiBreakUpVI::BreakFragment(G4FragmentVector* theResult,
|
||||
A = frag[i]->GetA();
|
||||
spin = frag[i]->GetSpin();
|
||||
mass = frag[i]->GetTotalEnergy();
|
||||
excitation = 0.0;
|
||||
if(thePool->IsPhysical(Z, A)) {
|
||||
excitation = frag[i]->GetExcitationEnergy();
|
||||
}
|
||||
lv0 = lvect[i];
|
||||
if(verbose > 0) {
|
||||
if(verbose > 1) {
|
||||
G4cout << "# FermiFrag " << i << ". Z= " << Z << " A= " << A
|
||||
<< " mass= " << mass << " exc= " << excitation << G4endl;
|
||||
<< " mass= " << mass << " exc= "
|
||||
<< frag[i]->GetExcitationEnergy() << G4endl;
|
||||
}
|
||||
// stable fragment
|
||||
if(!SampleDecay()) {
|
||||
if(verbose > 0) { G4cout << " New G4Fragment" << G4endl; }
|
||||
if(verbose > 1) { G4cout << " New G4Fragment" << G4endl; }
|
||||
G4Fragment* f = new G4Fragment(A, Z, lv0);
|
||||
f->SetSpin(0.5*spin);
|
||||
f->SetCreationTime(time);
|
||||
@@ -153,6 +149,8 @@ void G4FermiBreakUpVI::BreakFragment(G4FragmentVector* theResult,
|
||||
break;
|
||||
}
|
||||
}
|
||||
frag.clear();
|
||||
lvect.clear();
|
||||
}
|
||||
|
||||
G4bool G4FermiBreakUpVI::SampleDecay()
|
||||
@@ -160,7 +158,7 @@ G4bool G4FermiBreakUpVI::SampleDecay()
|
||||
const G4FermiChannels* chan = thePool->ClosestChannels(Z, A, mass);
|
||||
if(!chan) { return false; }
|
||||
size_t nn = chan->GetNumberOfChannels();
|
||||
if(verbose > 0) {
|
||||
if(verbose > 1) {
|
||||
G4cout << "== SampleDecay " << nn << " channels Eex= "
|
||||
<< chan->GetExcitation() << G4endl;
|
||||
}
|
||||
@@ -185,7 +183,7 @@ G4bool G4FermiBreakUpVI::SampleDecay()
|
||||
const std::vector<const G4FermiPair*>& pvect = chan->GetChannels();
|
||||
if(nn > 12) { prob.resize(nn, 0.0); }
|
||||
G4double ptot = 0.0;
|
||||
if(verbose > 1) {
|
||||
if(verbose > 2) {
|
||||
G4cout << "Start recompute probabilities" << G4endl;
|
||||
}
|
||||
for(size_t i=0; i<nn; ++i) {
|
||||
@@ -193,7 +191,7 @@ G4bool G4FermiBreakUpVI::SampleDecay()
|
||||
pvect[i]->GetFragment1(),
|
||||
pvect[i]->GetFragment2());
|
||||
prob[i] = ptot;
|
||||
if(verbose > 1) {
|
||||
if(verbose > 2) {
|
||||
G4cout << i << ". " << prob[i]
|
||||
<< " Z1= " << pvect[i]->GetFragment1()->GetZ()
|
||||
<< " A1= " << pvect[i]->GetFragment1()->GetA()
|
||||
@@ -218,7 +216,7 @@ G4bool G4FermiBreakUpVI::SampleDecay()
|
||||
|
||||
G4double mass1 = frag1->GetTotalEnergy();
|
||||
G4double mass2 = frag2->GetTotalEnergy();
|
||||
if(verbose > 1) {
|
||||
if(verbose > 2) {
|
||||
G4cout << " M= " << mass << " M1= " << mass1 << " M2= " << mass2
|
||||
<< " Exc1= " << frag1->GetExcitationEnergy()
|
||||
<< " Exc2= " << frag2->GetExcitationEnergy() << G4endl;
|
||||
@@ -239,13 +237,12 @@ G4bool G4FermiBreakUpVI::SampleDecay()
|
||||
boostVector = lv0.boostVector();
|
||||
lv1.boost(boostVector);
|
||||
|
||||
G4double e2 = mass - e1;
|
||||
lv0 -= lv1;
|
||||
|
||||
G4double e2 = lv0.e();
|
||||
if(e2 < mass2) {
|
||||
e2 = mass2;
|
||||
p1 = 0.0;
|
||||
lv0.set(0.,0.,0.,mass2);
|
||||
}
|
||||
lv0.set(-v*p1, e2);
|
||||
lv0.boost(boostVector);
|
||||
|
||||
frag.push_back(frag1);
|
||||
frag.push_back(frag2);
|
||||
|
||||
+4
-11
@@ -32,18 +32,11 @@
|
||||
#include "G4NucleiProperties.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
|
||||
G4FermiFragment::G4FermiFragment(G4int anA, G4int aZ, G4int sp,
|
||||
G4double exc, G4bool stable, G4bool phys):
|
||||
A(anA), Z(aZ), spin(sp), isStable(stable), isPhysical(phys),
|
||||
excitEnergy(exc)
|
||||
G4FermiFragment::G4FermiFragment(G4int anA, G4int aZ, G4int sp, G4double exc)
|
||||
: excitEnergy(exc), A(anA), Z(aZ), spin(sp)
|
||||
{
|
||||
cBarrier = nullptr;
|
||||
if(phys) {
|
||||
fragmentMass = G4NucleiProperties::GetNuclearMass(A, Z);
|
||||
if(!stable) { cBarrier = new G4CoulombBarrier(A, Z); }
|
||||
} else {
|
||||
fragmentMass = Z*proton_mass_c2 + (A-Z)*neutron_mass_c2;
|
||||
}
|
||||
cBarrier = new G4CoulombBarrier(A, Z);
|
||||
fragmentMass = G4NucleiProperties::GetNuclearMass(A, Z);
|
||||
}
|
||||
|
||||
G4FermiFragment::~G4FermiFragment()
|
||||
|
||||
+146
-415
@@ -41,178 +41,117 @@ G4FermiFragmentsPoolVI::G4FermiFragmentsPoolVI()
|
||||
// G4cout << "### G4FermiFragmentsPoolVI is constructed" << G4endl;
|
||||
G4DeexPrecoParameters* param =
|
||||
G4NuclearLevelData::GetInstance()->GetParameters();
|
||||
tolerance = (G4float)param->GetMinExcitation();
|
||||
tolerance = param->GetMinExcitation();
|
||||
timelim = (G4float)param->GetMaxLifeTime();
|
||||
|
||||
elim = param->GetFBUEnergyLimit();
|
||||
elimf= (G4float)elim;
|
||||
|
||||
/*
|
||||
G4cout << "G4FermiFragmentsPoolVI: tolerance= " << tolerance
|
||||
<< " timelim= " << timelim << " elim= " << elim << G4endl;
|
||||
*/
|
||||
fragment_pool.reserve(991);
|
||||
funstable.reserve(80);
|
||||
|
||||
Initialise();
|
||||
}
|
||||
|
||||
G4FermiFragmentsPoolVI::~G4FermiFragmentsPoolVI()
|
||||
{
|
||||
size_t nn;
|
||||
for(G4int i=0; i<maxA; ++i) {
|
||||
nn = list_p[i].size();
|
||||
for(size_t j=0; j<nn; ++j) { delete (list_p[i])[j]; }
|
||||
nn = list_c[i].size();
|
||||
for(size_t j=0; j<nn; ++j) { delete (list_c[i])[j]; }
|
||||
nn = list_d[i].size();
|
||||
for(size_t j=0; j<nn; ++j) { delete (list_d[i])[j]; }
|
||||
nn = list_u[i].size();
|
||||
for(size_t j=0; j<nn; ++j) { delete (list_u[i])[j]; }
|
||||
for(auto & ptr : list_p[i]) { delete ptr; ptr = nullptr; }
|
||||
for(auto & ptr : list_c[i]) { delete ptr; ptr = nullptr; }
|
||||
}
|
||||
nn = fragment_pool.size();
|
||||
for(size_t j=0; j<nn; ++j) { delete fragment_pool[j]; }
|
||||
nn = funstable.size();
|
||||
for(size_t j=0; j<nn; ++j) { delete funstable[j]; }
|
||||
}
|
||||
|
||||
G4bool
|
||||
G4FermiFragmentsPoolVI::IsApplicable(G4int Z, G4int A, G4double etot) const
|
||||
{
|
||||
G4bool isInList = false;
|
||||
size_t nn = list_f[A].size();
|
||||
for(size_t i=0; i<nn; ++i) {
|
||||
if(Z == (list_f[A])[i]->GetZ()) {
|
||||
isInList = true;
|
||||
if(etot <= (list_f[A])[i]->GetFragmentMass() + elim) { return true; }
|
||||
}
|
||||
}
|
||||
if(isInList) { return false; }
|
||||
nn = list_g[A].size();
|
||||
for(size_t i=0; i<nn; ++i) {
|
||||
if(Z == (list_g[A])[i]->GetZ() &&
|
||||
etot <= (list_g[A])[i]->GetFragmentMass() + elim) { return true; }
|
||||
}
|
||||
return false;
|
||||
for(auto & ptr : fragment_pool) { delete ptr; ptr = nullptr; }
|
||||
}
|
||||
|
||||
const G4FermiChannels*
|
||||
G4FermiFragmentsPoolVI::ClosestChannels(G4int Z, G4int A, G4double e) const
|
||||
{
|
||||
const G4FermiChannels* res = nullptr;
|
||||
G4double demax = e;
|
||||
const G4FermiChannels* res = nullptr;
|
||||
G4double demax = 1.e+9;
|
||||
|
||||
// stable channels;
|
||||
size_t nn = list_c[A].size();
|
||||
for(size_t j=0; j<nn; ++j) {
|
||||
// stable channels
|
||||
for(size_t j=0; j<(list_c[A]).size(); ++j) {
|
||||
const G4FermiFragment* frag = (list_f[A])[j];
|
||||
if(frag->GetZ() != Z) { continue; }
|
||||
G4double de = e - frag->GetTotalEnergy();
|
||||
//G4cout << " Stab check " << j << " channel de= " << de << " tol= " << tolerance << G4endl;
|
||||
//G4cout << " Stab check " << j << " channel de= " << de
|
||||
// << " tol= " << tolerance << G4endl;
|
||||
// an excitation coincide with a level
|
||||
if(std::abs(de) <= tolerance) {
|
||||
res = (list_c[A])[j];
|
||||
//G4cout << " Stab chan: " << j << " N= " << res->GetNumberOfChannels() << G4endl;
|
||||
break;
|
||||
} else if(de + tolerance > 0.0) {
|
||||
if(de < demax) {
|
||||
res = (list_c[A])[j];
|
||||
demax = de;
|
||||
//G4cout << " Stab chan: " << j << " N= " << res->GetNumberOfChannels() << G4endl;
|
||||
break;
|
||||
} else {
|
||||
// closest level selected
|
||||
de += tolerance;
|
||||
if(de >= 0.0 && de <= demax) {
|
||||
res = (list_c[A])[j];
|
||||
demax = de;
|
||||
}
|
||||
//G4cout << " Stab chan: " << j << " N= "
|
||||
//<< res->GetNumberOfChannels() << G4endl;
|
||||
}
|
||||
}
|
||||
// unstable channels
|
||||
if(!res) {
|
||||
nn = list_d[A].size();
|
||||
for(size_t j=0; j<nn; ++j) {
|
||||
const G4FermiFragment* frag = (list_g[A])[j];
|
||||
if(frag->GetZ() != Z) { continue; }
|
||||
G4double de = e - frag->GetTotalEnergy();
|
||||
//G4cout << " Unst check " << j << " channel de= " << de << " tol= " << tolerance << G4endl;
|
||||
if(std::abs(de) <= tolerance || de > 0.0) {
|
||||
res = (list_d[A])[j];
|
||||
//G4cout << " Unst chan No: " << j << " N= " << res->GetNumberOfChannels() << G4endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
G4bool G4FermiFragmentsPoolVI::IsPhysical(G4int Z, G4int A) const
|
||||
{
|
||||
G4bool res = false;
|
||||
G4int nn = list_f[A].size();
|
||||
for(G4int i=0; i<nn; ++i) {
|
||||
if((list_f[A])[i]->GetZ() == Z) {
|
||||
res = true;
|
||||
break;
|
||||
}
|
||||
for(auto const& ptr : list_f[A]) {
|
||||
if(ptr->GetZ() == Z) { return true; }
|
||||
}
|
||||
return res;
|
||||
return false;
|
||||
}
|
||||
|
||||
G4bool G4FermiFragmentsPoolVI::IsInThePool(G4int Z, G4int A,
|
||||
G4double exc) const
|
||||
G4double exc) const
|
||||
{
|
||||
G4bool res = false;
|
||||
G4int nfrag = fragment_pool.size();
|
||||
for(G4int i=0; i<nfrag; ++i) {
|
||||
const G4FermiFragment* fr = fragment_pool[i];
|
||||
if(fr->GetZ() == Z && fr->GetA() == A &&
|
||||
std::abs(exc - fr->GetExcitationEnergy()) < tolerance) {
|
||||
res = true;
|
||||
break;
|
||||
for(auto const& fr : fragment_pool) {
|
||||
if(fr->GetZ() == Z && fr->GetA() == A &&
|
||||
std::abs(exc - fr->GetExcitationEnergy()) < tolerance)
|
||||
{ return true; }
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
G4bool
|
||||
G4FermiFragmentsPoolVI::HasChannels(G4int Z, G4int A, G4double exc) const
|
||||
{
|
||||
// stable fragment
|
||||
for(size_t j=0; j<(list_f[A]).size(); ++j) {
|
||||
const G4FermiFragment* frag = (list_f[A])[j];
|
||||
if(frag->GetZ() == Z) {
|
||||
if(exc > frag->GetExcitationEnergy() &&
|
||||
(list_c[A])[j]->GetNumberOfChannels() > 0) { return true; }
|
||||
}
|
||||
}
|
||||
return res;
|
||||
return false;
|
||||
}
|
||||
|
||||
G4bool G4FermiFragmentsPoolVI::IsInPhysPairs(
|
||||
const G4FermiFragment* f1, const G4FermiFragment* f2) const
|
||||
{
|
||||
G4bool res = false;
|
||||
G4int A1 = f1->GetA();
|
||||
G4int A2 = f2->GetA();
|
||||
G4int A = A1 + A2;
|
||||
G4int nn = list_p[A].size();
|
||||
for(G4int i=0; i<nn; ++i) {
|
||||
if(f1 == (list_p[A])[i]->GetFragment1() &&
|
||||
f2 == (list_p[A])[i]->GetFragment2()) {
|
||||
res = true;
|
||||
break;
|
||||
const G4int A = f1->GetA() + f2->GetA();
|
||||
for(auto const& ptr : list_p[A]) {
|
||||
if(f1 == ptr->GetFragment1() && f2 == ptr->GetFragment2()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
G4bool G4FermiFragmentsPoolVI::IsInUnphysPairs(
|
||||
const G4FermiFragment* f1, const G4FermiFragment* f2) const
|
||||
{
|
||||
G4bool res = false;
|
||||
G4int A1 = f1->GetA();
|
||||
G4int A2 = f2->GetA();
|
||||
G4int A = A1 + A2;
|
||||
G4int nn = list_u[A].size();
|
||||
for(G4int i=0; i<nn; ++i) {
|
||||
if(f1 == (list_u[A])[i]->GetFragment1() &&
|
||||
f2 == (list_u[A])[i]->GetFragment2()) {
|
||||
res = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
return false;
|
||||
}
|
||||
|
||||
void G4FermiFragmentsPoolVI::Initialise()
|
||||
{
|
||||
static const G4int nmin = 8;
|
||||
//G4cout << "G4FermiFragmentsPoolVI::Initialise main loop @@@@@@" << G4endl;
|
||||
|
||||
// stable particles
|
||||
fragment_pool.push_back(new G4FermiFragment(1, 0, 1, 0.0, true, true));
|
||||
fragment_pool.push_back(new G4FermiFragment(1, 1, 1, 0.0, true, true));
|
||||
fragment_pool.push_back(new G4FermiFragment(2, 1, 2, 0.0, true, true));
|
||||
fragment_pool.push_back(new G4FermiFragment(3, 1, 1, 0.0, true, true));
|
||||
fragment_pool.push_back(new G4FermiFragment(3, 2, 1, 0.0, true, true));
|
||||
fragment_pool.push_back(new G4FermiFragment(4, 2, 0, 0.0, true, true));
|
||||
fragment_pool.push_back(new G4FermiFragment(5, 2, 3, 0.0, true, true));
|
||||
fragment_pool.push_back(new G4FermiFragment(5, 3, 3, 0.0, true, true));
|
||||
fragment_pool.push_back(new G4FermiFragment(1, 0, 1, 0.0));
|
||||
fragment_pool.push_back(new G4FermiFragment(1, 1, 1, 0.0));
|
||||
fragment_pool.push_back(new G4FermiFragment(2, 1, 2, 0.0));
|
||||
fragment_pool.push_back(new G4FermiFragment(3, 1, 1, 0.0));
|
||||
fragment_pool.push_back(new G4FermiFragment(3, 2, 1, 0.0));
|
||||
fragment_pool.push_back(new G4FermiFragment(4, 2, 0, 0.0));
|
||||
fragment_pool.push_back(new G4FermiFragment(5, 2, 3, 0.0));
|
||||
fragment_pool.push_back(new G4FermiFragment(5, 3, 3, 0.0));
|
||||
|
||||
// use level data and construct the pool
|
||||
G4NuclearLevelData* ndata = G4NuclearLevelData::GetInstance();
|
||||
@@ -220,82 +159,51 @@ void G4FermiFragmentsPoolVI::Initialise()
|
||||
G4int Amin = ndata->GetMinA(Z);
|
||||
G4int Amax = std::min(maxA, ndata->GetMaxA(Z)+1);
|
||||
for(G4int A=Amin; A<Amax; ++A) {
|
||||
const G4LevelManager* man = ndata->GetLevelManager(Z, A);
|
||||
const G4LevelManager* man = ndata->GetLevelManager(Z, A, true);
|
||||
if(man) {
|
||||
size_t nn = man->NumberOfTransitions();
|
||||
// very unstable state
|
||||
if(ndata->MaxLevelEnergy(Z, A) == 0.0f && man->LifeTime(0) == 0.0f) {
|
||||
continue;
|
||||
}
|
||||
size_t nn = man->NumberOfTransitions();
|
||||
// very unstable state
|
||||
if(ndata->MaxLevelEnergy(Z, A) == 0.0f && man->LifeTime(0) == 0.0f) {
|
||||
continue;
|
||||
}
|
||||
for(size_t i=0; i<=nn; ++i) {
|
||||
G4float exc = man->LevelEnergy(i);
|
||||
// only levels below limit are consided
|
||||
/*
|
||||
G4cout << "Z= " << Z << " A= " << A << " Eex= " << exc
|
||||
<< " elimf= " << elimf << " toler= " << tolerance
|
||||
<< " time= " << man->LifeTime(i) << " i= " << i << G4endl;
|
||||
*/
|
||||
// only levels below limit are consided
|
||||
if(exc >= elimf) { continue; }
|
||||
G4double excd = (G4double)exc;
|
||||
G4double excd = (G4double)exc;
|
||||
// only new are considered
|
||||
if(IsInThePool(Z, A, excd)) { continue; }
|
||||
G4float ltime = man->LifeTime(i);
|
||||
G4bool stable = (ltime < 0.0f || ltime > timelim) ? true : false;
|
||||
//G4cout << "Z= " << Z << " A= " << A << " Eex= " << exc
|
||||
// << " t= " << ltime << " tlim= " << timelim
|
||||
// << " stable: "<< stable << G4endl;
|
||||
fragment_pool.push_back(new G4FermiFragment(A,Z,man->SpinTwo(i),excd,stable,true));
|
||||
}
|
||||
if(IsInThePool(Z, A, excd)) { continue; }
|
||||
fragment_pool.push_back(new G4FermiFragment(A,Z,man->SpinTwo(i),excd));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
G4int nfrag = fragment_pool.size();
|
||||
// prepare structures per A for normal fragments
|
||||
static const size_t lfmax[maxA] = {
|
||||
const size_t lfmax[maxA] = {
|
||||
0, 2, 1, 2, 1, 2, 8, 19, 28, 56, 70, 104, 74, 109, 143, 212, 160};
|
||||
// 0, 2, 1, 2, 1, 2, 6, 14, 16, 22, 45, 53, 37, 44, 33, 58, 63};
|
||||
for(G4int A=1; A<maxA; ++A) {
|
||||
list_f[A].reserve(lfmax[A]);
|
||||
list_c[A].reserve(lfmax[A]);
|
||||
}
|
||||
static const size_t lfch[maxA] = {
|
||||
0, 0, 0, 0, 0, 1, 4, 8, 8, 15, 33, 48, 36, 27, 66, 69, 39};
|
||||
// 0, 0, 0, 0, 0, 1, 2, 5, 6, 3, 12, 8, 4, 10, 1, 8, 6};
|
||||
G4int nfrag = fragment_pool.size();
|
||||
for(G4int i=0; i<nfrag; ++i) {
|
||||
const G4FermiFragment* f = fragment_pool[i];
|
||||
const size_t lfch[maxA] = {
|
||||
0, 0, 0, 0, 0, 1, 4, 8, 6, 13, 27, 40, 29, 21, 31, 32, 30};
|
||||
|
||||
for(auto const& f : fragment_pool) {
|
||||
G4int A = f->GetA();
|
||||
G4double exc = f->GetExcitationEnergy();
|
||||
list_f[A].push_back(f);
|
||||
list_c[A].push_back(new G4FermiChannels(lfch[A], exc, f->GetTotalEnergy()));
|
||||
}
|
||||
|
||||
// list of unphysical fragments
|
||||
static const size_t lfun[maxA] = {
|
||||
|
||||
0, 0, 2, 2, 4, 4, 6, 6, 6, 6, 6, 6, 7, 6, 7, 6, 6};
|
||||
for(G4int A=1; A<maxA; ++A) {
|
||||
list_g[A].reserve(lfun[A]);
|
||||
list_d[A].reserve(lfun[A]);
|
||||
}
|
||||
|
||||
static const size_t luch[maxA] = {
|
||||
0, 0, 1, 1, 3, 3, 5, 6, 6, 8, 8, 8, 8, 8, 8, 8, 8};
|
||||
for(G4int Z=0; Z<maxZ; ++Z) {
|
||||
G4int A0 = std::max(Z, 1);
|
||||
for(G4int A=A0; A<maxA; ++A) {
|
||||
if(IsInThePool(Z, A, 0.0)) { continue; }
|
||||
const G4FermiFragment* f = new G4FermiFragment(A, Z, -1, 0.0, false, false);
|
||||
funstable.push_back(f);
|
||||
list_g[A].push_back(f);
|
||||
list_d[A].push_back(new G4FermiChannels(luch[A],0.0,f->GetTotalEnergy()));
|
||||
}
|
||||
}
|
||||
static const size_t pphm[maxA] = {
|
||||
0, 0, 2, 2, 4, 4, 6, 6, 6, 6, 6, 6, 7, 6, 7, 6, 6};
|
||||
static const size_t punm[maxA] = {
|
||||
0, 0, 2, 2, 8, 10, 22, 24, 24, 31, 35, 36, 44, 36, 44, 36, 36};
|
||||
for(G4int A=1; A<maxA; ++A) {
|
||||
list_p[A].reserve(pphm[A]);
|
||||
list_u[A].reserve(punm[A]);
|
||||
}
|
||||
/*
|
||||
G4cout << "G4FermiFragmentsPoolVI::Initialise main loop @@@@@@"
|
||||
<< " Nfrag= " << nfrag << " Nuns= " << funstable.size() << G4endl;
|
||||
/*
|
||||
G4cout << "Defined fragments @@@@@@"
|
||||
<< " PhysicalFrag= " << nfrag
|
||||
<< " UnphysicalFrag= " << funstable.size() << G4endl;
|
||||
*/
|
||||
// list of fragment pairs ordered by A
|
||||
for(G4int i=0; i<nfrag; ++i) {
|
||||
@@ -311,120 +219,42 @@ void G4FermiFragmentsPoolVI::Initialise()
|
||||
G4int Z = Z1 + Z2;
|
||||
G4int A = A1 + A2;
|
||||
|
||||
if(Z >= maxZ || A >= maxA ||
|
||||
IsInPhysPairs(f1, f2) || IsInUnphysPairs(f1, f2)) { continue; }
|
||||
if(Z >= maxZ || A >= maxA || IsInPhysPairs(f1, f2)) { continue; }
|
||||
|
||||
G4double e2 = f2->GetTotalEnergy();
|
||||
G4double minE = e1 + e2;
|
||||
G4double exc = 0.0;
|
||||
if(IsPhysical(Z, A)) {
|
||||
minE += f1->GetCoulombBarrier(A2, Z2, 0.0);
|
||||
exc = minE - G4NucleiProperties::GetNuclearMass(A, Z);
|
||||
minE += f1->GetCoulombBarrier(A2, Z2, 0.0);
|
||||
exc = minE - G4NucleiProperties::GetNuclearMass(A, Z);
|
||||
}
|
||||
/*
|
||||
G4cout << "Z= " << Z << " A= " << A
|
||||
<< " Z1= " << Z1 << " A1= " << A1
|
||||
<< " Z2= " << Z2 << " A2= " << A2 << " Eex= " << exc
|
||||
<< " Qb= " << f1->GetCoulombBarrier(A2, Z2, 0.0)
|
||||
<< " " << e1
|
||||
<< " " << e2
|
||||
<< " " << G4NucleiProperties::GetNuclearMass(A, Z)
|
||||
<< G4endl;
|
||||
G4cout << "Z= " << Z << " A= " << A
|
||||
<< " Z1= " << Z1 << " A1= " << A1
|
||||
<< " Z2= " << Z2 << " A2= " << A2 << " Eex= " << exc
|
||||
<< " Qb= " << f1->GetCoulombBarrier(A2, Z2, 0.0)
|
||||
<< " " << e1
|
||||
<< " " << e2
|
||||
<< " " << G4NucleiProperties::GetNuclearMass(A, Z)
|
||||
<< G4endl;
|
||||
*/
|
||||
// ignore very excited case
|
||||
if(exc >= elim) { continue; }
|
||||
G4FermiPair* fpair = nullptr;
|
||||
G4int kmax = list_f[A].size();
|
||||
for(G4int k=0; k<kmax; ++k) {
|
||||
const G4FermiFragment* f3 = (list_f[A])[k];
|
||||
if(Z == f3->GetZ() &&
|
||||
f3->GetTotalEnergy() - minE + tolerance >= 0.0) {
|
||||
if(!fpair) {
|
||||
fpair = new G4FermiPair(f1, f2);
|
||||
list_p[A].push_back(fpair);
|
||||
}
|
||||
(list_c[A])[k]->AddChannel(fpair);
|
||||
}
|
||||
}
|
||||
if(fpair) { continue; }
|
||||
|
||||
kmax = list_g[A].size();
|
||||
for(G4int k=0; k<kmax; ++k) {
|
||||
if((list_d[A])[k]->GetNumberOfChannels() >= nmin) { continue; }
|
||||
const G4FermiFragment* f3 = (list_g[A])[k];
|
||||
/*
|
||||
if(Z==0) {
|
||||
G4cout << "%%% A= " << A << " isStable: " << f3->IsStable()
|
||||
<< " de= " << f3->GetTotalEnergy() - minE << G4endl;
|
||||
}
|
||||
*/
|
||||
if(Z == f3->GetZ() &&
|
||||
f3->GetTotalEnergy() - minE + tolerance >= 0.0) {
|
||||
if(!fpair) {
|
||||
fpair = new G4FermiPair(f1, f2);
|
||||
list_u[A].push_back(fpair);
|
||||
}
|
||||
(list_d[A])[k]->AddChannel(fpair);
|
||||
/*
|
||||
if(Z==0) {
|
||||
G4cout << " isAdded Unstable" << G4endl;
|
||||
}
|
||||
*/
|
||||
}
|
||||
const G4FermiFragment* f3 = (list_f[A])[k];
|
||||
if(Z == f3->GetZ() &&
|
||||
f3->GetTotalEnergy() - minE + tolerance >= 0.0) {
|
||||
if(!fpair) {
|
||||
fpair = new G4FermiPair(f1, f2);
|
||||
list_p[A].push_back(fpair);
|
||||
}
|
||||
(list_c[A])[k]->AddChannel(fpair);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// G4cout << "@@@@@@ sec loop @@@@@@" << G4endl;
|
||||
// list of fragment pairs (stable+unstable) ordered by A
|
||||
G4int unphys = funstable.size();
|
||||
for(G4int i=0; i<nfrag; ++i) {
|
||||
const G4FermiFragment* f1 = fragment_pool[i];
|
||||
G4int Z1 = f1->GetZ();
|
||||
G4int A1 = f1->GetA();
|
||||
G4double e1 = f1->GetTotalEnergy();
|
||||
for(G4int j=0; j<unphys; ++j) {
|
||||
const G4FermiFragment* f2 = funstable[j];
|
||||
G4int Z2 = f2->GetZ();
|
||||
G4int A2 = f2->GetA();
|
||||
G4int Z = Z1 + Z2;
|
||||
G4int A = A1 + A2;
|
||||
if(Z >= maxZ || A >= maxA || IsInUnphysPairs(f1, f2) || IsPhysical(Z, A))
|
||||
{ continue; }
|
||||
G4double e2 = f2->GetTotalEnergy();
|
||||
G4double minE = e1 + e2;
|
||||
/*
|
||||
G4cout << "Z= " << Z << " A= " << A << " Z1= " << Z1 << " A1= " << A1
|
||||
<< " Z2= " << Z2 << " A2= " << A2 << G4endl;
|
||||
*/
|
||||
// check if this is the list of stable pairs
|
||||
G4FermiPair* fpair = nullptr;
|
||||
// check unphysics list
|
||||
G4int kmax = list_g[A].size();
|
||||
for(G4int k=0; k<kmax; ++k) {
|
||||
const G4FermiFragment* f3 = (list_g[A])[k];
|
||||
/*
|
||||
if(Z == f3->GetZ())
|
||||
G4cout << " Unst+ST k= " << k << " Z= " << f3->GetZ()
|
||||
<< " isStab " << f3->IsStable()
|
||||
<< " Nch= " << (list_d[A])[k]->GetNumberOfChannels()
|
||||
<< " de= " << f3->GetTotalEnergy() - minE
|
||||
<< G4endl;
|
||||
*/
|
||||
if(Z == f3->GetZ() &&
|
||||
(list_d[A])[k]->GetNumberOfChannels() < nmin &&
|
||||
f3->GetTotalEnergy() - minE + tolerance >= 0.0)
|
||||
{
|
||||
fpair = new G4FermiPair(f1, f2);
|
||||
list_u[A].push_back(fpair);
|
||||
(list_d[A])[k]->AddChannel(fpair);
|
||||
// G4cout << " isAdded Unstable" << G4endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// compute static probabilities
|
||||
for(G4int A=1; A<maxA; ++A) {
|
||||
for(size_t j=0; j<list_c[A].size(); ++j) {
|
||||
@@ -432,51 +262,24 @@ void G4FermiFragmentsPoolVI::Initialise()
|
||||
const G4FermiFragment* frag = (list_f[A])[j];
|
||||
size_t nch = ch->GetNumberOfChannels();
|
||||
if(1 < nch) {
|
||||
std::vector<G4double>& prob = ch->GetProbabilities();
|
||||
const std::vector<const G4FermiPair*>& pairs = ch->GetChannels();
|
||||
std::vector<G4double>& prob = ch->GetProbabilities();
|
||||
const std::vector<const G4FermiPair*>& pairs = ch->GetChannels();
|
||||
G4double ptot = 0.0;
|
||||
for(size_t i=0; i<nch; ++i) {
|
||||
ptot += theDecay.ComputeProbability(frag->GetZ(), frag->GetA(),
|
||||
frag->GetSpin(),
|
||||
frag->GetTotalEnergy(),
|
||||
pairs[i]->GetFragment1(),
|
||||
pairs[i]->GetFragment2());
|
||||
ptot += theDecay.ComputeProbability(frag->GetZ(), frag->GetA(),
|
||||
frag->GetSpin(),
|
||||
frag->GetTotalEnergy(),
|
||||
pairs[i]->GetFragment1(),
|
||||
pairs[i]->GetFragment2());
|
||||
prob[i] = ptot;
|
||||
}
|
||||
}
|
||||
if(0.0 == ptot) {
|
||||
prob[0] = 1.0;
|
||||
} else {
|
||||
ptot = 1./ptot;
|
||||
for(size_t i=0; i<nch-1; ++i) { prob[i] *= ptot; }
|
||||
prob[nch-1] = 1.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for(G4int A=1; A<maxA; ++A) {
|
||||
for(size_t j=0; j<list_d[A].size(); ++j) {
|
||||
G4FermiChannels* ch = (list_d[A])[j];
|
||||
const G4FermiFragment* frag = (list_g[A])[j];
|
||||
size_t nch = ch->GetNumberOfChannels();
|
||||
if(1 < nch) {
|
||||
std::vector<G4double>& prob = ch->GetProbabilities();
|
||||
const std::vector<const G4FermiPair*>& pairs = ch->GetChannels();
|
||||
G4double ptot = 0.0;
|
||||
for(size_t i=0; i<nch; ++i) {
|
||||
ptot += theDecay.ComputeProbability(frag->GetZ(), frag->GetA(),
|
||||
frag->GetSpin(),
|
||||
frag->GetTotalEnergy(),
|
||||
pairs[i]->GetFragment1(),
|
||||
pairs[i]->GetFragment2());
|
||||
prob[i] = ptot;
|
||||
}
|
||||
if(0.0 == ptot) {
|
||||
prob[0] = 1.0;
|
||||
} else {
|
||||
ptot = 1./ptot;
|
||||
for(size_t i=0; i<nch-1; ++i) { prob[i] *= ptot; }
|
||||
prob[nch-1] = 1.0;
|
||||
}
|
||||
prob[0] = 1.0;
|
||||
} else {
|
||||
ptot = 1./ptot;
|
||||
for(size_t i=0; i<nch-1; ++i) { prob[i] *= ptot; }
|
||||
prob[nch-1] = 1.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -487,10 +290,11 @@ void G4FermiFragmentsPoolVI::DumpFragment(const G4FermiFragment* f) const
|
||||
if(f) {
|
||||
G4int prec = G4cout.precision(6);
|
||||
G4cout << " Z= " << f->GetZ() << " A= " << std::setw(2) << f->GetA()
|
||||
<< " Mass(GeV)= " << std::setw(8) << f->GetFragmentMass()/GeV
|
||||
<< " Eexc(MeV)= " << std::setw(7) << f->GetExcitationEnergy()
|
||||
<< " 2s= " << f->GetSpin() << " IsStable: " << f->IsStable()
|
||||
<< " IsPhys: " << f->IsPhysical() << G4endl;
|
||||
<< " Mass(GeV)= " << std::setw(8) << f->GetFragmentMass()/GeV
|
||||
<< " Eexc(MeV)= " << std::setw(7) << f->GetExcitationEnergy()
|
||||
<< " 2s= " << f->GetSpin() << " IsStable: "
|
||||
<< HasChannels(f->GetZ(), f->GetA(), f->GetExcitationEnergy())
|
||||
<< G4endl;
|
||||
G4cout.precision(prec);
|
||||
}
|
||||
}
|
||||
@@ -498,12 +302,12 @@ void G4FermiFragmentsPoolVI::DumpFragment(const G4FermiFragment* f) const
|
||||
void G4FermiFragmentsPoolVI::Dump() const
|
||||
{
|
||||
G4cout <<"----------------------------------------------------------------"
|
||||
<<G4endl;
|
||||
<<G4endl;
|
||||
G4cout << "##### List of Fragments in the Fermi Fragment Pool #####"
|
||||
<< G4endl;
|
||||
<< G4endl;
|
||||
G4int nfrag = fragment_pool.size();
|
||||
G4cout << " For stable " << nfrag << " Elim(MeV) = "
|
||||
<< elim/CLHEP::MeV << G4endl;
|
||||
<< elim/CLHEP::MeV << G4endl;
|
||||
for(G4int i=0; i<nfrag; ++i) {
|
||||
DumpFragment(fragment_pool[i]);
|
||||
}
|
||||
@@ -511,7 +315,7 @@ void G4FermiFragmentsPoolVI::Dump() const
|
||||
|
||||
|
||||
G4cout << "----------------------------------------------------------------"
|
||||
<< G4endl;
|
||||
<< G4endl;
|
||||
G4cout << "### G4FermiFragmentPoolVI: fragments sorted by A" << G4endl;
|
||||
|
||||
G4int prec = G4cout.precision(6);
|
||||
@@ -527,22 +331,22 @@ void G4FermiFragmentsPoolVI::Dump() const
|
||||
size_t nch = (list_c[A])[j]->GetNumberOfChannels();
|
||||
am = std::max(am, nch);
|
||||
G4cout << " ("<<a1<<","<<z1<<"); Eex(MeV)= "
|
||||
<< f->GetExcitationEnergy()
|
||||
<< " 2S= " << f->GetSpin()
|
||||
<< "; Nchannels= " << nch
|
||||
<< " MassExcess= " << f->GetTotalEnergy() -
|
||||
(z1*proton_mass_c2 + (a1 - z1)*neutron_mass_c2)
|
||||
<< G4endl;
|
||||
<< f->GetExcitationEnergy()
|
||||
<< " 2S= " << f->GetSpin()
|
||||
<< "; Nchannels= " << nch
|
||||
<< " MassExcess= " << f->GetTotalEnergy() -
|
||||
(z1*proton_mass_c2 + (a1 - z1)*neutron_mass_c2)
|
||||
<< G4endl;
|
||||
for(size_t k=0; k<nch; ++k) {
|
||||
const G4FermiPair* fpair = ((list_c[A])[j]->GetChannels())[k];
|
||||
G4cout << " (" << fpair->GetFragment1()->GetZ()
|
||||
<< ", " << fpair->GetFragment1()->GetA()
|
||||
<< ", " << fpair->GetFragment1()->GetExcitationEnergy()
|
||||
<< ") ("<< fpair->GetFragment2()->GetZ()
|
||||
<< ", " << std::setw(3)<< fpair->GetFragment2()->GetA()
|
||||
<< ", " << std::setw(8)<< fpair->GetFragment2()->GetExcitationEnergy()
|
||||
<< ") prob= " << ((list_c[A])[j]->GetProbabilities())[k]
|
||||
<< G4endl;
|
||||
<< ", " << fpair->GetFragment1()->GetA()
|
||||
<< ", " << fpair->GetFragment1()->GetExcitationEnergy()
|
||||
<< ") ("<< fpair->GetFragment2()->GetZ()
|
||||
<< ", " << std::setw(3)<< fpair->GetFragment2()->GetA()
|
||||
<< ", " << std::setw(8)<< fpair->GetFragment2()->GetExcitationEnergy()
|
||||
<< ") prob= " << ((list_c[A])[j]->GetProbabilities())[k]
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
ama[A] = am;
|
||||
@@ -563,57 +367,7 @@ void G4FermiFragmentsPoolVI::Dump() const
|
||||
G4cout << G4endl;
|
||||
|
||||
G4cout << "----------------------------------------------------------------"
|
||||
<< G4endl;
|
||||
|
||||
G4cout << "### G4FermiFragmentPoolVI: " << funstable.size()
|
||||
<< " unphysical fragments" << G4endl;
|
||||
G4cout << " Number of unphysical fragments per A:" << G4endl;
|
||||
for(G4int j=0; j<maxA; ++j) { G4cout << list_g[j].size() << ", "; }
|
||||
G4cout << G4endl;
|
||||
|
||||
G4cout << " Number of unphysical fragment pairs per A:" << G4endl;
|
||||
for(G4int j=0; j<maxA; ++j) { G4cout << list_u[j].size() << ", "; }
|
||||
G4cout << G4endl;
|
||||
|
||||
prec = G4cout.precision(6);
|
||||
for(G4int A=1; A<maxA; ++A) {
|
||||
G4cout << " # A= " << A << G4endl;
|
||||
size_t am(0);
|
||||
for(size_t j=0; j<list_g[A].size(); ++j) {
|
||||
const G4FermiFragment* f = (list_g[A])[j];
|
||||
G4int a1 = f->GetA();
|
||||
G4int z1 = f->GetZ();
|
||||
size_t nch = (list_d[A])[j]->GetNumberOfChannels();
|
||||
am = std::max(am, nch);
|
||||
G4cout << "("<<a1<<","<<z1<<"); Eex(MeV)= "
|
||||
<< std::setw(8) << f->GetExcitationEnergy()
|
||||
<< "; Nchannels= " << nch
|
||||
<< " MassExcess= " << f->GetTotalEnergy() -
|
||||
(z1*proton_mass_c2 + (a1 - z1)*neutron_mass_c2)
|
||||
<< G4endl;
|
||||
for(size_t k=0; k<nch; ++k) {
|
||||
const G4FermiPair* fpair = ((list_d[A])[j]->GetChannels())[k];
|
||||
G4cout << " (" << fpair->GetFragment1()->GetZ()
|
||||
<< ", " << fpair->GetFragment1()->GetA()
|
||||
<< ", " << std::setw(8)<< fpair->GetFragment1()->GetExcitationEnergy()
|
||||
<< ") ("<< fpair->GetFragment2()->GetZ()
|
||||
<< ", " << std::setw(3)<< fpair->GetFragment2()->GetA()
|
||||
<< ", " << std::setw(8)<< fpair->GetFragment2()->GetExcitationEnergy()
|
||||
<< ") prob= " << ((list_d[A])[j]->GetProbabilities())[k]
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
ama[A] = am;
|
||||
G4cout << G4endl;
|
||||
}
|
||||
G4cout.precision(prec);
|
||||
G4cout << G4endl;
|
||||
G4cout << " Max number of unphysical channels per A:" << G4endl;
|
||||
for (size_t j=0; j<maxA; ++j) { G4cout << ama[j] << ", "; }
|
||||
G4cout << G4endl;
|
||||
G4cout << "----------------------------------------------------------------"
|
||||
<< G4endl;
|
||||
G4cout << G4endl;
|
||||
<< G4endl;
|
||||
G4cout << "### Pairs of stable fragments: " << G4endl;
|
||||
|
||||
prec = G4cout.precision(6);
|
||||
@@ -627,37 +381,14 @@ void G4FermiFragmentsPoolVI::Dump() const
|
||||
G4int a2 = f2->GetA();
|
||||
G4int z2 = f2->GetZ();
|
||||
G4cout << "("<<a1<<","<<z1<<")("<<a2<<","<<z2<<") % Eex(MeV)= "
|
||||
<< std::setw(8)<< (list_p[A])[j]->GetExcitationEnergy()
|
||||
<< std::setw(8)<< (list_p[A])[j]->GetExcitationEnergy()
|
||||
<< " Eex1= " << std::setw(8)<< f1->GetExcitationEnergy()
|
||||
<< " Eex2= " << std::setw(8)<< f2->GetExcitationEnergy()
|
||||
<< G4endl;
|
||||
<< G4endl;
|
||||
}
|
||||
G4cout << G4endl;
|
||||
G4cout <<"----------------------------------------------------------------"
|
||||
<< G4endl;
|
||||
}
|
||||
G4cout.precision(prec);
|
||||
G4cout << "### Pairs of stable+unstable fragments: " << G4endl;
|
||||
|
||||
prec = G4cout.precision(6);
|
||||
for(G4int A=2; A<maxA; ++A) {
|
||||
G4cout << " A= " << A << G4endl;
|
||||
for(size_t j=0; j<list_u[A].size(); ++j) {
|
||||
const G4FermiFragment* f1 = (list_u[A])[j]->GetFragment1();
|
||||
const G4FermiFragment* f2 = (list_u[A])[j]->GetFragment2();
|
||||
G4int a1 = f1->GetA();
|
||||
G4int z1 = f1->GetZ();
|
||||
G4int a2 = f2->GetA();
|
||||
G4int z2 = f2->GetZ();
|
||||
G4cout << "("<<a1<<","<<z1<<")("<<a2<<","<<z2<<") % Eex(MeV)= "
|
||||
<< std::setw(8)<< (list_u[A])[j]->GetExcitationEnergy()
|
||||
<< " Eex1= " << std::setw(8)<< f1->GetExcitationEnergy()
|
||||
<< " Eex2= " << std::setw(8)<< f2->GetExcitationEnergy()
|
||||
<< G4endl;
|
||||
}
|
||||
G4cout << G4endl;
|
||||
G4cout << "----------------------------------------------------------------"
|
||||
<< G4endl;
|
||||
<< G4endl;
|
||||
}
|
||||
G4cout.precision(prec);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user