Import Geant4 10.6.0.beta source tree

This commit is contained in:
Gabriele Cosmo
2019-06-28 11:59:04 +02:00
parent 28a70706e0
commit d0f911957d
1056 changed files with 95168 additions and 78160 deletions
@@ -34,8 +34,6 @@
// Author: Vladimir Ivanchenko
//
// Creation date: 13.03.2007
// Modifications:
//
//
// -------------------------------------------------------------------
//
@@ -45,7 +43,6 @@
#include "G4ComponentGGHadronNucleusXsc.hh"
#include "G4NucleonNuclearCrossSection.hh"
#include "G4HadronNucleonXsc.hh"
#include "G4ComponentSAIDTotalXS.hh"
#include "G4Proton.hh"
#include "G4Neutron.hh"
#include "G4NistManager.hh"
@@ -54,29 +51,27 @@
#include "G4CrossSectionDataSetRegistry.hh"
G4double G4BGGNucleonElasticXS::theGlauberFac[93] = {0.0};
G4double G4BGGNucleonElasticXS::theCoulombFac[93] = {0.0};
G4int G4BGGNucleonElasticXS::theA[93] = {0};
#ifdef G4MULTITHREADED
G4Mutex G4BGGNucleonElasticXS::nucleonElasticXSMutex = G4MUTEX_INITIALIZER;
#endif
G4BGGNucleonElasticXS::G4BGGNucleonElasticXS(const G4ParticleDefinition* p)
: G4VCrossSectionDataSet("Barashenkov-Glauber")
: G4VCrossSectionDataSet("BarashenkovGlauberGribov")
{
verboseLevel = 0;
fGlauberEnergy = 91.*GeV;
fPDGEnergy = 5*GeV;
fLowEnergy = 14.*MeV;
fSAIDLowEnergyLimit = 1*MeV;
fSAIDHighEnergyLimit = 1.3*GeV;
fLowestXSection = millibarn;
for (G4int i = 0; i < 93; ++i) {
theGlauberFac[i] = 0.0;
theCoulombFac[i] = 0.0;
theA[i] = 1;
}
fLowEnergy = 0.75*MeV;
fNucleon = nullptr;
fGlauber = nullptr;
fHadron = nullptr;
fSAID = nullptr;
particle = p;
theProton= G4Proton::Proton();
isProton = (theProton == p) ? true : false;
isInitialized = false;
isMaster = false;
SetForAllAtomsAndEnergies(true);
}
@@ -149,14 +144,10 @@ G4BGGNucleonElasticXS::GetIsoCrossSection(const G4DynamicParticle* dp,
const G4Material*)
{
// this method should be called only for Z = 1
fHadron->HadronNucleonXscNS(dp->GetDefinition(), theProton,
dp->GetKineticEnergy());
G4double cross = A*fHadron->GetElasticHadronNucleonXsc();
G4double cross = 0.0;
if(1 == Z) {
G4double ekin = std::max(dp->GetKineticEnergy(), fLowEnergy);
fHadron->HadronNucleonXscNS(dp->GetDefinition(), theProton, ekin);
cross = fHadron->GetElasticHadronNucleonXsc();
}
cross *= A;
if(verboseLevel > 1) {
G4cout << "G4BGGNucleonElasticXS::GetIsoCrossSection for "
<< dp->GetDefinition()->GetParticleName()
@@ -174,62 +165,75 @@ void G4BGGNucleonElasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
{
if(&p == theProton || &p == G4Neutron::Neutron()) {
particle = &p;
isProton = (theProton == particle) ? true : false;
} else {
G4cout << "### G4BGGNucleonElasticXS WARNING: is not applicable to "
<< p.GetParticleName()
<< G4endl;
throw G4HadronicException(__FILE__, __LINE__,
"G4BGGNucleonElasticXS::BuildPhysicsTable is used for wrong particle");
G4ExceptionDescription ed;
ed << "This BGG cross section is applicable only to nucleons and not to "
<< p.GetParticleName() << G4endl;
G4Exception("G4BGGNucleonElasticXS::BuildPhysicsTable", "had001",
FatalException, ed);
return;
}
if(isInitialized) { return; }
isInitialized = true;
fNucleon = (G4NucleonNuclearCrossSection*)G4CrossSectionDataSetRegistry::Instance()->GetCrossSectionDataSet(G4NucleonNuclearCrossSection::Default_Name());
fGlauber = new G4ComponentGGHadronNucleusXsc();
fHadron = new G4HadronNucleonXsc();
if(!fNucleon) {
fNucleon = (G4NucleonNuclearCrossSection*)G4CrossSectionDataSetRegistry::Instance()->GetCrossSectionDataSet(G4NucleonNuclearCrossSection::Default_Name());
fGlauber = new G4ComponentGGHadronNucleusXsc();
fHadron = new G4HadronNucleonXsc();
}
fNucleon->BuildPhysicsTable(*particle);
fGlauber->BuildPhysicsTable(*particle);
G4ThreeVector mom(0.0,0.0,1.0);
G4DynamicParticle dp(particle, mom, fGlauberEnergy);
G4NistManager* nist = G4NistManager::Instance();
G4double csup, csdn;
G4int A;
if(verboseLevel > 0) {
G4cout << "### G4BGGNucleonElasticXS::Initialise for "
<< particle->GetParticleName() << G4endl;
if(0 == theA[0]) {
#ifdef G4MULTITHREADED
G4MUTEXLOCK(&nucleonElasticXSMutex);
if(0 == theA[0]) {
#endif
isMaster = true;
#ifdef G4MULTITHREADED
}
G4MUTEXUNLOCK(&nucleonElasticXSMutex);
#endif
}
for(G4int iz=2; iz<93; iz++) {
if(isMaster && 0 == theA[0]) {
A = G4lrint(nist->GetAtomicMassAmu(iz));
theA[iz] = A;
theA[0] = 1;
G4ThreeVector mom(0.0,0.0,1.0);
G4DynamicParticle dp(particle, mom, fGlauberEnergy);
csup = fGlauber->GetElasticGlauberGribov(&dp, iz, A);
csdn = fNucleon->GetElasticCrossSection(&dp, iz);
G4NistManager* nist = G4NistManager::Instance();
G4double csup, csdn;
theGlauberFac[iz] = csdn/csup;
if(verboseLevel > 0) {
G4cout << "Z= " << iz << " A= " << A
<< " factor= " << theGlauberFac[iz] << G4endl;
}
}
theCoulombFac[0] = theCoulombFac[1] = 1.0;
dp.SetKineticEnergy(fLowEnergy);
for(G4int iz=2; iz<93; iz++) {
theCoulombFac[iz] =
fNucleon->GetElasticCrossSection(&dp, iz)/CoulombFactor(fLowEnergy, iz);
if(verboseLevel > 0) {
G4cout << "Z= " << iz << " A= " << theA[iz]
<< " factor= " << theCoulombFac[iz] << G4endl;
G4cout << "### G4BGGNucleonElasticXS::Initialise for "
<< particle->GetParticleName() << G4endl;
}
for(G4int iz=2; iz<93; iz++) {
G4int A = G4lrint(nist->GetAtomicMassAmu(iz));
theA[iz] = A;
csup = fGlauber->GetElasticGlauberGribov(&dp, iz, A);
csdn = fNucleon->GetElasticCrossSection(&dp, iz);
theGlauberFac[iz] = csdn/csup;
if(verboseLevel > 0) {
G4cout << "Z= " << iz << " A= " << A
<< " factor= " << theGlauberFac[iz] << G4endl;
}
}
theCoulombFac[0] = theCoulombFac[1] = 1.0;
dp.SetKineticEnergy(fLowEnergy);
for(G4int iz=2; iz<93; ++iz) {
theCoulombFac[iz] =
fNucleon->GetElasticCrossSection(&dp, iz)/CoulombFactor(fLowEnergy, iz);
if(verboseLevel > 0) {
G4cout << "Z= " << iz << " A= " << theA[iz]
<< " factor= " << theCoulombFac[iz] << G4endl;
}
}
}
}
@@ -61,29 +61,30 @@
const G4double llog10 = G4Log(10.);
G4double G4BGGNucleonInelasticXS::theGlauberFac[93] = {0.0};
G4double G4BGGNucleonInelasticXS::theCoulombFac[93] = {0.0};
G4int G4BGGNucleonInelasticXS::theA[93] = {0};
#ifdef G4MULTITHREADED
G4Mutex G4BGGNucleonInelasticXS::nucleonInelasticXSMutex = G4MUTEX_INITIALIZER;
#endif
G4BGGNucleonInelasticXS::G4BGGNucleonInelasticXS(const G4ParticleDefinition* p)
: G4VCrossSectionDataSet("Barashenkov-Glauber")
: G4VCrossSectionDataSet("BarashenkovGlauberGribov")
{
verboseLevel = 0;
fGlauberEnergy = 91.*GeV;
fLowEnergy = 14.*MeV;
fHighEnergy = 5.*GeV;
fSAIDHighEnergyLimit = 1.3*GeV;
fLowestXSection = millibarn;
for (G4int i = 0; i < 93; ++i) {
theGlauberFac[i] = 0.0;
theCoulombFac[i] = 0.0;
theA[i] = 1;
}
fNucleon = nullptr;
fGlauber = nullptr;
fHadron = nullptr;
fSAID = nullptr;
particle = p;
theProton= G4Proton::Proton();
isProton = (theProton == p) ? true : false;
isInitialized = false;
isMaster = false;
SetForAllAtomsAndEnergies(true);
}
@@ -160,13 +161,10 @@ G4BGGNucleonInelasticXS::GetIsoCrossSection(const G4DynamicParticle* dp,
const G4Material*)
{
// this method should be called only for Z = 1
fHadron->HadronNucleonXscNS(dp->GetDefinition(), theProton,
dp->GetKineticEnergy());
G4double cross = A*fHadron->GetInelasticHadronNucleonXsc();
G4double cross = 0.0;
if(1 == Z) {
fHadron->GetHadronNucleonXscNS(dp, theProton);
cross = fHadron->GetInelasticHadronNucleonXsc();
}
cross *= A;
if(verboseLevel > 1) {
G4cout << "G4BGGNucleonInelasticXS::GetIsoCrossSection for "
<< dp->GetDefinition()->GetParticleName()
@@ -184,60 +182,74 @@ void G4BGGNucleonInelasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
{
if(&p == theProton || &p == G4Neutron::Neutron()) {
particle = &p;
isProton = (theProton == particle) ? true : false;
} else {
G4cout << "### G4BGGNucleonInelasticXS WARNING: is not applicable to "
<< p.GetParticleName()
<< G4endl;
throw G4HadronicException(__FILE__, __LINE__,
"G4BGGNucleonElasticXS::BuildPhysicsTable is used for wrong particle");
G4ExceptionDescription ed;
ed << "This BGG cross section is applicable only to nucleons and not to "
<< p.GetParticleName() << G4endl;
G4Exception("G4BGGNucleonInelasticXS::BuildPhysicsTable", "had001",
FatalException, ed);
return;
}
if(isInitialized) { return; }
isInitialized = true;
fNucleon = (G4NucleonNuclearCrossSection*)G4CrossSectionDataSetRegistry::Instance()->GetCrossSectionDataSet(G4NucleonNuclearCrossSection::Default_Name());
fGlauber = new G4ComponentGGHadronNucleusXsc();
fHadron = new G4HadronNucleonXsc();
if(!fNucleon) {
fNucleon = (G4NucleonNuclearCrossSection*)G4CrossSectionDataSetRegistry::Instance()->GetCrossSectionDataSet(G4NucleonNuclearCrossSection::Default_Name());
fGlauber = new G4ComponentGGHadronNucleusXsc();
fHadron = new G4HadronNucleonXsc();
}
fNucleon->BuildPhysicsTable(*particle);
fGlauber->BuildPhysicsTable(*particle);
G4ThreeVector mom(0.0,0.0,1.0);
G4DynamicParticle dp(particle, mom, fGlauberEnergy);
G4NistManager* nist = G4NistManager::Instance();
G4int A;
G4double csup, csdn;
if(verboseLevel > 0) {
G4cout << "### G4BGGNucleonInelasticXS::Initialise for "
<< particle->GetParticleName() << G4endl;
}
for(G4int iz=2; iz<93; iz++) {
A = G4lrint(nist->GetAtomicMassAmu(iz));
theA[iz] = A;
csup = fGlauber->GetInelasticGlauberGribov(&dp, iz, A);
csdn = fNucleon->GetElementCrossSection(&dp, iz);
theGlauberFac[iz] = csdn/csup;
if(verboseLevel > 0) {
G4cout << "Z= " << iz << " A= " << A
<< " GlauberFactor= " << theGlauberFac[iz] << G4endl;
if(0 == theA[0]) {
#ifdef G4MULTITHREADED
G4MUTEXLOCK(&nucleonInelasticXSMutex);
if(0 == theA[0]) {
#endif
isMaster = true;
#ifdef G4MULTITHREADED
}
G4MUTEXUNLOCK(&nucleonInelasticXSMutex);
#endif
}
theCoulombFac[1] = theCoulombFac[2] = 1.0;
dp.SetKineticEnergy(fLowEnergy);
for(G4int iz=3; iz<93; ++iz) {
theCoulombFac[iz] =
fNucleon->GetElementCrossSection(&dp, iz)/CoulombFactor(fLowEnergy, iz);
if(isMaster && 0 == theA[0]) {
theA[0] = 1;
G4ThreeVector mom(0.0,0.0,1.0);
G4DynamicParticle dp(particle, mom, fGlauberEnergy);
G4NistManager* nist = G4NistManager::Instance();
G4double csup, csdn;
if(verboseLevel > 0) {
G4cout << "Z= " << iz << " A= " << theA[iz]
<< " CoulombFactor= " << theCoulombFac[iz] << G4endl;
G4cout << "### G4BGGNucleonInelasticXS::Initialise for "
<< particle->GetParticleName() << G4endl;
}
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);
theGlauberFac[iz] = csdn/csup;
if(verboseLevel > 0) {
G4cout << "Z= " << iz << " A= " << A
<< " GlauberFactor= " << theGlauberFac[iz] << G4endl;
}
}
theCoulombFac[1] = 1.0;
dp.SetKineticEnergy(fLowEnergy);
for(G4int iz=2; iz<93; ++iz) {
theCoulombFac[iz] =
fNucleon->GetElementCrossSection(&dp, iz)/CoulombFactor(fLowEnergy, iz);
if(verboseLevel > 0) {
G4cout << "Z= " << iz << " A= " << theA[iz]
<< " CoulombFactor= " << theCoulombFac[iz] << G4endl;
}
}
}
}
@@ -44,38 +44,40 @@
#include "G4ComponentGGHadronNucleusXsc.hh"
#include "G4UPiNuclearCrossSection.hh"
#include "G4HadronNucleonXsc.hh"
#include "G4ComponentSAIDTotalXS.hh"
#include "G4Proton.hh"
#include "G4PionPlus.hh"
#include "G4PionMinus.hh"
#include "G4NistManager.hh"
#include "G4HadronicParameters.hh"
G4double G4BGGPionElasticXS::theGlauberFacPiPlus[93] = {0.0};
G4double G4BGGPionElasticXS::theCoulombFacPiPlus[93] = {0.0};
G4double G4BGGPionElasticXS::theGlauberFacPiMinus[93] = {0.0};
G4double G4BGGPionElasticXS::theCoulombFacPiMinus[93] = {0.0};
G4int G4BGGPionElasticXS::theA[93] = {0};
#ifdef G4MULTITHREADED
G4Mutex G4BGGPionElasticXS::pionElasticXSMutex = G4MUTEX_INITIALIZER;
#endif
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4BGGPionElasticXS::G4BGGPionElasticXS(const G4ParticleDefinition* p)
: G4VCrossSectionDataSet("Barashenkov-Glauber")
: G4VCrossSectionDataSet("BarashenkovGlauberGribov")
{
verboseLevel = 0;
fGlauberEnergy = 91.*GeV;
fLowEnergy = 20.*MeV;
fSAIDHighEnergyLimit = 2.6*GeV;
fLowEnergy = 1.*MeV;
SetMinKinEnergy(0.0);
SetMaxKinEnergy( G4HadronicParameters::Instance()->GetMaxEnergy() );
for (G4int i = 0; i < 93; i++) {
theGlauberFac[i] = 0.0;
theCoulombFac[i] = 0.0;
theA[i] = 1;
}
fPion = nullptr;
fGlauber = nullptr;
fHadron = nullptr;
fSAID = nullptr;
particle = p;
theProton= G4Proton::Proton();
isPiplus = (p == G4PionPlus::PionPlus()) ? true : false;
isInitialized = false;
isMaster = false;
SetForAllAtomsAndEnergies(true);
}
@@ -119,9 +121,10 @@ G4BGGPionElasticXS::GetElementCrossSection(const G4DynamicParticle* dp,
cross = 1.0115*GetIsoCrossSection(dp,1,1);
} else {
if(ekin <= fLowEnergy) {
cross = theCoulombFac[Z];
cross = (isPiplus) ? theCoulombFacPiPlus[Z] : theCoulombFacPiMinus[Z];
} else if(ekin > fGlauberEnergy) {
cross = theGlauberFac[Z]*fGlauber->GetElasticGlauberGribov(dp, Z, theA[Z]);
cross = (isPiplus) ? theGlauberFacPiPlus[Z] : theGlauberFacPiMinus[Z];
cross *= fGlauber->GetElasticGlauberGribov(dp, Z, theA[Z]);
} else {
cross = fPion->GetElasticCrossSection(dp, Z, theA[Z]);
}
@@ -145,13 +148,10 @@ G4BGGPionElasticXS::GetIsoCrossSection(const G4DynamicParticle* dp,
const G4Material*)
{
// this method should be called only for Z = 1
G4double cross = 0.0;
if(1 == Z) {
G4double ekin = std::max(dp->GetKineticEnergy(), fLowEnergy);
fHadron->HadronNucleonXscNS(dp->GetDefinition(), theProton, ekin);
cross = fHadron->GetElasticHadronNucleonXsc();
}
cross *= A;
fHadron->HadronNucleonXscNS(dp->GetDefinition(), theProton,
dp->GetKineticEnergy());
G4double cross = A*fHadron->GetElasticHadronNucleonXsc();
if(verboseLevel > 1) {
G4cout << "G4BGGPionElasticXS::GetIsoCrossSection for "
<< dp->GetDefinition()->GetParticleName()
@@ -169,52 +169,83 @@ void G4BGGPionElasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
{
if(&p == G4PionPlus::PionPlus() || &p == G4PionMinus::PionMinus()) {
particle = &p;
isPiplus = (particle == G4PionPlus::PionPlus()) ? true : false;
} else {
G4cout << "### G4BGGPionElasticXS WARNING: is not applicable to "
<< p.GetParticleName()
<< G4endl;
throw G4HadronicException(__FILE__, __LINE__,
"G4BGGPionElasticXS::BuildPhysicsTable is used for wrong particle");
G4ExceptionDescription ed;
ed << "This BGG cross section is applicable only to pions and not to "
<< p.GetParticleName() << G4endl;
G4Exception("G4BGGPionElasticXS::BuildPhysicsTable", "had001",
FatalException, ed);
return;
}
if(isInitialized) { return; }
isInitialized = true;
fPion = new G4UPiNuclearCrossSection();
fGlauber = new G4ComponentGGHadronNucleusXsc();
fHadron = new G4HadronNucleonXsc();
if(!fPion) {
fPion = new G4UPiNuclearCrossSection();
fGlauber = new G4ComponentGGHadronNucleusXsc();
fHadron = new G4HadronNucleonXsc();
}
fPion->BuildPhysicsTable(*particle);
fGlauber->BuildPhysicsTable(*particle);
G4ThreeVector mom(0.0,0.0,1.0);
G4DynamicParticle dp(particle, mom, fGlauberEnergy);
G4NistManager* nist = G4NistManager::Instance();
G4double csup, csdn;
for(G4int iz=2; iz<93; iz++) {
G4int A = G4lrint(nist->GetAtomicMassAmu(iz));
theA[iz] = A;
csup = fGlauber->GetElasticGlauberGribov(&dp, iz, A);
csdn = fPion->GetElasticCrossSection(&dp, iz, A);
theGlauberFac[iz] = csdn/csup;
if(verboseLevel > 0) {
G4cout << "Z= " << iz << " A= " << A
<< " factor= " << theGlauberFac[iz] << G4endl;
if(0 == theA[0]) {
#ifdef G4MULTITHREADED
G4MUTEXLOCK(&pionElasticXSMutex);
if(0 == theA[0]) {
#endif
isMaster = true;
#ifdef G4MULTITHREADED
}
G4MUTEXUNLOCK(&pionElasticXSMutex);
#endif
}
theCoulombFac[1] = 1.0;
dp.SetKineticEnergy(fLowEnergy);
for(G4int iz=2; iz<93; iz++) {
theCoulombFac[iz] = fPion->GetElasticCrossSection(&dp, iz, theA[iz]);
if(verboseLevel > 0) {
G4cout << "Z= " << iz << " A= " << theA[iz]
<< " CoulombFactor= " << theCoulombFac[iz] << G4endl;
if(isMaster && 0 == theA[0]) {
theA[0] = 1;
G4ThreeVector mom(0.0,0.0,1.0);
G4DynamicParticle dp(particle, mom, fGlauberEnergy);
G4NistManager* nist = G4NistManager::Instance();
G4double csup, csdn;
for(G4int iz=2; iz<93; ++iz) {
G4int A = G4lrint(nist->GetAtomicMassAmu(iz));
theA[iz] = A;
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);
theGlauberFacPiMinus[iz] = csdn/csup;
if(verboseLevel > 0) {
G4cout << "Z= " << iz << " A= " << A
<< " factorPiPlus= " << theGlauberFacPiPlus[iz]
<< " factorPiMinus= " << theGlauberFacPiMinus[iz]
<< G4endl;
}
}
theCoulombFacPiPlus[1] = 1.0;
theCoulombFacPiMinus[1]= 1.0;
dp.SetKineticEnergy(fLowEnergy);
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]);
if(verboseLevel > 0) {
G4cout << "Z= " << iz << " A= " << theA[iz]
<< " CoulombFactorPiPlus= " << theCoulombFacPiPlus[iz]
<< " CoulombFactorPiMinus= " << theCoulombFacPiMinus[iz]
<< G4endl;
}
}
}
}
@@ -44,7 +44,6 @@
#include "G4ComponentGGHadronNucleusXsc.hh"
#include "G4UPiNuclearCrossSection.hh"
#include "G4HadronNucleonXsc.hh"
#include "G4ComponentSAIDTotalXS.hh"
#include "G4Proton.hh"
#include "G4PionPlus.hh"
@@ -54,32 +53,35 @@
#include "G4HadronicParameters.hh"
G4double G4BGGPionInelasticXS::theGlauberFacPiPlus[93] = {0.0};
G4double G4BGGPionInelasticXS::theGlauberFacPiMinus[93] = {0.0};
G4double G4BGGPionInelasticXS::theLowEPiPlus[93] = {0.0};
G4double G4BGGPionInelasticXS::theLowEPiMinus[93] = {0.0};
G4int G4BGGPionInelasticXS::theA[93] = {0};
#ifdef G4MULTITHREADED
G4Mutex G4BGGPionInelasticXS::pionInelasticXSMutex = G4MUTEX_INITIALIZER;
#endif
G4BGGPionInelasticXS::G4BGGPionInelasticXS(const G4ParticleDefinition* p)
: G4VCrossSectionDataSet("Barashenkov-Glauber-Gribov")
: G4VCrossSectionDataSet("BarashenkovGlauberGribov")
{
verboseLevel = 0;
fGlauberEnergy = 91.*GeV;
fLowEnergy = 20.*MeV;
fSAIDHighEnergyLimit = 2.6*GeV;
SetMinKinEnergy(0.0);
SetMaxKinEnergy( G4HadronicParameters::Instance()->GetMaxEnergy() );
for (G4int i = 0; i < 93; i++) {
theGlauberFac[i] = 0.0;
theCoulombFac[i] = 0.0;
theA[i] = 1;
}
fPion = nullptr;
fGlauber = nullptr;
fHadron = nullptr;
fSAID = nullptr;
fG4pow = G4Pow::GetInstance();
particle = p;
theProton= G4Proton::Proton();
isPiplus = (p == G4PionPlus::PionPlus()) ? true : false;
isInitialized = false;
isMaster = false;
SetForAllAtomsAndEnergies(true);
}
@@ -120,18 +122,17 @@ G4BGGPionInelasticXS::GetElementCrossSection(const G4DynamicParticle* dp,
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(ekin <= fLowEnergy) {
cross = (isPiplus) ? theLowEPiPlus[Z]*CoulombFactor(ekin, Z)
: theLowEPiMinus[Z];
} else if(ekin > fGlauberEnergy) {
cross = (isPiplus) ? theGlauberFacPiPlus[Z] : theGlauberFacPiMinus[Z];
cross *= fGlauber->GetInelasticGlauberGribov(dp, Z, theA[Z]);
} else {
if(ekin <= fLowEnergy && !isPiplus) {
cross = theCoulombFac[Z];
} else if(ekin <= 2*MeV && isPiplus) {
cross = theCoulombFac[Z]*CoulombFactor(ekin, Z);
} else if(ekin > fGlauberEnergy) {
cross = theGlauberFac[Z]*fGlauber->GetInelasticGlauberGribov(dp, Z, theA[Z]);
} else {
cross = fPion->GetInelasticCrossSection(dp, Z, theA[Z]);
}
cross = fPion->GetInelasticCrossSection(dp, Z, theA[Z]);
}
if(verboseLevel > 1) {
G4cout << "G4BGGPionInelasticXS::GetCrossSection for "
@@ -154,13 +155,9 @@ G4BGGPionInelasticXS::GetIsoCrossSection(const G4DynamicParticle* dp,
const G4Material*)
{
// this method should be called only for Z = 1
G4double cross = 0.0;
if(1 == Z) {
fHadron->GetHadronNucleonXscNS(dp, theProton);
cross = fHadron->GetInelasticHadronNucleonXsc();
}
cross *= A;
fHadron->HadronNucleonXscNS(dp->GetDefinition(), theProton,
dp->GetKineticEnergy());
G4double cross = A*fHadron->GetInelasticHadronNucleonXsc();
if(verboseLevel > 1) {
G4cout << "G4BGGPionInelasticXS::GetCrossSection for "
@@ -179,66 +176,92 @@ void G4BGGPionInelasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
{
if(&p == G4PionPlus::PionPlus() || &p == G4PionMinus::PionMinus()) {
particle = &p;
isPiplus = (particle == G4PionPlus::PionPlus()) ? true : false;
} else {
G4cout << "### G4BGGPionInelasticXS WARNING: is not applicable to "
<< p.GetParticleName()
<< G4endl;
throw G4HadronicException(__FILE__, __LINE__,
"G4BGGPionInelasticXS::BuildPhysicsTable is used for wrong particle");
G4ExceptionDescription ed;
ed << "This BGG cross section is applicable only to pions and not to "
<< p.GetParticleName() << G4endl;
G4Exception("G4BGGPionInelasticXS::BuildPhysicsTable", "had001",
FatalException, ed);
return;
}
if(isInitialized) { return; }
isInitialized = true;
fPion = new G4UPiNuclearCrossSection();
fGlauber = new G4ComponentGGHadronNucleusXsc();
fHadron = new G4HadronNucleonXsc();
if(!fPion) {
fPion = new G4UPiNuclearCrossSection();
fGlauber = new G4ComponentGGHadronNucleusXsc();
fHadron = new G4HadronNucleonXsc();
}
fPion->BuildPhysicsTable(*particle);
fGlauber->BuildPhysicsTable(*particle);
G4ThreeVector mom(0.0,0.0,1.0);
G4DynamicParticle dp(particle, mom, fGlauberEnergy);
G4NistManager* nist = G4NistManager::Instance();
G4double csup, csdn;
if(verboseLevel > 0) {
G4cout << "### G4BGGPionInelasticXS::Initialise for "
<< particle->GetParticleName()
<< " isPiplus: " << isPiplus
<< G4endl;
if(0 == theA[0]) {
#ifdef G4MULTITHREADED
G4MUTEXLOCK(&pionInelasticXSMutex);
if(0 == theA[0]) {
#endif
isMaster = true;
#ifdef G4MULTITHREADED
}
G4MUTEXUNLOCK(&pionInelasticXSMutex);
#endif
}
for(G4int iz=2; iz<93; ++iz) {
G4int A = G4lrint(nist->GetAtomicMassAmu(iz));
theA[iz] = A;
if(isMaster && 0 == theA[0]) {
csup = fGlauber->GetInelasticGlauberGribov(&dp, iz, A);
csdn = fPion->GetInelasticCrossSection(&dp, iz, A);
theA[0] = 1;
theA[1] = 1;
G4ThreeVector mom(0.0,0.0,1.0);
G4DynamicParticle dp(particle, mom, fGlauberEnergy);
G4NistManager* nist = G4NistManager::Instance();
G4double csup, csdn;
theGlauberFac[iz] = csdn/csup;
if(verboseLevel > 0) {
G4cout << "Z= " << iz << " A= " << A
<< " factor= " << theGlauberFac[iz] << G4endl;
G4cout << "### G4BGGPionInelasticXS::Initialise for "
<< particle->GetParticleName()
<< " isPiplus: " << isPiplus
<< G4endl;
}
}
theCoulombFac[1] = 1.0;
G4double elim = (isPiplus) ? 2*MeV : fLowEnergy;
dp.SetKineticEnergy(elim);
for(G4int iz=2; iz<93; ++iz) {
if(isPiplus) {
theCoulombFac[iz] = fPion->GetInelasticCrossSection(&dp, iz, theA[iz])
/CoulombFactor(elim, iz);
} else {
theCoulombFac[iz] = fPion->GetInelasticCrossSection(&dp, iz, theA[iz]);
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);
theGlauberFacPiMinus[iz] = csdn/csup;
if(verboseLevel > 0) {
G4cout << "Z= " << iz << " A= " << A
<< " factorPiPlus= " << theGlauberFacPiPlus[iz]
<< " factorPiMinus= " << theGlauberFacPiMinus[iz]
<< G4endl;
}
}
if(verboseLevel > 0) {
G4cout << "Z= " << iz << " A= " << theA[iz]
<< " CoulombFactor= " << theCoulombFac[iz] << G4endl;
theLowEPiPlus[1] = 1.0;
theLowEPiMinus[1]= 1.0;
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]);
if(verboseLevel > 0) {
G4cout << "Z= " << iz << " A= " << theA[iz]
<< " LowEtorPiPlus= " << theLowEPiPlus[iz]
<< " LowEtorPiMinus= " << theLowEPiMinus[iz]
<< G4endl;
}
}
}
}
@@ -43,249 +43,221 @@
#include "G4ParticleDefinition.hh"
#include "G4Pow.hh"
///////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
G4ComponentAntiNuclNuclearXS::G4ComponentAntiNuclNuclearXS()
: G4VComponentCrossSection("AntiAGlauber"),
// fUpperLimit(10000*GeV), fLowerLimit(10*MeV),
fRadiusEff(0.0), fRadiusNN2(0.0),
fTotalXsc(0.0), fElasticXsc(0.0), fInelasticXsc(0.0),
fAntiHadronNucleonTotXsc(0.0), fAntiHadronNucleonElXsc(0.0),
Elab(0.0), S(0.0), SqrtS(0)
{
theAProton = G4AntiProton::AntiProton();
theANeutron = G4AntiNeutron::AntiNeutron();
theADeuteron = G4AntiDeuteron::AntiDeuteron();
theATriton = G4AntiTriton::AntiTriton();
theAAlpha = G4AntiAlpha::AntiAlpha();
theAHe3 = G4AntiHe3::AntiHe3();
Mn = 0.93827231; // GeV
b0 = 11.92; // GeV^(-2)
b2 = 0.3036; // GeV^(-2)
SqrtS0 = 20.74; // GeV
S0 = 33.0625; // GeV^2
R0 = 1.0; // default value (V.Ivanchenko)
theAProton = G4AntiProton::AntiProton();
theANeutron = G4AntiNeutron::AntiNeutron();
theADeuteron = G4AntiDeuteron::AntiDeuteron();
theATriton = G4AntiTriton::AntiTriton();
theAAlpha = G4AntiAlpha::AntiAlpha();
theAHe3 = G4AntiHe3::AntiHe3();
Mn = 0.93827231; // GeV
b0 = 11.92; // GeV^(-2)
b2 = 0.3036; // GeV^(-2)
SqrtS0 = 20.74; // GeV
S0 = 33.0625; // GeV^2
R0 = 1.0; // default value (V.Ivanchenko)
}
///////////////////////////////////////////////////////////////////////////////////////
//
//
/////////////////////////////////////////////////////////////////////////////
G4ComponentAntiNuclNuclearXS::~G4ComponentAntiNuclNuclearXS()
{
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//
// Calculation of total CrossSection of Anti-Nucleus - Nucleus
G4double G4ComponentAntiNuclNuclearXS::GetTotalElementCrossSection
(const G4ParticleDefinition* aParticle, G4double kinEnergy, G4int Z, G4double A)
{
G4double xsection, sigmaTotal, sigmaElastic;
G4double xsection, sigmaTotal, sigmaElastic;
const G4ParticleDefinition* theParticle = aParticle;
sigmaTotal = GetAntiHadronNucleonTotCrSc(theParticle,kinEnergy);
sigmaElastic = GetAntiHadronNucleonElCrSc(theParticle,kinEnergy);
const G4ParticleDefinition* theParticle = aParticle;
sigmaTotal = GetAntiHadronNucleonTotCrSc(theParticle,kinEnergy);
sigmaElastic = GetAntiHadronNucleonElCrSc(theParticle,kinEnergy);
// calculation of squared radius of NN-collision
fRadiusNN2=sigmaTotal*sigmaTotal*0.1/(8.*sigmaElastic*pi) ; //fm^2
// calculation of effective nuclear radius for Pbar and Nbar interactions (can be changed)
// calculation of squared radius of NN-collision
fRadiusNN2=sigmaTotal*sigmaTotal*0.1/(8.*sigmaElastic*pi) ; //fm^2
// calculation of effective nuclear radius for Pbar and Nbar interactions (can be changed)
//A.R. 29-Jan-2013 : use antiprotons/antineutrons as the default case,
// to be used for instance, as first approximation
// without validation, for anti-hyperons.
//if ( (theParticle == theAProton) || (theParticle == theANeutron) ) {
if(A==1)
{ fTotalXsc = sigmaTotal * millibarn;
return fTotalXsc; }
fRadiusEff = 1.34*G4Pow::GetInstance()->powA(A,0.23)+1.35/G4Pow::GetInstance()->powA(A,1./3.); //fm
if( (Z==1) && (A==2) ) fRadiusEff = 3.800; //fm
if( (Z==1) && (A==3) ) fRadiusEff = 3.300;
if( (Z==2) && (A==3) ) fRadiusEff = 3.300;
if( (Z==2) && (A==4) ) fRadiusEff = 2.376;
//}
//calculation of effective nuclear radius for AntiDeuteron interaction (can be changed)
if (theParticle == theADeuteron)
{ fRadiusEff = 1.46 * G4Pow::GetInstance()->powA(A,0.21) + 1.45 / G4Pow::GetInstance()->powA(A,1./3.);
if( (Z==1) && (A==2) ) fRadiusEff = 3.238; //fm
if( (Z==1) && (A==3) ) fRadiusEff = 3.144;
if( (Z==2) && (A==3) ) fRadiusEff = 3.144;
if( (Z==2) && (A==4) ) fRadiusEff = 2.544;
}
// calculation of effective nuclear radius for AntiHe3 interaction (can be changed)
if( (theParticle ==theAHe3) || (theParticle ==theATriton) )
{ fRadiusEff = 1.40* G4Pow::GetInstance()->powA(A,0.21)+1.63/G4Pow::GetInstance()->powA(A,1./3.);
if( (Z==1) && (A==2) ) fRadiusEff = 3.144; //fm
if( (Z==1) && (A==3) ) fRadiusEff = 3.075;
if( (Z==2) && (A==3) ) fRadiusEff = 3.075;
if( (Z==2) && (A==4) ) fRadiusEff = 2.589;
if (A==1) {
fTotalXsc = sigmaTotal * millibarn;
return fTotalXsc;
}
fRadiusEff = 1.34*G4Pow::GetInstance()->powA(A,0.23)+1.35/G4Pow::GetInstance()->powA(A,1./3.); //fm
if ( (Z==1) && (A==2) ) fRadiusEff = 3.800; //fm
if ( (Z==1) && (A==3) ) fRadiusEff = 3.300;
if ( (Z==2) && (A==3) ) fRadiusEff = 3.300;
if ( (Z==2) && (A==4) ) fRadiusEff = 2.376;
// calculation of effective nuclear radius for AntiDeuteron interaction (can be changed)
if (theParticle == theADeuteron) {
fRadiusEff = 1.46 * G4Pow::GetInstance()->powA(A,0.21) + 1.45 / G4Pow::GetInstance()->powA(A,1./3.);
if ( (Z==1) && (A==2) ) fRadiusEff = 3.238; //fm
if ( (Z==1) && (A==3) ) fRadiusEff = 3.144;
if ( (Z==2) && (A==3) ) fRadiusEff = 3.144;
if ( (Z==2) && (A==4) ) fRadiusEff = 2.544;
}
//calculation of effective nuclear radius for AntiAlpha interaction (can be changed)
// calculation of effective nuclear radius for AntiHe3 interaction (can be changed)
if ( (theParticle ==theAHe3) || (theParticle ==theATriton) ) {
fRadiusEff = 1.40* G4Pow::GetInstance()->powA(A,0.21)+1.63/G4Pow::GetInstance()->powA(A,1./3.);
if ( (Z==1) && (A==2) ) fRadiusEff = 3.144; //fm
if ( (Z==1) && (A==3) ) fRadiusEff = 3.075;
if ( (Z==2) && (A==3) ) fRadiusEff = 3.075;
if ( (Z==2) && (A==4) ) fRadiusEff = 2.589;
}
if (theParticle == theAAlpha)
{
fRadiusEff = 1.35* G4Pow::GetInstance()->powA(A,0.21)+1.1/G4Pow::GetInstance()->powA(A,1./3.);
if( (Z==1) && (A==2) ) fRadiusEff = 2.544; //fm
if( (Z==1) && (A==3) ) fRadiusEff = 2.589;
if( (Z==2) && (A==3) ) fRadiusEff = 2.589;
if( (Z==2) && (A==4) ) fRadiusEff = 2.241;
}
// calculation of effective nuclear radius for AntiAlpha interaction (can be changed)
if (theParticle == theAAlpha) {
fRadiusEff = 1.35* G4Pow::GetInstance()->powA(A,0.21)+1.1/G4Pow::GetInstance()->powA(A,1./3.);
if ( (Z==1) && (A==2) ) fRadiusEff = 2.544; //fm
if ( (Z==1) && (A==3) ) fRadiusEff = 2.589;
if ( (Z==2) && (A==3) ) fRadiusEff = 2.589;
if ( (Z==2) && (A==4) ) fRadiusEff = 2.241;
}
G4double R2 = fRadiusEff*fRadiusEff;
G4double REf2 = R2+fRadiusNN2;
G4double ApAt = std::abs(theParticle->GetBaryonNumber()) * A;
G4double R2 = fRadiusEff*fRadiusEff;
G4double REf2 = R2+fRadiusNN2;
G4double ApAt = std::abs(theParticle->GetBaryonNumber()) * A;
xsection = 2*pi*REf2*10.*G4Log(1+(ApAt*sigmaTotal/(2*pi*REf2*10.))); //mb
xsection =xsection *millibarn;
fTotalXsc = xsection;
xsection = 2*pi*REf2*10.*G4Log(1+(ApAt*sigmaTotal/(2*pi*REf2*10.))); //mb
xsection = xsection *millibarn;
fTotalXsc = xsection;
return fTotalXsc;
}
////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//
// Calculation of total CrossSection of Anti-Nucleus - Nucleus
//////////////////////////////////////////////////////////////////////////////
G4double G4ComponentAntiNuclNuclearXS::GetTotalIsotopeCrossSection
(const G4ParticleDefinition* aParticle, G4double kinEnergy, G4int Z, G4int A )
{ return GetTotalElementCrossSection(aParticle, kinEnergy, Z, (G4double) A); }
{
return GetTotalElementCrossSection(aParticle, kinEnergy, Z, (G4double) A);
}
////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Calculation of inelastic CrossSection of Anti-Nucleus - Nucleus
////////////////////////////////////////////////////////////////
G4double G4ComponentAntiNuclNuclearXS::GetInelasticElementCrossSection
(const G4ParticleDefinition* aParticle, G4double kinEnergy, G4int Z, G4double A)
{
G4double inelxsection, sigmaTotal, sigmaElastic;
const G4ParticleDefinition* theParticle = aParticle;
sigmaTotal = GetAntiHadronNucleonTotCrSc(theParticle,kinEnergy);
sigmaElastic = GetAntiHadronNucleonElCrSc(theParticle,kinEnergy);
sigmaTotal = GetAntiHadronNucleonTotCrSc(theParticle,kinEnergy);
sigmaElastic = GetAntiHadronNucleonElCrSc(theParticle,kinEnergy);
// calculation of sqr of radius NN-collision
fRadiusNN2=sigmaTotal*sigmaTotal*0.1/(8.*sigmaElastic*pi); // fm^2
// calculation of effective nuclear radius for Pbar and Nbar interaction (can be changed)
// calculation of sqr of radius NN-collision
fRadiusNN2=sigmaTotal*sigmaTotal*0.1/(8.*sigmaElastic*pi); // fm^2
// calculation of effective nuclear radius for Pbar and Nbar interaction (can be changed)
//A.R. 29-Jan-2013 : use antiprotons/antineutrons as the default case,
// to be used for instance, as first approximation
// without validation, for anti-hyperons.
//if ( (theParticle == theAProton) || (theParticle == theANeutron) ) {
if (A==1)
{ fInelasticXsc = (sigmaTotal - sigmaElastic) * millibarn;
return fInelasticXsc;
}
fRadiusEff = 1.31*G4Pow::GetInstance()->powA(A, 0.22)+0.9/G4Pow::GetInstance()->powA(A, 1./3.); //fm
if( (Z==1) && (A==2) ) fRadiusEff = 3.582; //fm
if( (Z==1) && (A==3) ) fRadiusEff = 3.105;
if( (Z==2) && (A==3) ) fRadiusEff = 3.105;
if( (Z==2) && (A==4) ) fRadiusEff = 2.209;
//}
if (A==1) {
fInelasticXsc = (sigmaTotal - sigmaElastic) * millibarn;
return fInelasticXsc;
}
fRadiusEff = 1.31*G4Pow::GetInstance()->powA(A, 0.22)+0.9/G4Pow::GetInstance()->powA(A, 1./3.); //fm
if ( (Z==1) && (A==2) ) fRadiusEff = 3.582; //fm
if ( (Z==1) && (A==3) ) fRadiusEff = 3.105;
if ( (Z==2) && (A==3) ) fRadiusEff = 3.105;
if ( (Z==2) && (A==4) ) fRadiusEff = 2.209;
//calculation of effective nuclear radius for AntiDeuteron interaction (can be changed)
// calculation of effective nuclear radius for AntiDeuteron interaction (can be changed)
if (theParticle ==theADeuteron) {
fRadiusEff = 1.38*G4Pow::GetInstance()->powA(A, 0.21)+1.55/G4Pow::GetInstance()->powA(A, 1./3.);
if ( (Z==1) && (A==2) ) fRadiusEff = 3.169; //fm
if ( (Z==1) && (A==3) ) fRadiusEff = 3.066;
if ( (Z==2) && (A==3) ) fRadiusEff = 3.066;
if ( (Z==2) && (A==4) ) fRadiusEff = 2.498;
}
if (theParticle ==theADeuteron)
{
fRadiusEff = 1.38*G4Pow::GetInstance()->powA(A, 0.21)+1.55/G4Pow::GetInstance()->powA(A, 1./3.);
if( (Z==1) && (A==2) ) fRadiusEff = 3.169; //fm
if( (Z==1) && (A==3) ) fRadiusEff = 3.066;
if( (Z==2) && (A==3) ) fRadiusEff = 3.066;
if( (Z==2) && (A==4) ) fRadiusEff = 2.498;
}
// calculation of effective nuclear radius for AntiHe3 interaction (can be changed)
if ( (theParticle ==theAHe3) || (theParticle ==theATriton) ) {
fRadiusEff = 1.34 * G4Pow::GetInstance()->powA(A, 0.21)+1.51/G4Pow::GetInstance()->powA(A, 1./3.);
if ( (Z==1) && (A==2) ) fRadiusEff = 3.066; //fm
if ( (Z==1) && (A==3) ) fRadiusEff = 2.973;
if ( (Z==2) && (A==3) ) fRadiusEff = 2.973;
if ( (Z==2) && (A==4) ) fRadiusEff = 2.508;
}
//calculation of effective nuclear radius for AntiHe3 interaction (can be changed)
// calculation of effective nuclear radius for AntiAlpha interaction (can be changed)
if (theParticle == theAAlpha) {
fRadiusEff = 1.3*G4Pow::GetInstance()->powA(A, 0.21)+1.05/G4Pow::GetInstance()->powA(A, 1./3.);
if ( (Z==1) && (A==2) ) fRadiusEff = 2.498; //fm
if ( (Z==1) && (A==3) ) fRadiusEff = 2.508;
if ( (Z==2) && (A==3) ) fRadiusEff = 2.508;
if ( (Z==2) && (A==4) ) fRadiusEff = 2.158;
}
if( (theParticle ==theAHe3) || (theParticle ==theATriton) )
{
fRadiusEff = 1.34 * G4Pow::GetInstance()->powA(A, 0.21)+1.51/G4Pow::GetInstance()->powA(A, 1./3.);
if( (Z==1) && (A==2) ) fRadiusEff = 3.066; //fm
if( (Z==1) && (A==3) ) fRadiusEff = 2.973;
if( (Z==2) && (A==3) ) fRadiusEff = 2.973;
if( (Z==2) && (A==4) ) fRadiusEff = 2.508;
}
G4double R2 = fRadiusEff*fRadiusEff;
G4double REf2 = R2+fRadiusNN2;
G4double ApAt = std::abs(theParticle->GetBaryonNumber()) * A;
//calculation of effective nuclear radius for AntiAlpha interaction (can be changed)
inelxsection = pi*REf2 *10* G4Log(1+(ApAt*sigmaTotal/(pi*REf2*10.))); //mb
inelxsection = inelxsection * millibarn;
fInelasticXsc = inelxsection;
if (theParticle == theAAlpha)
{
fRadiusEff = 1.3*G4Pow::GetInstance()->powA(A, 0.21)+1.05/G4Pow::GetInstance()->powA(A, 1./3.);
if( (Z==1) && (A==2) ) fRadiusEff = 2.498; //fm
if( (Z==1) && (A==3) ) fRadiusEff = 2.508;
if( (Z==2) && (A==3) ) fRadiusEff = 2.508;
if( (Z==2) && (A==4) ) fRadiusEff = 2.158;
}
G4double R2 = fRadiusEff*fRadiusEff;
G4double REf2 = R2+fRadiusNN2;
G4double ApAt= std::abs(theParticle->GetBaryonNumber()) * A;
inelxsection = pi*REf2 *10* G4Log(1+(ApAt*sigmaTotal/(pi*REf2*10.))); //mb
inelxsection = inelxsection * millibarn;
fInelasticXsc = inelxsection;
return fInelasticXsc;
return fInelasticXsc;
}
///////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//
// Calculates Inelastic Anti-nucleus-Nucleus cross-section
//
G4double G4ComponentAntiNuclNuclearXS::GetInelasticIsotopeCrossSection
(const G4ParticleDefinition* aParticle, G4double kinEnergy, G4int Z, G4int A)
{return GetInelasticElementCrossSection(aParticle, kinEnergy, Z, (G4double) A); }
{
return GetInelasticElementCrossSection(aParticle, kinEnergy, Z, (G4double) A);
}
///////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//
// Calculates elastic Anti-nucleus-Nucleus cross-section as Total - Inelastic
//
G4double G4ComponentAntiNuclNuclearXS::GetElasticElementCrossSection
(const G4ParticleDefinition* aParticle, G4double kinEnergy, G4int Z, G4double A)
{
fElasticXsc = GetTotalElementCrossSection(aParticle, kinEnergy, Z, A)-
GetInelasticElementCrossSection(aParticle, kinEnergy, Z, A);
if (fElasticXsc < 0.) fElasticXsc = 0.;
return fElasticXsc;
fElasticXsc = GetTotalElementCrossSection(aParticle, kinEnergy, Z, A)-
GetInelasticElementCrossSection(aParticle, kinEnergy, Z, A);
if (fElasticXsc < 0.) fElasticXsc = 0.;
return fElasticXsc;
}
///////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//
// Calculates elastic Anti-nucleus-Nucleus cross-section
//
G4double G4ComponentAntiNuclNuclearXS::GetElasticIsotopeCrossSection
(const G4ParticleDefinition* aParticle, G4double kinEnergy, G4int Z, G4int A)
{ return GetElasticElementCrossSection(aParticle, kinEnergy, Z, (G4double) A); }
{
return GetElasticElementCrossSection(aParticle, kinEnergy, Z, (G4double) A);
}
///////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Calculation of Antihadron - hadron Total Cross-section
G4double G4ComponentAntiNuclNuclearXS::GetAntiHadronNucleonTotCrSc
@@ -298,68 +270,66 @@ G4double G4ComponentAntiNuclNuclearXS::GetAntiHadronNucleonTotCrSc
momentum=std::sqrt(Energy*Energy-Pmass*Pmass)/std::abs(theParticle->GetBaryonNumber());
G4double Plab = momentum / GeV;
G4double B, SigAss;
G4double C, d1, d2, d3 ;
G4double B, SigAss;
G4double C, d1, d2, d3;
Elab = std::sqrt(Mn*Mn + Plab*Plab); // GeV
S = 2.*Mn*Mn + 2. *Mn*Elab; // GeV^2
SqrtS = std::sqrt(S); // GeV
B = b0+b2*G4Log(SqrtS/SqrtS0)*G4Log(SqrtS/SqrtS0); //GeV^(-2)
SigAss = 36.04 +0.304*G4Log(S/S0)*G4Log(S/S0); //mb
R0 = std::sqrt(0.40874044*SigAss - B); //GeV^(-2)
C = 13.55;
d1 = -4.47;
d2 = 12.38;
d3 = -12.43;
Elab = std::sqrt(Mn*Mn + Plab*Plab); // GeV
S = 2.*Mn*Mn + 2. *Mn*Elab; // GeV^2
SqrtS = std::sqrt(S); // GeV
B = b0+b2*G4Log(SqrtS/SqrtS0)*G4Log(SqrtS/SqrtS0); //GeV^(-2)
SigAss = 36.04 +0.304*G4Log(S/S0)*G4Log(S/S0); //mb
R0 = std::sqrt(0.40874044*SigAss - B); //GeV^(-2)
C = 13.55;
d1 = -4.47;
d2 = 12.38;
d3 = -12.43;
xsection = SigAss*(1 + 1./(std::sqrt(S-4.*Mn*Mn)) / (G4Pow::GetInstance()->powA(R0, 3.))
*C* (1+d1/SqrtS+d2/(G4Pow::GetInstance()->powA(SqrtS,2.))+d3/(G4Pow::GetInstance()->powA(SqrtS,3.)) ));
// xsection *= millibarn;
xsection = SigAss * ( 1 + 1./(std::sqrt(S-4.*Mn*Mn)) / (G4Pow::GetInstance()->powA(R0, 3.))
* C * ( 1 + d1/SqrtS + d2/(G4Pow::GetInstance()->powA(SqrtS,2.))
+ d3/(G4Pow::GetInstance()->powA(SqrtS,3.)) ) );
//xsection *= millibarn;
fAntiHadronNucleonTotXsc = xsection;
return fAntiHadronNucleonTotXsc;
}
//
// /////////////////////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////////////
// Calculation of Antihadron - hadron Elastic Cross-section
G4double G4ComponentAntiNuclNuclearXS ::
GetAntiHadronNucleonElCrSc(const G4ParticleDefinition* aParticle, G4double kinEnergy)
{
G4double xsection;
G4double xsection;
G4double SigAss;
G4double C, d1, d2, d3;
GetAntiHadronNucleonTotCrSc(aParticle,kinEnergy);
SigAss = 4.5 + 0.101*G4Log(S/S0)*G4Log(S/S0); //mb
C = 59.27;
d1 = -6.95;
d2 = 23.54;
d3 = -25.34;
G4double SigAss;
G4double C, d1, d2, d3 ;
GetAntiHadronNucleonTotCrSc(aParticle,kinEnergy);
SigAss = 4.5 + 0.101*G4Log(S/S0)*G4Log(S/S0); //mb
C = 59.27;
d1 = -6.95;
d2 = 23.54;
d3 = -25.34;
xsection = SigAss* (1 + 1. / (std::sqrt(S-4.*Mn*Mn)) / (G4Pow::GetInstance()->powA(R0, 3.))
*C* ( 1+d1/SqrtS+d2/(G4Pow::GetInstance()->powA(SqrtS,2.))+d3/(G4Pow::GetInstance()->powA(SqrtS,3.)) ));
// xsection *= millibarn;
xsection = SigAss * ( 1 + 1. / (std::sqrt(S-4.*Mn*Mn)) / (G4Pow::GetInstance()->powA(R0, 3.))
* C * ( 1 + d1/SqrtS + d2/(G4Pow::GetInstance()->powA(SqrtS,2.))
+ d3/(G4Pow::GetInstance()->powA(SqrtS,3.)) ) );
//xsection *= millibarn;
fAntiHadronNucleonElXsc = xsection;
return fAntiHadronNucleonElXsc;
}
/////////////////////////////////////////////////////////////////////////////
void G4ComponentAntiNuclNuclearXS::CrossSectionDescription(std::ostream& outFile) const
{
outFile << "The G4ComponentAntiNuclNuclearXS calculates total,\n"
<< "inelastic, elastic cross sections of anti-nucleons and light \n"
<< "anti-nucleus interactions with nuclei using Glauber's approach.\n"
<< "anti-nucleus interactions with nuclei using Glauber's approach.\n"
<< "It uses parametrizations of antiproton-proton total and elastic \n"
<< "cross sections and Wood-Saxon distribution of nuclear density.\n"
<< "The lower limit is 10 MeV, the upper limit is 10 TeV. \n"
<< "cross sections and Wood-Saxon distribution of nuclear density.\n"
<< "See details in Phys.Lett. B705 (2011) 235. \n";
}
@@ -40,112 +40,41 @@
#include "G4BarashenkovData.hh"
#include "G4NistManager.hh"
using namespace std;
///////////////////////////////////////////////////////////////////////////////
G4double G4ComponentBarNucleonNucleusXsc::theA[93] = {0.0};
G4double G4ComponentBarNucleonNucleusXsc::A75[93] = {0.0};
G4int G4ComponentBarNucleonNucleusXsc::theZ[] =
{2,4,6,7,8,11,13,14,20,26,29,42,48,50,74,82,92};
std::vector<G4PiData*>* G4ComponentBarNucleonNucleusXsc::thePData = nullptr;
std::vector<G4PiData*>* G4ComponentBarNucleonNucleusXsc::theNData = nullptr;
#ifdef G4MULTITHREADED
G4Mutex G4ComponentBarNucleonNucleusXsc::barNNXSMutex = G4MUTEX_INITIALIZER;
#endif
G4ComponentBarNucleonNucleusXsc::G4ComponentBarNucleonNucleusXsc()
: G4VComponentCrossSection("G4ComponentBarNucleonNucleusXsc"),
fTotalXsc(0.0), fInelasticXsc(0.0), fElasticXsc(0.0)
: G4VComponentCrossSection("BarashenkovNucleonNucleusXsc"),
fTotalXsc(0.0), fInelasticXsc(0.0), fElasticXsc(0.0), isMaster(false)
{
theNeutron = G4Neutron::Neutron();
theProton = G4Proton::Proton();
// He, Be, C
thePimData.push_back(new G4PiData(he_m_t, he_m_in, e1, 44));
thePipData.push_back(new G4PiData(he_m_t, he_p_in, e1, 44));
thePimData.push_back(new G4PiData(be_m_t, be_m_in, e1, 44));
thePipData.push_back(new G4PiData(be_m_t, be_p_in, e1, 44));
thePimData.push_back(new G4PiData(c_m_t, c_m_in, e1, 44));
thePipData.push_back(new G4PiData(c_m_t, c_p_in, e1, 44));
// N, O, Na
thePimData.push_back(new G4PiData(n_m_t, n_m_in, e2, 44));
thePipData.push_back(new G4PiData(n_m_t, n_p_in, e2, 44));
thePimData.push_back(new G4PiData(o_m_t, o_m_in, e2, 44));
thePipData.push_back(new G4PiData(o_m_t, o_p_in, e2, 44));
thePimData.push_back(new G4PiData(na_m_t, na_m_in, e2, 44));
thePipData.push_back(new G4PiData(na_m_t, na_p_in, e2, 44));
// Al, Si, Ca
thePimData.push_back(new G4PiData(al_m_t, al_m_in, e3, 45));
thePipData.push_back(new G4PiData(al_m_t, al_p_in, e3, 45));
thePimData.push_back(new G4PiData(si_m_t, si_m_in, e3, 45));
thePipData.push_back(new G4PiData(si_m_t, si_p_in, e3, 45));
thePimData.push_back(new G4PiData(ca_m_t, ca_m_in, e3, 45));
thePipData.push_back(new G4PiData(ca_m_t, ca_p_in, e3, 45));
// Fe, Cu, Mo
thePimData.push_back(new G4PiData(fe_m_t, fe_m_in, e4, 47));
thePipData.push_back(new G4PiData(fe_m_t, fe_p_in, e4, 47));
thePimData.push_back(new G4PiData(cu_m_t, cu_m_in, e4, 47));
thePipData.push_back(new G4PiData(cu_m_t, cu_p_in, e4, 47));
thePimData.push_back(new G4PiData(mo_m_t, mo_m_in, e4, 47));
thePipData.push_back(new G4PiData(mo_m_t, mo_p_in, e4, 47));
// Cd, Sn, W
thePimData.push_back(new G4PiData(cd_m_t, cd_m_in, e5, 48));
thePipData.push_back(new G4PiData(cd_m_t, cd_p_in, e5, 48));
thePimData.push_back(new G4PiData(sn_m_t, sn_m_in, e5, 48));
thePipData.push_back(new G4PiData(sn_m_t, sn_p_in, e5, 48));
thePimData.push_back(new G4PiData(w_m_t, w_m_in, e5, 48));
thePipData.push_back(new G4PiData(w_m_t, w_p_in, e5, 48));
// Pb, U
thePimData.push_back(new G4PiData(pb_m_t, pb_m_in, e6, 46));
thePipData.push_back(new G4PiData(pb_m_t, pb_p_in, e6, 46));
thePimData.push_back(new G4PiData(u_m_t, u_m_in, e6, 46));
thePipData.push_back(new G4PiData(u_m_t, u_p_in, e6, 46));
theZ.push_back(2); // He
theZ.push_back(4); // Be
theZ.push_back(6); // C
theZ.push_back(7); // N
theZ.push_back(8); // O
theZ.push_back(11); // Na
theZ.push_back(13); // Al
theZ.push_back(14); // Si
theZ.push_back(20); // Ca
theZ.push_back(26); // Fe
theZ.push_back(29); // Cu
theZ.push_back(42); // Mo
theZ.push_back(48); // Cd
theZ.push_back(50); // Sn
theZ.push_back(74); // W
theZ.push_back(82); // Pb
theZ.push_back(92); // U
if(A75[0] == 0.0) {
G4NistManager* nist = G4NistManager::Instance();
A75[0] = theA[0] = 1.0;
for(G4int i=1; i<93; ++i) {
theA[i] = nist->GetAtomicMassAmu(i);
A75[i] = G4Pow::GetInstance()->A23(theA[i]); // interpolate by square ~ A^(2/3)
}
}
}
///////////////////////////////////////////////////////////////////////////////
//
G4ComponentBarNucleonNucleusXsc::~G4ComponentBarNucleonNucleusXsc()
{
for(auto xsec : thePimData) { delete xsec; }
for(auto xsec : thePipData) { delete xsec; }
if(isMaster && thePData && theNData) {
for(G4int i=0; i<NZ; ++i) {
delete (*thePData)[i];
delete (*theNData)[i];
}
delete thePData;
delete theNData;
thePData = nullptr;
theNData = nullptr;
}
}
////////////////////////////////////////////////////////////////////
@@ -208,61 +137,41 @@ G4double G4ComponentBarNucleonNucleusXsc::GetElasticIsotopeCrossSection(
return fElasticXsc;
}
////////////////////////////////////////////////////////////////////////////
//
G4bool G4ComponentBarNucleonNucleusXsc::IsElementApplicable(
const G4DynamicParticle*, G4int Z)
{
return (Z > 1);
}
////////////////////////////////////////////////////////////////////////////
//
//
void G4ComponentBarNucleonNucleusXsc::ComputeCrossSections(
const G4ParticleDefinition* aParticle, G4double kineticEnergy, G4int ZZ)
{
G4int Z = std::min(ZZ, 92);
size_t it = 0;
size_t itmax = theZ.size() - 1;
for(; it <= itmax; ++it) { if(Z <= theZ[it]) { break; } }
if( it > itmax ) { it = itmax; }
G4int Z1, Z2;
G4double x1, x2, xt1, xt2;
G4int it = 0;
for(; it<NZ; ++it) { if(Z <= theZ[it]) { break; } }
if( it >= NZ ) { it = NZ-1; }
std::vector<G4PiData*>* theData = (aParticle == theNeutron) ? &thePimData : &thePipData;
std::vector<G4PiData*>* theData = (aParticle == theNeutron) ? theNData : thePData;
if( theZ[it] == Z )
{
fInelasticXsc = (*theData)[it]->ReactionXSection(kineticEnergy);
fTotalXsc = (*theData)[it]->TotalXSection(kineticEnergy);
}
else
{
if(0 == it) { it = 1; }
x1 = (*theData)[it-1]->ReactionXSection(kineticEnergy);
xt1 = (*theData)[it-1]->TotalXSection(kineticEnergy);
Z1 = theZ[it-1];
x2 = (*theData)[it]->ReactionXSection(kineticEnergy);
xt2 = (*theData)[it]->TotalXSection(kineticEnergy);
Z2 = theZ[it];
if( theZ[it] == Z ) {
fInelasticXsc = (*theData)[it]->ReactionXSection(kineticEnergy);
fTotalXsc = (*theData)[it]->TotalXSection(kineticEnergy);
} else {
if(0 == it) { it = 1; }
G4double x1 = (*theData)[it-1]->ReactionXSection(kineticEnergy);
G4double xt1 = (*theData)[it-1]->TotalXSection(kineticEnergy);
G4double x2 = (*theData)[it]->ReactionXSection(kineticEnergy);
G4double xt2 = (*theData)[it]->TotalXSection(kineticEnergy);
G4int Z1 = theZ[it-1];
G4int Z2 = theZ[it];
fInelasticXsc = Interpolate(Z1, Z2, Z, x1, x2);
fTotalXsc = Interpolate(Z1, Z2, Z, xt1, xt2);
}
fElasticXsc = std::max(fTotalXsc - fInelasticXsc, 0.0);
fInelasticXsc = Interpolate(Z1, Z2, Z, x1, x2);
fTotalXsc = Interpolate(Z1, Z2, Z, xt1, xt2);
}
fElasticXsc = std::max(fTotalXsc - fInelasticXsc, 0.0);
}
/////////////////////////////////////////////////////////////////////////////
//
G4double G4ComponentBarNucleonNucleusXsc::
Interpolate(G4int Z1, G4int Z2, G4int Z, G4double x1, G4double x2)
Interpolate(G4int Z1, G4int Z2, G4int Z, G4double x1, G4double x2) const
{
// for tabulated data, cross section scales with A^(2/3)
G4double r1 = x1* A75[Z] / A75[Z1];
@@ -275,8 +184,9 @@ Interpolate(G4int Z1, G4int Z2, G4int Z, G4double x1, G4double x2)
return result;
}
void
G4ComponentBarNucleonNucleusXsc::CrossSectionDescription(std::ostream& outFile) const
/////////////////////////////////////////////////////////////////////////////
void G4ComponentBarNucleonNucleusXsc::Description(std::ostream& outFile) const
{
outFile << "G4ComponentBarNucleonNucleusXsc is a variant of the Barashenkov\n"
<< "cross section parameterization to be used of protons and\n"
@@ -286,3 +196,98 @@ G4ComponentBarNucleonNucleusXsc::CrossSectionDescription(std::ostream& outFile)
<< "to 1 TeV.\n";
}
/////////////////////////////////////////////////////////////////////////////
void
G4ComponentBarNucleonNucleusXsc::BuildPhysicsTable(const G4ParticleDefinition&)
{
if(theNData) { return; }
#ifdef G4MULTITHREADED
G4MUTEXLOCK(&barNNXSMutex);
if(!theNData) {
#endif
isMaster = true;
#ifdef G4MULTITHREADED
}
G4MUTEXUNLOCK(&barNNXSMutex);
#endif
if(isMaster) { LoadData(); }
}
/////////////////////////////////////////////////////////////////////////////
void G4ComponentBarNucleonNucleusXsc::LoadData()
{
theNData = new std::vector<G4PiData*>;
thePData = new std::vector<G4PiData*>;
theNData->resize(NZ, nullptr);
thePData->resize(NZ, nullptr);
// He, Be, C
(*theNData)[0] = new G4PiData(he_m_t, he_m_in, e1, 44);
(*thePData)[0] = new G4PiData(he_m_t, he_p_in, e1, 44);
(*theNData)[1] = new G4PiData(be_m_t, be_m_in, e1, 44);
(*thePData)[1] = new G4PiData(be_m_t, be_p_in, e1, 44);
(*theNData)[2] = new G4PiData(c_m_t, c_m_in, e1, 44);
(*thePData)[2] = new G4PiData(c_m_t, c_p_in, e1, 44);
// N, O, Na
(*theNData)[3] = new G4PiData(n_m_t, n_m_in, e2, 44);
(*thePData)[3] = new G4PiData(n_m_t, n_p_in, e2, 44);
(*theNData)[4] = new G4PiData(o_m_t, o_m_in, e2, 44);
(*thePData)[4] = new G4PiData(o_m_t, o_p_in, e2, 44);
(*theNData)[5] = new G4PiData(na_m_t, na_m_in, e2, 44);
(*thePData)[5] = new G4PiData(na_m_t, na_p_in, e2, 44);
// Al, Si, Ca
(*theNData)[6] = new G4PiData(al_m_t, al_m_in, e3, 45);
(*thePData)[6] = new G4PiData(al_m_t, al_p_in, e3, 45);
(*theNData)[7] = new G4PiData(si_m_t, si_m_in, e3, 45);
(*thePData)[7] = new G4PiData(si_m_t, si_p_in, e3, 45);
(*theNData)[8] = new G4PiData(ca_m_t, ca_m_in, e3, 45);
(*thePData)[8] = new G4PiData(ca_m_t, ca_p_in, e3, 45);
// Fe, Cu, Mo
(*theNData)[9] = new G4PiData(fe_m_t, fe_m_in, e4, 47);
(*thePData)[9] = new G4PiData(fe_m_t, fe_p_in, e4, 47);
(*theNData)[10] = new G4PiData(cu_m_t, cu_m_in, e4, 47);
(*thePData)[10] = new G4PiData(cu_m_t, cu_p_in, e4, 47);
(*theNData)[11] = new G4PiData(mo_m_t, mo_m_in, e4, 47);
(*thePData)[11] = new G4PiData(mo_m_t, mo_p_in, e4, 47);
// Cd, Sn, W
(*theNData)[12] = new G4PiData(cd_m_t, cd_m_in, e5, 48);
(*thePData)[12] = new G4PiData(cd_m_t, cd_p_in, e5, 48);
(*theNData)[13] = new G4PiData(sn_m_t, sn_m_in, e5, 48);
(*thePData)[13] = new G4PiData(sn_m_t, sn_p_in, e5, 48);
(*theNData)[14] = new G4PiData(w_m_t, w_m_in, e5, 48);
(*thePData)[14] = new G4PiData(w_m_t, w_p_in, e5, 48);
// Pb, U
(*theNData)[15] = new G4PiData(pb_m_t, pb_m_in, e6, 46);
(*thePData)[15] = new G4PiData(pb_m_t, pb_p_in, e6, 46);
(*theNData)[16] = new G4PiData(u_m_t, u_m_in, e6, 46);
(*thePData)[16] = new G4PiData(u_m_t, u_p_in, e6, 46);
G4NistManager* nist = G4NistManager::Instance();
A75[0] = theA[0] = 1.0;
G4Pow* g4pow = G4Pow::GetInstance();
for(G4int i=1; i<93; ++i) {
theA[i] = nist->GetAtomicMassAmu(i);
A75[i] = g4pow->A23(theA[i]); // interpolate by square ~ A^(2/3)
}
}
/////////////////////////////////////////////////////////////////////////////
@@ -29,6 +29,7 @@
//
// 04.09.18 V. Ivantchenko Major revision of interfaces and implementation
// 01.10.18 V. Grichine strange hyperon xsc
// 27.05.19 V. Ivantchenko Removed obsolete methods and members
//
#include "G4ComponentGGHadronNucleusXsc.hh"
@@ -41,19 +42,16 @@
#include "G4DynamicParticle.hh"
#include "G4HadronNucleonXsc.hh"
#include "G4Log.hh"
#include "G4Exp.hh"
#include "G4Pow.hh"
#include "G4NuclearRadii.hh"
//////////////////////////////////////////////////////////////////////////////
//
G4ComponentGGHadronNucleusXsc::G4ComponentGGHadronNucleusXsc()
: G4VComponentCrossSection(Default_Name()),
fLowerLimit(10.*MeV),
fRadiusConst(1.08*fermi),
fTotalXsc(0.0), fElasticXsc(0.0), fInelasticXsc(0.0), fProductionXsc(0.0),
fDiffractionXsc(0.0), fAxsc2piR2(0.0),fModelInLog(0.0),
fParticle(nullptr), fEnergy(0.0), fZ(0), fA(0)
fTotalXsc(0.0),fElasticXsc(0.0),fInelasticXsc(0.0),fProductionXsc(0.0),
fDiffractionXsc(0.0),fAxsc2piR2(0.0),fModelInLog(0.0),fEnergy(0.0),
fParticle(nullptr),fZ(0),fA(0)
{
theGamma = G4Gamma::Gamma();
theProton = G4Proton::Proton();
@@ -66,24 +64,8 @@ G4ComponentGGHadronNucleusXsc::G4ComponentGGHadronNucleusXsc()
theKMinus = G4KaonMinus::KaonMinus();
theK0S = G4KaonZeroShort::KaonZeroShort();
theK0L = G4KaonZeroLong::KaonZeroLong();
//strange hyperons
theL = G4Lambda::Lambda();
theAntiL = G4AntiLambda::AntiLambda();
theSPlus = G4SigmaPlus::SigmaPlus();
theASPlus = G4AntiSigmaPlus::AntiSigmaPlus();
theSMinus = G4SigmaMinus::SigmaMinus();
theASMinus = G4AntiSigmaMinus::AntiSigmaMinus();
theS0 = G4SigmaZero::SigmaZero();
theAS0 = G4AntiSigmaZero::AntiSigmaZero();
theXiMinus = G4XiMinus::XiMinus();
theXi0 = G4XiZero::XiZero();
theAXiMinus = G4AntiXiMinus::AntiXiMinus();
theAXi0 = G4AntiXiZero::AntiXiZero();
theOmega = G4OmegaMinus::OmegaMinus();
theAOmega = G4AntiOmegaMinus::AntiOmegaMinus();
hnXsc = new G4HadronNucleonXsc();
g4calc = G4Pow::GetInstance();
}
/////////////////////////////////////////////////////////////////////////////
@@ -186,46 +168,6 @@ G4double G4ComponentGGHadronNucleusXsc::GetProductionIsotopeCrossSection(
return fProductionXsc;
}
//////////////////////////////////////////////////////////////////////
G4bool
G4ComponentGGHadronNucleusXsc::IsIsoApplicable(const G4DynamicParticle* aDP,
G4int /*Z*/, G4int /*A*/,
const G4Element*,
const G4Material*)
{
G4bool applicable = false;
G4double kineticEnergy = aDP->GetKineticEnergy();
const G4ParticleDefinition* theParticle = aDP->GetDefinition();
if ((kineticEnergy >= fLowerLimit &&
(theParticle == theAProton ||
theParticle == theGamma ||
theParticle == theSMinus ||
theParticle == theProton ||
theParticle == theNeutron ||
theParticle == thePiPlus ||
theParticle == thePiMinus ||
theParticle == theL || theParticle == theAntiL || theParticle == theSPlus || theParticle == theASPlus ||
theParticle == theSMinus || theParticle == theASMinus || theParticle == theS0 || theParticle == theAS0 ||
theParticle == theXiMinus || theParticle == theXi0 || theParticle == theAXiMinus || theParticle == theAXi0 ||
theParticle == theOmega || theParticle == theAOmega
))
||
(kineticEnergy >= 0.01*fLowerLimit &&
(
theParticle == theKPlus ||
theParticle == theKMinus ||
theParticle == theK0L ||
theParticle == theK0S
)
)
) applicable = true;
return applicable;
}
////////////////////////////////////////////////////////////////////////////
//
// Calculates total and inelastic Xsc, derives elastic as total
@@ -247,35 +189,14 @@ void G4ComponentGGHadronNucleusXsc::ComputeCrossSections(
fEnergy = kinEnergy;
//
G4double sigma(0.0), cofInelastic(2.2), cofTotal(2.0);
G4double hpInXsc(0.), hnInXsc(0.);
G4double R = GetNucleusRadius(A);
G4double cofInelastic = 2.4;
static const G4double cofTotal = 2.0;
G4double sigma(0.0), hpInXsc(0.0), hnInXsc(0.0), R(0.0);
G4int N = std::max(A - Z, 0); // number of neutrons
G4int N = std::max(A - Z, 0); // number of neutrons
if( aParticle == theProton ||
aParticle == theNeutron ||
aParticle == thePiPlus ||
aParticle == thePiMinus ||
aParticle == theL || aParticle == theAntiL || aParticle == theSPlus || aParticle == theASPlus ||
aParticle == theSMinus || aParticle == theASMinus || aParticle == theS0 || aParticle == theAS0 ||
aParticle == theXiMinus || aParticle == theXi0 || aParticle == theAXiMinus || aParticle == theAXi0 ||
aParticle == theOmega || aParticle == theAOmega
)
{
sigma = Z*hnXsc->HadronNucleonXscNS(aParticle, theProton, kinEnergy);
hpInXsc = hnXsc->GetInelasticHadronNucleonXsc();
if(N > 0) {
sigma += N*hnXsc->HadronNucleonXscNS(aParticle, theNeutron, kinEnergy);
hnInXsc = hnXsc->GetInelasticHadronNucleonXsc();
}
cofInelastic = 2.4;
} else if( aParticle == theKPlus ||
aParticle == theKMinus ||
aParticle == theK0S ||
aParticle == theK0L)
if( aParticle == theKPlus || aParticle == theKMinus ||
aParticle == theK0S || aParticle == theK0L)
{
sigma = (1 == Z)
? hnXsc->KaonNucleonXscNS(aParticle, theProton, kinEnergy)
@@ -286,7 +207,8 @@ void G4ComponentGGHadronNucleusXsc::ComputeCrossSections(
sigma += N*hnXsc->KaonNucleonXscGG(aParticle, theNeutron, kinEnergy);
hnInXsc = hnXsc->GetInelasticHadronNucleonXsc();
}
R = 1.3*fermi*g4calc->Z13(A);
R = G4NuclearRadii::RadiusKNGG(A);
cofInelastic = 2.2;
}
else
{
@@ -297,7 +219,9 @@ void G4ComponentGGHadronNucleusXsc::ComputeCrossSections(
sigma += N*hnXsc->HadronNucleonXscNS(aParticle, theNeutron, kinEnergy);
hnInXsc = hnXsc->GetInelasticHadronNucleonXsc();
}
R = G4NuclearRadii::RadiusHNGG(A);
}
G4double nucleusSquare = cofTotal*pi*R*R; // basically 2piRR
G4double ratio = sigma/nucleusSquare;
G4double difratio = ratio/(1.+ratio);
@@ -314,7 +238,7 @@ void G4ComponentGGHadronNucleusXsc::ComputeCrossSections(
fInelasticXsc = nucleusSquare*fModelInLog/cofInelastic;
G4double barcorr = GetParticleBarCorIn(aParticle, Z);
fInelasticXsc *= barcorr;
fElasticXsc = std::max(fTotalXsc - fInelasticXsc, 0.);
fElasticXsc = std::max(fTotalXsc - fInelasticXsc, 0.);
G4double xratio = (Z*hpInXsc + N*hnInXsc)/nucleusSquare;
fProductionXsc =
@@ -330,7 +254,7 @@ void G4ComponentGGHadronNucleusXsc::ComputeCrossSections(
fProductionXsc = nucleusSquare*G4Log(1. + cofInelastic*xratio)/cofInelastic;
fProductionXsc = std::min(fProductionXsc, fInelasticXsc);
}
/*
/*
G4cout << "GGXsc: Z= " << Z << " A= " << A << " E= " << kinEnergy
<< " xtot(b)= " << fTotalXsc/barn
<< " xel(b)= " << fElasticXsc/barn << " xinel(b)= " << fInelasticXsc/barn
@@ -368,9 +292,6 @@ GetRatioQE(const G4DynamicParticle* aParticle, G4int A, G4int Z)
/////////////////////////////////////////////////////////////////////////////////////
//
// Returns hadron-nucleon total Xsc according to differnt parametrisations:
// [2] E. Levin, hep-ph/9710546
// [3] U. Dersch, et al, hep-ex/9910052
// [4] M.J. Longo, et al, Phys.Rev.Lett. 33 (1974) 725
G4double G4ComponentGGHadronNucleusXsc::GetHadronNucleonXsc(
const G4DynamicParticle* aParticle, const G4Element* anElement)
@@ -384,9 +305,6 @@ G4double G4ComponentGGHadronNucleusXsc::GetHadronNucleonXsc(
/////////////////////////////////////////////////////////////////////////////////////
//
// Returns hadron-nucleon total Xsc according to differnt parametrisations:
// [2] E. Levin, hep-ph/9710546
// [3] U. Dersch, et al, hep-ex/9910052
// [4] M.J. Longo, et al, Phys.Rev.Lett. 33 (1974) 725
G4double G4ComponentGGHadronNucleusXsc::GetHadronNucleonXsc(
const G4DynamicParticle* aParticle, G4int, G4int)
@@ -519,84 +437,6 @@ G4double G4ComponentGGHadronNucleusXsc::GetHNinelasticXscVU(
return sumInelastic;
}
////////////////////////////////////////////////////////////////////////////////////
G4double G4ComponentGGHadronNucleusXsc::GetNucleusRadius(
const G4DynamicParticle*, const G4Element* anElement)
{
G4int At = G4lrint(anElement->GetN());
G4double R = fRadiusConst*g4calc->Z13(At);
static const G4double meanA = 21.;
static const G4double tauA1 = 40.;
static const G4double tauA2 = 10.;
static const G4double tauA3 = 5.;
static const G4double a1 = 0.85;
static const G4double b1 = 1. - a1;
static const G4double b2 = 0.3;
static const G4double b3 = 4.;
if (At > 20)
{
R *= ( a1 + b1*G4Exp( -(At - meanA)/tauA1) );
}
else if (At > 3)
{
R *= ( 1.0 + b2*( 1. - G4Exp( (At - meanA)/tauA2) ) );
}
else
{
R *= ( 1.0 + b3*( 1. - G4Exp( (At - meanA)/tauA3) ) );
}
return R;
}
//////////////////////////////////////////////////////////////////////
G4double G4ComponentGGHadronNucleusXsc::GetNucleusRadius(G4int At)
{
G4double R = fRadiusConst*g4calc->Z13(At);
static const G4double meanA = 20.;
static const G4double tauA = 20.;
if (At > 20)
{
R *= ( 0.8 + 0.2*G4Exp( -(G4double(At) - meanA)/tauA) );
}
else
{
R *= ( 1.0 + 0.1*( 1. - G4Exp( (G4double(At) - meanA)/tauA) ) );
}
return R;
}
////////////////////////////////////////////////////////////////////////
G4double G4ComponentGGHadronNucleusXsc::CalculateEcmValue(G4double mp ,
G4double mt ,
G4double Plab )
{
G4double Elab = std::sqrt ( mp * mp + Plab * Plab );
G4double Ecm = std::sqrt ( mp * mp + mt * mt + 2 * Elab * mt );
return Ecm ;
}
////////////////////////////////////////////////////////////////////////
G4double G4ComponentGGHadronNucleusXsc::CalcMandelstamS(G4double mp ,
G4double mt ,
G4double Plab )
{
G4double Elab = std::sqrt ( mp * mp + Plab * Plab );
G4double sMand = mp*mp + mt*mt + 2*Elab*mt ;
return sMand;
}
///////////////////////////////////////////////////////////////////////
//
//
@@ -26,6 +26,7 @@
// 24.11.08 V. Grichine - first implementation
//
// 04.09.18 V. Ivantchenko Major revision of interfaces and implementation
// 27.05.19 V. Ivantchenko Removed obsolete methods and members
#include "G4ComponentGGNuclNuclXsc.hh"
@@ -33,25 +34,21 @@
#include "G4SystemOfUnits.hh"
#include "G4NucleiProperties.hh"
#include "G4ParticleDefinition.hh"
#include "G4HadTmpUtil.hh"
#include "G4HadronNucleonXsc.hh"
#include "G4ComponentGGHadronNucleusXsc.hh"
#include "G4Pow.hh"
#include "G4NuclearRadii.hh"
static const G4double inve = 1./CLHEP::eplus;
G4ComponentGGNuclNuclXsc::G4ComponentGGNuclNuclXsc()
: G4VComponentCrossSection("Glauber-Gribov Nucl-nucl"),
fRadiusConst(1.08*fermi), // 1.1, 1.3 ?
fTotalXsc(0.0), fElasticXsc(0.0), fInelasticXsc(0.0), fProductionXsc(0.0),
fDiffractionXsc(0.0), fParticle(nullptr), fEnergy(0.0), fZ(0), fA(0)
fDiffractionXsc(0.0), fEnergy(0.0), fParticle(nullptr), fZ(0), fA(0)
{
theProton = G4Proton::Proton();
theNeutron = G4Neutron::Neutron();
fHNXsc = new G4HadronNucleonXsc();
fHadrNucl = new G4ComponentGGHadronNucleusXsc();
fNist = G4NistManager::Instance();
fCalc = G4Pow::GetInstance();
}
G4ComponentGGNuclNuclXsc::~G4ComponentGGNuclNuclXsc()
@@ -153,14 +150,6 @@ void G4ComponentGGNuclNuclXsc::Description(std::ostream& outFile) const
<< "For the hydrogen target G4HadronNucleonXsc class is used.\n";
}
/////////////////////////////////////////////////////////////////////
G4bool G4ComponentGGNuclNuclXsc::IsElementApplicable(const G4DynamicParticle*,
G4int, const G4Material*)
{
return true;
}
///////////////////////////////////////////////////////////////////////////////
//
// Calculates total and inelastic Xsc, derives elastic as total - inelastic
@@ -203,8 +192,8 @@ void G4ComponentGGNuclNuclXsc::ComputeCrossSections(
G4int pN = pA - pZ;
G4int tN = A - Z;
G4double tR = GetNucleusRadius( Z, A);
G4double pR = GetNucleusRadius( pZ, pA);
G4double tR = G4NuclearRadii::Radius(Z, A);
G4double pR = G4NuclearRadii::Radius(pZ, pA);
G4double cB = ComputeCoulombBarier(aParticle, kinEnergy, Z, A, pR, tR);
@@ -298,229 +287,3 @@ G4double G4ComponentGGNuclNuclXsc::GetRatioQE(
}
///////////////////////////////////////////////////////////////////////////////
//
// Returns hadron-nucleon Xsc according to differnt parametrisations:
// [2] E. Levin, hep-ph/9710546
// [3] U. Dersch, et al, hep-ex/9910052
// [4] M.J. Longo, et al, Phys.Rev.Lett. 33 (1974) 725
G4double
G4ComponentGGNuclNuclXsc::GetHadronNucleonXsc(const G4DynamicParticle* aParticle,
const G4Element* anElement)
{
G4int At = G4lrint(anElement->GetN()); // number of nucleons
G4int Zt = anElement->GetZasInt(); // number of protons
return GetHadronNucleonXsc(aParticle, At, Zt);
}
///////////////////////////////////////////////////////////////////////////////
//
// Returns hadron-nucleon Xsc according to differnt parametrisations:
// [2] E. Levin, hep-ph/9710546
// [3] U. Dersch, et al, hep-ex/9910052
// [4] M.J. Longo, et al, Phys.Rev.Lett. 33 (1974) 725
G4double
G4ComponentGGNuclNuclXsc::GetHadronNucleonXsc(const G4DynamicParticle* aParticle,
G4int At, G4int Zt)
{
return fHadrNucl->GetHadronNucleonXsc(aParticle, At, Zt);
}
///////////////////////////////////////////////////////////////////////////////
//
// Returns hadron-nucleon Xsc according to PDG parametrisation (2005):
// http://pdg.lbl.gov/2006/reviews/hadronicrpp.pdf
// At = number of nucleons, Zt = number of protons
G4double
G4ComponentGGNuclNuclXsc::GetHadronNucleonXscPDG(const G4ParticleDefinition* pParticle,
G4double pTkin,
const G4ParticleDefinition* tParticle)
{
G4double res = 0.0;
if(tParticle == theProton) {
res = fHNXsc->HadronNucleonXscPDG(pParticle, theProton, pTkin);
} else if(tParticle == theNeutron) {
res = fHNXsc->HadronNucleonXscPDG(pParticle, theNeutron, pTkin);
} else {
G4int Zt = tParticle->GetAtomicNumber();
G4int At = tParticle->GetAtomicMass();
fHadrNucl->ComputeCrossSections(pParticle, pTkin, Zt, At);
res = fHadrNucl->GetTotalGlauberGribovXsc();
}
return res;
}
///////////////////////////////////////////////////////////////////////////////
//
// Returns total nucleon-nucleon cross-section based on N. Starkov parametrisation
// of data from mainly http://wwwppds.ihep.su:8001/c5-6A.html database
// projectile nucleon is pParticle with pTkin shooting target nucleon tParticle
G4double
G4ComponentGGNuclNuclXsc::GetHadronNucleonXscNS(const G4ParticleDefinition* pParticle,
G4double pTkin,
const G4ParticleDefinition* tParticle)
{
G4int Zt = 1;
G4int At = 1;
if(tParticle == theNeutron) { Zt = 0; }
else if(tParticle != theProton) {
Zt = tParticle->GetAtomicNumber();
At = tParticle->GetAtomicMass();
}
fHadrNucl->ComputeCrossSections(pParticle, pTkin, Zt, At);
return fHadrNucl->GetTotalGlauberGribovXsc();
}
/////////////////////////////////////////////////////////////////////////////////
//
// Returns hadron-nucleon inelastic cross-section based on FTF-parametrisation
G4double
G4ComponentGGNuclNuclXsc::GetHNinelasticXscVU(const G4DynamicParticle* aParticle,
G4int At, G4int Zt)
{
return fHadrNucl->GetHNinelasticXscVU(aParticle, At, Zt);
}
///////////////////////////////////////////////////////////////////////////////
G4double G4ComponentGGNuclNuclXsc::GetNucleusRadius(const G4DynamicParticle*,
const G4Element* anElement)
{
G4double At = anElement->GetN();
G4double R = fRadiusConst*fCalc->A13(At);
static const G4double meanA = 21.;
static const G4double tauA1 = 40.;
static const G4double tauA2 = 10.;
static const G4double tauA3 = 5.;
static const G4double a1 = 0.85;
static const G4double b1 = 1. - a1;
static const G4double b2 = 0.3;
static const G4double b3 = 4.;
if (At > 20.) // 20.
{
R *= ( a1 + b1*G4Exp( -(At - meanA)/tauA1) );
}
else if (At > 3.5)
{
R *= ( 1.0 + b2*( 1. - G4Exp( (At - meanA)/tauA2) ) );
}
else
{
R *= ( 1.0 + b3*( 1. - G4Exp( (At - meanA)/tauA3) ) );
}
return R;
}
///////////////////////////////////////////////////////////////////////////////
G4double G4ComponentGGNuclNuclXsc::GetNucleusRadius(G4int Zt, G4int At)
{
return GetNucleusRadiusDE(Zt, At);
}
///////////////////////////////////////////////////////////////////////////////
G4double G4ComponentGGNuclNuclXsc::GetNucleusRadiusGG(G4int At)
{
G4double R = fRadiusConst*fCalc->Z13(At);
static const G4double meanA = 20.;
if ( At > 20) // 20.
{
R *= (0.8 + 0.2*G4Exp( -((G4double)At - meanA)/meanA) );
}
else
{
R *= (1.0 + 0.1*( 1. - G4Exp( ((G4double)At - meanA)/meanA) ) );
}
return R;
}
/////////////////////////////////////////////////////////////////////////////
G4double G4ComponentGGNuclNuclXsc::GetNucleusRadiusDE(G4int Z, G4int A)
{
// algorithm from diffuse-elastic
static const G4double a11 = 1.26; // 1.08, 1.16
static const G4double a12 = 1.19; // 1.08, 1.16
static const G4double a13 = 1.12; // 1.08, 1.16
static const G4double a2 = 1.1;
static const G4double a3 = 1.;
G4double R = CLHEP::fermi;
// Special rms radii for light nucleii
if (A < 50)
{
if(A == 1) { return 0.89*R; }// p
else if(A == 2) { return 2.13*R; }// d
else if(Z == 1 && A == 3) { return 1.80*R; }// t
else if(Z == 2 && A == 3) { return 1.96*R; }// He3
else if(Z == 2 && A == 4) { return 1.68*R; }// He4
else if(Z == 3) { return 2.40*R; }// Li7
else if(Z == 4) { return 2.51*R; }// Be9
else if( 10 < A && A <= 15) { R *= a11*(1. - 1./fCalc->Z23(A)); }
else if( 15 < A && A <= 20) { R *= a12*(1. - 1./fCalc->Z23(A)); }
else if( 20 < A && A <= 30) { R *= a13*(1. - 1./fCalc->Z23(A)); }
else { R *= a2; }
R *= fCalc->Z13(A);
}
else
{
R *= a3*fCalc->powZ(A, 0.27);
}
return R;
}
/////////////////////////////////////////////////////////////////////////////
//
// RMS radii from e-A scattering data
G4double
G4ComponentGGNuclNuclXsc::GetNucleusRadiusRMS(G4int Z, G4int A)
{
if (A == 1) { return 0.89*fermi; }// p
else if(A == 2) { return 2.13*fermi; } // d
else if(Z == 1 && A == 3) { return 1.80*fermi; }// t
else if(Z == 2 && A == 3) { return 1.96*fermi; }// He3
else if(Z == 2 && A == 4) { return 1.68*fermi; }// He4
else if(Z == 3) { return 2.40*fermi; }// Li7
else if(Z == 4) { return 2.51*fermi; }// Be9
else { return 1.24*fCalc->powZ(A, 0.28 )*fermi; }// A > 9
}
///////////////////////////////////////////////////////////////////////////////
G4double G4ComponentGGNuclNuclXsc::CalculateEcmValue(G4double mp,
G4double mt,
G4double Plab)
{
G4double Elab = std::sqrt ( mp * mp + Plab * Plab );
G4double Ecm = std::sqrt ( mp * mp + mt * mt + 2 * Elab * mt );
return Ecm ; // KEcm;
}
///////////////////////////////////////////////////////////////////////////////
G4double G4ComponentGGNuclNuclXsc::CalcMandelstamS(G4double mp,
G4double mt,
G4double Plab)
{
G4double Elab = std::sqrt ( mp * mp + Plab * Plab );
G4double sMand = mp*mp + mt*mt + 2*Elab*mt ;
return sMand;
}
///////////////////////////////////////////////////////////////////////////////
@@ -44,8 +44,6 @@
#include "G4CrossSectionDataStore.hh"
#include "G4SystemOfUnits.hh"
#include "G4UnitsTable.hh"
#include "G4HadronicException.hh"
#include "G4HadTmpUtil.hh"
#include "Randomize.hh"
#include "G4Nucleus.hh"
@@ -375,16 +373,15 @@ G4CrossSectionDataStore::GetIsoCrossSection(const G4DynamicParticle* part,
}
}
}
G4cout << "G4CrossSectionDataStore::GetCrossSection ERROR: "
<< " no isotope cross section found"
<< G4endl;
G4cout << " for " << part->GetDefinition()->GetParticleName()
<< " off Element " << elm->GetName()
<< " in " << mat->GetName()
<< " Z= " << Z << " A= " << A
<< " E(MeV)= " << part->GetKineticEnergy()/MeV << G4endl;
throw G4HadronicException(__FILE__, __LINE__,
" no applicable data set found for the isotope");
G4ExceptionDescription ed;
ed << "No isotope cross section found for "
<< part->GetDefinition()->GetParticleName()
<< " off Element " << elm->GetName()
<< " in " << mat->GetName() << " Z= " << Z << " A= " << A
<< " E(MeV)= " << part->GetKineticEnergy()/MeV << G4endl;
G4Exception("G4CrossSectionDataStore::GetIsoCrossSection", "had001",
FatalException, ed);
return 0.0;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
@@ -401,16 +398,15 @@ G4CrossSectionDataStore::GetCrossSection(const G4DynamicParticle* part,
return dataSetList[i]->GetIsoCrossSection(part, Z, A, iso, elm, mat);
}
}
G4cout << "G4CrossSectionDataStore::GetCrossSection ERROR: "
<< " no isotope cross section found"
<< G4endl;
G4cout << " for " << part->GetDefinition()->GetParticleName()
<< " off Element " << elm->GetName()
<< " in " << mat->GetName()
<< " Z= " << Z << " A= " << A
<< " E(MeV)= " << part->GetKineticEnergy()/MeV << G4endl;
throw G4HadronicException(__FILE__, __LINE__,
" no applicable data set found for the isotope");
G4ExceptionDescription ed;
ed << "No isotope cross section found for "
<< part->GetDefinition()->GetParticleName()
<< " off Element " << elm->GetName()
<< " in " << mat->GetName() << " Z= " << Z << " A= " << A
<< " E(MeV)= " << part->GetKineticEnergy()/MeV << G4endl;
G4Exception("G4CrossSectionDataStore::GetCrossSection", "had001",
FatalException, ed);
return 0.0;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
@@ -449,9 +445,10 @@ G4CrossSectionDataStore::SampleZandA(const G4DynamicParticle* part,
// more than 1 isotope
if(1 < nIso) {
iso = dataSetList[i]->SelectIsotope(anElement, part->GetKineticEnergy());
iso = dataSetList[i]->SelectIsotope(anElement,
part->GetKineticEnergy(),
part->GetLogKineticEnergy());
}
} else {
//----------------------------------------------------------------
@@ -496,12 +493,14 @@ G4CrossSectionDataStore::SampleZandA(const G4DynamicParticle* part,
void
G4CrossSectionDataStore::BuildPhysicsTable(const G4ParticleDefinition& aParticleType)
{
if (nDataSetList == 0)
{
throw G4HadronicException(__FILE__, __LINE__,
"G4CrossSectionDataStore: no data sets registered");
return;
}
if (nDataSetList == 0) {
G4ExceptionDescription ed;
ed << "No cross section is registered for "
<< aParticleType.GetParticleName() << G4endl;
G4Exception("G4CrossSectionDataStore::BuildPhysicsTable", "had001",
FatalException, ed);
return;
}
for (G4int i=0; i<nDataSetList; ++i) {
dataSetList[i]->BuildPhysicsTable(aParticleType);
}
@@ -529,16 +528,19 @@ G4CrossSectionDataStore::BuildPhysicsTable(const G4ParticleDefinition& aParticle
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4CrossSectionDataStore::ActivateFastPath( const G4ParticleDefinition* pdef, const G4Material* mat, G4double min_cutoff)
void G4CrossSectionDataStore::ActivateFastPath( const G4ParticleDefinition* pdef,
const G4Material* mat, G4double min_cutoff)
{
assert(pdef!=nullptr&&mat!=nullptr);
G4FastPathHadronicCrossSection::G4CrossSectionDataStore_Key key={pdef,mat};
if ( requests.insert( { key , min_cutoff } ).second ) {
std::ostringstream msg;
msg<<"Attempting to request FastPath for couple: "<<pdef->GetParticleName()<<","<<mat->GetName();
msg<<" but combination already exists";
throw G4HadronicException(__FILE__,__LINE__,msg.str());
}
assert(pdef!=nullptr&&mat!=nullptr);
G4FastPathHadronicCrossSection::G4CrossSectionDataStore_Key key={pdef,mat};
if ( requests.insert( { key , min_cutoff } ).second ) {
G4ExceptionDescription ed;
ed << "Attempting to request FastPath for couple: <"
<< pdef->GetParticleName() << ", " <<mat->GetName()
<< "> but combination already exists" << G4endl;
G4Exception("G4CrossSectionDataStore::ActivateFastPath", "had001",
FatalException, ed);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
@@ -37,7 +37,6 @@
#include "G4HadronCrossSections.hh"
#include "G4ios.hh"
#include "G4SystemOfUnits.hh"
#include "G4HadronicException.hh"
#include "G4Pow.hh"
#include "G4Threading.hh"
@@ -1706,13 +1705,6 @@ G4HadronCrossSections::GetParticleCode(const G4DynamicParticle* aParticle)
case -3334:
ipart = 34; // anti-omega-
break;
/*
default:
throw G4HadronicException(__FILE__, __LINE__,
"G4HadronCrossSections::GetParticleCode: unsupported particle "
+ aParticle->GetDefinition()->GetParticleName());
return 0;
*/
}
return ipart;
@@ -41,6 +41,76 @@
#include "G4Exp.hh"
#include "G4Pow.hh"
#include "G4LambdacPlus.hh"
#include "G4AntiLambdacPlus.hh"
#include "G4AntiXibZero.hh"
#include "G4OmegacZero.hh"
#include "G4SigmacZero.hh"
#include "G4AntiLambdab.hh"
#include "G4AntiSigmabMinus.hh"
#include "G4AntiXicPlus.hh"
#include "G4AntiLambdacPlus.hh"
#include "G4AntiSigmabPlus.hh"
#include "G4AntiXicZero.hh"
#include "G4AntiSigmabZero.hh"
#include "G4XibMinus.hh"
#include "G4AntiSigmacPlus.hh"
#include "G4XibZero.hh"
#include "G4AntiOmegabMinus.hh"
#include "G4AntiSigmacPlusPlus.hh"
#include "G4Lambdab.hh"
#include "G4SigmabMinus.hh"
#include "G4XicPlus.hh"
#include "G4AntiOmegacZero.hh"
#include "G4AntiSigmacZero.hh"
#include "G4LambdacPlus.hh"
#include "G4SigmabPlus.hh"
#include "G4XicZero.hh"
#include "G4SigmabZero.hh"
#include "G4SigmacPlus.hh"
#include "G4AntiXibMinus.hh"
#include "G4OmegabMinus.hh"
#include "G4SigmacPlusPlus.hh"
#include "G4BMesonZero.hh"
#include "G4AntiBMesonZero.hh"
#include "G4DMesonZero.hh"
#include "G4AntiDMesonZero.hh"
#include "G4BsMesonZero.hh"
#include "G4AntiBsMesonZero.hh"
#include "G4BcMesonPlus.hh"
#include "G4BcMesonMinus.hh"
#include "G4DsMesonPlus.hh"
#include "G4DsMesonMinus.hh"
#include "G4Eta.hh"
#include "G4EtaPrime.hh"
#include "G4Etac.hh"
#include "G4BMesonPlus.hh"
#include "G4BMesonMinus.hh"
#include "G4DMesonPlus.hh"
#include "G4DMesonMinus.hh"
#include "G4JPsi.hh"
#include "G4Upsilon.hh"
#include "G4Lambda.hh"
#include "G4AntiLambda.hh"
#include "G4SigmaPlus.hh"
#include "G4AntiSigmaPlus.hh"
#include "G4SigmaMinus.hh"
#include "G4AntiSigmaMinus.hh"
#include "G4SigmaZero.hh"
#include "G4AntiSigmaZero.hh"
#include "G4XiMinus.hh"
#include "G4XiZero.hh"
#include "G4AntiXiMinus.hh"
#include "G4AntiXiZero.hh"
#include "G4OmegaMinus.hh"
#include "G4AntiOmegaMinus.hh"
static const G4double invGeV = 1.0/CLHEP::GeV;
static const G4double invGeV2 = 1.0/(CLHEP::GeV*CLHEP::GeV);
// PDG fit constants
@@ -51,8 +121,7 @@ static const G4double pMin = .1; // fast LE calculation
static const G4double pMax = 1000.; // fast HE calculation
G4HadronNucleonXsc::G4HadronNucleonXsc()
: fLowerLimit( 0.03 * CLHEP::MeV ),
fTotalXsc(0.0), fElasticXsc(0.0), fInelasticXsc(0.0)
: fTotalXsc(0.0), fElasticXsc(0.0), fInelasticXsc(0.0)
{
fHypTotXscCof = 0.88; // for transformation pp(pn) to hyperon-nucleon
@@ -64,6 +133,11 @@ G4HadronNucleonXsc::G4HadronNucleonXsc()
thePiPlus = G4PionPlus::PionPlus();
thePiMinus = G4PionMinus::PionMinus();
thePiZero = G4PionZero::PionZero();
theD = G4Deuteron::Deuteron();
theT = G4Triton::Triton();
theA = G4Alpha::Alpha();
theHe3 = G4He3::He3();
// strange
theKPlus = G4KaonPlus::KaonPlus();
theKMinus = G4KaonMinus::KaonMinus();
theK0S = G4KaonZeroShort::KaonZeroShort();
@@ -82,10 +156,55 @@ G4HadronNucleonXsc::G4HadronNucleonXsc()
theAXi0 = G4AntiXiZero::AntiXiZero();
theOmega = G4OmegaMinus::OmegaMinus();
theAOmega = G4AntiOmegaMinus::AntiOmegaMinus();
theD = G4Deuteron::Deuteron();
theT = G4Triton::Triton();
theA = G4Alpha::Alpha();
theHe3 = G4He3::He3();
// c- and b- hyperons
theLambdaCPlus = G4LambdacPlus::LambdacPlus();
theALambdaCPlus = G4AntiLambdacPlus::AntiLambdacPlus();
theOmegaC0 = G4OmegacZero::OmegacZero();
theAOmegaC0 = G4AntiOmegacZero::AntiOmegacZero();
theSigmaCPlus = G4SigmacPlus::SigmacPlus();
theASigmaCPlus = G4AntiSigmacPlus::AntiSigmacPlus();
theSigmacPP = G4SigmacPlusPlus::SigmacPlusPlus();
theASigmacPP = G4AntiSigmacPlusPlus::AntiSigmacPlusPlus();
theSigmaC0 = G4SigmacZero::SigmacZero();
theASigmaC0 = G4AntiSigmacZero::AntiSigmacZero();
theXiCPlus = G4XicPlus::XicPlus();
theAXiCPlus = G4AntiXicPlus::AntiXicPlus();
theXiC0 = G4XicZero::XicZero();
theAXiC0 = G4AntiXicZero::AntiXicZero();
theLambdaB = G4Lambdab::Lambdab();
theALambdaB = G4AntiLambdab::AntiLambdab();
theOmegaBMinus = G4OmegabMinus::OmegabMinus();
theAOmegaBMinus = G4AntiOmegabMinus::AntiOmegabMinus();
theSigmaBMinus = G4SigmabMinus::SigmabMinus();
theASigmaBMinus = G4AntiSigmabMinus::AntiSigmabMinus();
theSigmaBPlus = G4SigmabPlus::SigmabPlus();
theASigmaBPlus = G4AntiSigmabPlus::AntiSigmabPlus();
theSigmaB0 = G4SigmabZero::SigmabZero();
theASigmaB0 = G4AntiSigmabZero::AntiSigmabZero();
theXiBMinus = G4XibMinus::XibMinus();
theAXiBMinus = G4AntiXibMinus::AntiXibMinus();
theXiB0 = G4XibZero::XibZero();
theAXiB0 = G4AntiXibZero::AntiXibZero();
//(s-) c- and b-mesons
theBMeson0 = G4BMesonZero::BMesonZero();
theABMeson0 = G4AntiBMesonZero::AntiBMesonZero();
theDMeson0 = G4DMesonZero::DMesonZero();
theADMeson0 = G4AntiDMesonZero::AntiDMesonZero();
theBsMeson0 = G4BsMesonZero::BsMesonZero();
theABsMeson0 = G4AntiBsMesonZero::AntiBsMesonZero();
theBcMesonPlus = G4BcMesonPlus::BcMesonPlus();
theBcMesonMinus = G4BcMesonMinus::BcMesonMinus();
theDsMesonPlus = G4DsMesonPlus::DsMesonPlus();
theDsMesonMinus = G4DsMesonMinus::DsMesonMinus();
theDMesonPlus = G4DMesonPlus::DMesonPlus();
theDMesonMinus = G4DMesonMinus::DMesonMinus();
theBMesonPlus = G4BMesonPlus::BMesonPlus();
theBMesonMinus = G4BMesonMinus::BMesonMinus();
theEta = G4Eta::Eta();
theEtaPrime = G4EtaPrime::EtaPrime();
theEtaC = G4Etac::Etac();
theJPsi = G4JPsi::JPsi();
theUpsilon = G4Upsilon::Upsilon();
g4calc = G4Pow::GetInstance();
}
@@ -103,222 +222,6 @@ void G4HadronNucleonXsc::CrossSectionDescription(std::ostream& outFile) const
<< "is to be used to build a cross section data set.\n";
}
G4bool
G4HadronNucleonXsc::IsApplicable(const G4DynamicParticle* aDP,
const G4Element* anElement)
{
return IsIsoApplicable(aDP, anElement->GetZasInt());
}
//////////////////////////////////////////////////////////////////////////////
G4bool
G4HadronNucleonXsc::IsIsoApplicable(const G4DynamicParticle* aDP, G4int Z)
{
G4bool applicable = false;
G4double kineticEnergy = aDP->GetKineticEnergy();
const G4ParticleDefinition* theParticle = aDP->GetDefinition();
if ( ( kineticEnergy >= fLowerLimit &&
Z > 1 && // >= He
( theParticle == theAProton ||
theParticle == theGamma ||
theParticle == theKPlus ||
theParticle == theKMinus ||
theParticle == theSMinus) ) ||
( kineticEnergy >= 0.1*fLowerLimit &&
Z > 1 && // >= He
( theParticle == theProton ||
theParticle == theNeutron ||
theParticle == thePiPlus ||
theParticle == thePiMinus ) ) ) applicable = true;
return applicable;
}
////////////////////////////////////////////////////////////////////////////////
//
// Returns hadron-nucleon Xsc according to PDG parametrisation (2005):
// http://pdg.lbl.gov/2006/reviews/hadronicrpp.pdf
G4double G4HadronNucleonXsc::HadronNucleonXscPDG2005(
const G4ParticleDefinition* theParticle,
const G4ParticleDefinition* nucleon, G4double ekin)
{
static const G4double s0 = 5.38*5.38; // in Gev^2
static const G4double eta = 0.458;
static const G4double B = 0.308;
G4double mass1 = theParticle->GetPDGMass();
if(theParticle == theGamma) { mass1 = 770.; }
G4double mass2 = nucleon->GetPDGMass();
G4double sMand = CalcMandelstamS(ekin, mass1, mass2)*invGeV2;
G4double blog = G4Log(sMand/s0);
G4double P(0.0), R1(0.0), R2(0.0);
G4bool proton = (nucleon == theProton);
G4bool neutron = (nucleon == theNeutron);
if(theParticle == theNeutron)
{
if ( proton )
{
P = 35.80;
R1 = 40.15;
R2 = -30.;
}
else
{
P = 35.45;
R1 = 42.53;
R2 = -33.34;
}
}
else if(theParticle == theProton)
{
if ( neutron )
{
P = 35.80;
R1 = 40.15;
R2 = -30.;
}
else
{
P = 35.45;
R1 = 42.53;
R2 = -33.34;
}
}
else if(theParticle == theAProton)
{
if ( neutron )
{
P = 35.80;
R1 = 40.15;
R2 = 30.;
}
else
{
P = 35.45;
R1 = 42.53;
R2 = 33.34;
}
}
else if(theParticle == theANeutron)
{
if ( proton )
{
P = 35.45;
R1 = 42.53;
R2 = 33.34;
}
else
{
P = 35.80;
R1 = 40.15;
R2 = 30.;
}
}
else if(theParticle == thePiPlus)
{
P = 20.86;
R1 = 19.24;
R2 = -6.03;
}
else if(theParticle == thePiMinus)
{
P = 20.86;
R1 = 19.24;
R2 = 6.03;
}
else if(theParticle == theKPlus)
{
if ( proton )
{
P = 17.91;
R1 = 7.14;
R2 = -13.45;
}
else
{
P = 17.87;
R1 = 5.17;
R2 = -7.23;
}
}
else if(theParticle == theKMinus)
{
if ( proton )
{
P = 17.91;
R1 = 7.14;
R2 = 13.45;
}
else
{
P = 17.97;
R1 = 5.17;
R2 = 7.23;
}
}
else if(theParticle == theK0S || theParticle == theK0L)
{
if ( proton )
{
P = 17.91;
R1 = 7.14;
}
else
{
P = 17.97;
R1 = 5.17;
}
}
else if(theParticle == theSMinus)
{
P = 35.20;
R1 = -199.;
R2 = 264.;
}
else if(theParticle == theGamma) // modify later on
{
R1 = 0.032;
}
else // as proton ???
{
if ( neutron )
{
P = 35.80;
R1 = 40.15;
R2 = -30.;
}
else
{
P = 35.45;
R1 = 42.53;
R2 = -33.34;
}
}
fTotalXsc = CLHEP::millibarn*(B*blog*blog + P + (R1 + R2)*G4Exp(-eta*blog));
fInelasticXsc = 0.75*fTotalXsc;
fElasticXsc = fTotalXsc - fInelasticXsc;
if( proton && theParticle->GetPDGCharge() > 0. && ekin < 100*MeV)
{
G4double cB = CoulombBarrier(theParticle, nucleon, ekin);
fTotalXsc *= cB;
fElasticXsc *= cB;
fInelasticXsc *= cB;
}
return fTotalXsc;
}
//////////////////////////////////////////////////////////////////////////////
//
// Returns hadron-nucleon Xsc according to PDG parametrisation (2017):
@@ -738,16 +641,11 @@ G4double G4HadronNucleonXsc::HadronNucleonXscNS(
fTotalXsc = 10./((logP + 1.273)*(logP + 1.273) + 0.05);
fElasticXsc = fTotalXsc;
}
else if( pLab < 0.4 )
else if( pLab < 0.68 )
{
fTotalXsc = 14./( (logP + 1.273)*(logP + 1.273) + 0.07);
fElasticXsc = fTotalXsc;
}
else if( pLab < 0.68 )
{
fTotalXsc = 14./( (logP + 1.273)*(logP + 1.273) + 0.07);
fElasticXsc = fTotalXsc;
}
else if( pLab < 0.85 )
{
G4double x = G4Log(pLab/0.77);
@@ -923,13 +821,10 @@ G4double G4HadronNucleonXsc::HadronNucleonXscNS(
}
else if( (theParticle == theKPlus) && proton ) // K+p
{
if( pLab < pMin )
// VI: modified low-energy part
if( pLab < 0.631 )
{
G4double lr = pLab - .38;
G4double lm = pLab - 1.;
G4double md = lm*lm + .392;
fElasticXsc = .7/(lr*lr + .076) + 2./md;
fTotalXsc = .7/(lr*lr + .076) + 2.6/md;
fElasticXsc = fTotalXsc = 12.03;
}
else if( pLab > pMax )
{
@@ -947,10 +842,11 @@ G4double G4HadronNucleonXsc::HadronNucleonXscNS(
G4double sp = std::sqrt(pLab);
G4double p2 = pLab*pLab;
G4double p4 = p2*p2;
G4double lm = pLab - 1.;
G4double md = lm*lm + .392;
fElasticXsc = LE + (cofLogE*ld2 + 2.23)/(1. - .7/sp + .1/p4) + 2./md;
fTotalXsc = LE + (cofLogT*ld2 + 19.5)/(1. + .46/sp + 1.6/p4) + 2.6/md;
// VI: tuned elastic
fElasticXsc = LE + (cofLogE*ld2 + 2.23)/(1. - .7/sp + .1/p4)
+ 2./((pLab - 0.8)*(pLab - 0.8) + 0.652);
fTotalXsc = LE + (cofLogT*ld2 + 19.5)/(1. + .46/sp + 1.6/p4)
+ 2.6/((pLab - 1.)*(pLab - 1.) + 0.392);
}
}
else if( (theParticle == theKPlus) && neutron) // K+n
@@ -1006,35 +902,8 @@ G4double G4HadronNucleonXsc::HadronNucleonXscNS(
//////////////////////////////////////////////////////////////////////////////
//
// Returns kaon-nucleon cross-section based on smoothed NS for GG model
G4double G4HadronNucleonXsc::ComputeKaonNucleonXsc(
const G4ParticleDefinition* theParticle,
const G4ParticleDefinition* nucleon, G4double ekin)
{
fTotalXsc = fElasticXsc = fInelasticXsc = 0.0;
static const G4double kaonE1 = 80*MeV;
static const G4double kaonE2 = 100*MeV;
if(ekin <= kaonE1) {
HadronNucleonXscNS(theParticle, nucleon, ekin);
} else if(ekin >= kaonE2) {
KaonNucleonXscVG(theParticle, nucleon, ekin);
} else {
G4double stot = KaonNucleonXscVG(theParticle, nucleon, kaonE2);
G4double sel = fElasticXsc;
G4double sinel = fInelasticXsc;
HadronNucleonXscNS(theParticle, nucleon, kaonE1);
G4double f = (ekin - kaonE1)/(kaonE2 - kaonE1);
fTotalXsc += (stot - fTotalXsc)*f;
fElasticXsc += (sel - fElasticXsc)*f;
fInelasticXsc += (sinel - fInelasticXsc)*f;
}
return fTotalXsc;
}
//////////////////////////////////////////////////////////////////////////////
//
// Returns kaon-nucleon cross-section based on smoothed NS for GG model
// Returns kaon-nucleon cross-section based on smoothed NS
// tuned for the Glauber-Gribov hadron model for Z>1
G4double G4HadronNucleonXsc::KaonNucleonXscGG(
const G4ParticleDefinition* theParticle,
@@ -1042,13 +911,13 @@ G4double G4HadronNucleonXsc::KaonNucleonXscGG(
{
fTotalXsc = fElasticXsc = fInelasticXsc = 0.0;
if(theParticle == theKMinus || theParticle == theKPlus) {
ComputeKaonNucleonXsc(theParticle, nucleon, ekin);
KaonNucleonXscVG(theParticle, nucleon, ekin);
} else if(theParticle == theK0S || theParticle == theK0L) {
G4double stot = ComputeKaonNucleonXsc(theKMinus, nucleon, ekin);
G4double stot = KaonNucleonXscVG(theKMinus, nucleon, ekin);
G4double sel = fElasticXsc;
G4double sinel = fInelasticXsc;
stot += ComputeKaonNucleonXsc(theKPlus, nucleon, ekin);
stot += KaonNucleonXscVG(theKPlus, nucleon, ekin);
sel += fElasticXsc;
sinel += fInelasticXsc;
fTotalXsc = stot*0.5;
@@ -1155,13 +1024,10 @@ G4double G4HadronNucleonXsc::KaonNucleonXscVG(
}
else if( (theParticle == theKPlus) && proton ) // K+p
{
if( pLab < pMin )
// VI: modified low-energy part
if( pLab < 0.631 )
{
G4double lr = pLab - .38;
G4double lm = pLab - 1.;
G4double md = lm*lm + .392;
fElasticXsc = .7/(lr*lr + .076) + 2./md;
fTotalXsc = 2.6/md; // vg version
fElasticXsc = fTotalXsc = 12.03;
}
else if( pLab > pMax )
{
@@ -1179,10 +1045,11 @@ 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
fElasticXsc = LE + (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
// VI: tuned elastic
fElasticXsc = LE + (cofLogE*ld2 + 2.23)/(1. - .7/sp + .1/p4)
+ 2./((pLab - 0.8)*(pLab - 0.8) + 0.652);
fTotalXsc = LE + (cofLogT*ld2 + 19.5)/(1. + .46/sp + 1.6/p4)
+ 2.6/((pLab - 1.)*(pLab - 1.) + 0.392);
}
}
else if( (theParticle == theKPlus) && neutron) // K+n
@@ -1236,6 +1103,153 @@ G4double G4HadronNucleonXsc::KaonNucleonXscVG(
return fTotalXsc;
}
//////////////////////////////////////////////////////////////////////////////
//
// Returns hyperon-nucleon cross-section using NS x-section for protons
G4double G4HadronNucleonXsc::HyperonNucleonXscNS(
const G4ParticleDefinition* theParticle,
const G4ParticleDefinition* nucleon, G4double ekin)
{
G4double coeff = 1.0;
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( theParticle == theL || theParticle == theSPlus ||
theParticle == theSMinus || theParticle == theS0 ||
theParticle == theAntiL || theParticle == theASPlus ||
theParticle == theASMinus || theParticle == theAS0 )
{
coeff = lBarCof1S;
} else if( theParticle == theXiMinus || theParticle == theXi0 ||
theParticle == theAXiMinus || theParticle == theAXi0 )
{
coeff = lBarCof2S;
}
else if( theParticle == theOmega || theParticle == theAOmega)
{
coeff = lBarCof3S;
}
else if( theParticle == theLambdaCPlus || theParticle == theALambdaCPlus ||
theParticle == theSigmaCPlus || theParticle == theASigmaCPlus ||
theParticle == theSigmacPP || theParticle == theASigmacPP ||
theParticle == theSigmaC0 || theParticle == theASigmaC0
)
{
coeff = lBarCof1C;
}
else if( theParticle == theOmegaC0 || theParticle == theAOmegaC0 )
{
coeff = lBarCof2SC;
}
else if( theParticle == theXiCPlus || theParticle == theXiC0 ||
theParticle == theAXiCPlus || theParticle == theAXiC0)
{
coeff = lBarCofSC;
}
else if( theParticle == theLambdaB || theParticle == theALambdaB ||
theParticle == theSigmaBPlus || theParticle == theASigmaBPlus ||
theParticle == theSigmaBMinus || theParticle == theASigmaBMinus ||
theParticle == theSigmaB0 || theParticle == theASigmaB0
)
{
coeff = lBarCof1B;
}
else if( theParticle == theOmegaBMinus || theParticle == theAOmegaBMinus)
{
coeff = lBarCof2SB;
}
else if( theParticle == theXiBMinus || theParticle == theXiB0 ||
theParticle == theAXiBMinus || theParticle == theAXiB0)
{
coeff = lBarCofSB;
}
fTotalXsc = coeff*HadronNucleonXscNS( theProton, nucleon, ekin);
fInelasticXsc *= coeff;
fElasticXsc *= coeff;
return fTotalXsc;
}
//////////////////////////////////////////////////////////////////////////////
//
// Returns hyperon-nucleon cross-section using NS x-section for protons
G4double G4HadronNucleonXsc::SCBMesonNucleonXscNS( const G4ParticleDefinition* theParticle,
const G4ParticleDefinition* nucleon, G4double ekin )
{
G4double coeff(1.0);
// static const G4double lMesCof1S = 0.82; // Kp/piP
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( theParticle == theBMeson0 || theParticle == theABMeson0 ||
theParticle == theBMesonPlus || theParticle == theBMesonMinus )
{
coeff = llMesCof1B;
}
else if(theParticle == theDMeson0 || theParticle == theADMeson0 ||
theParticle == theDMesonPlus || theParticle == theDMesonMinus )
{
coeff = llMesCof1C;
}
else if(theParticle == theBsMeson0 || theParticle == theABsMeson0 )
{
coeff = llMesCofSB;
}
else if(theParticle == theBcMesonPlus || theParticle == theBcMesonMinus )
{
coeff = llMesCofCB;
}
else if(theParticle == theDsMesonPlus || theParticle == theDsMesonMinus )
{
coeff = llMesCofSC;
}
else if(theParticle == theBMesonPlus || theParticle == theBMesonMinus )
{
coeff = llMesCof1B;
}
else if(theParticle == theDMesonPlus || theParticle == theDMesonMinus )
{
coeff = llMesCof1C;
}
else if(theParticle == theEtaC || theParticle == theJPsi )
{
coeff = llMesCof2C;
}
else if(theParticle == theUpsilon )
{
coeff = llMesCof2B;
}
else if(theParticle == theEta )
{
coeff = llMesCofEta;
}
else if(theParticle == theEtaPrime )
{
coeff = llMesCofEtaP;
}
fTotalXsc = coeff*HadronNucleonXscNS( thePiPlus, nucleon, ekin);
fElasticXsc *= coeff;
fInelasticXsc *= coeff;
return fTotalXsc;
}
////////////////////////////////////////////////////////////////////////////////
//
// Returns hadron-nucleon cross-section based on V. Uzjinsky parametrisation of
@@ -33,8 +33,6 @@
//
// Author Ivantchenko, Geant4, 30 July 2010
//
// Modifications:
//
#include "G4IonProtonCrossSection.hh"
#include "G4SystemOfUnits.hh"
@@ -42,6 +40,7 @@
#include "G4DynamicParticle.hh"
#include "G4Element.hh"
#include "G4Proton.hh"
#include "G4Log.hh"
using namespace std;
@@ -70,7 +69,7 @@ G4IonProtonCrossSection::GetElementCrossSection(
G4double e = dp->GetKineticEnergy()*CLHEP::proton_mass_c2/p->GetPDGMass();
G4int Z = p->GetAtomicNumber();
G4int A = p->GetAtomicMass();
return theForward->IsoCrossSection(e, Z, A);
return theForward->IsoCrossSection(e, G4Log(e), Z, A);
}
void G4IonProtonCrossSection::BuildPhysicsTable(const G4ParticleDefinition& part)
@@ -33,6 +33,10 @@
#include "G4IonTable.hh"
#include "G4HadTmpUtil.hh"
#include "G4NistManager.hh"
#include "G4Material.hh"
#include "G4Element.hh"
#include "G4Isotope.hh"
#include "G4ElementVector.hh"
#include "G4MuonMinus.hh"
#include "G4MuonPlus.hh"
@@ -41,7 +45,7 @@ using namespace std;
using namespace CLHEP;
G4MuNeutrinoNucleusTotXsc::G4MuNeutrinoNucleusTotXsc()
: G4VCrossSectionDataSet("NuElectronTotXsc")
: G4VCrossSectionDataSet("NuMuNuclTotXsc")
{
fCofXsc = 1.e-38*cm2/GeV;
@@ -56,7 +60,7 @@ G4MuNeutrinoNucleusTotXsc::G4MuNeutrinoNucleusTotXsc()
fCofS = 5.*fSin2tW*fSin2tW/9.;
fCofL = 1. - fSin2tW + fCofS;
G4cout<<"fCosL = "<<fCofL<<", fCofS = "<<fCofS<<G4endl;
// G4cout<<"fCosL = "<<fCofL<<", fCofS = "<<fCofS<<G4endl;
fCutEnergy = 0.; // default value
@@ -64,6 +68,10 @@ G4MuNeutrinoNucleusTotXsc::G4MuNeutrinoNucleusTotXsc()
fIndex = 50;
fTotXsc = 0.;
fCcTotRatio = 0.75; // from nc/cc~0.33 ratio
fCcFactor = fNcFactor = 1.;
theMuonMinus = G4MuonMinus::MuonMinus();
theMuonPlus = G4MuonPlus::MuonPlus();
}
@@ -74,7 +82,7 @@ G4MuNeutrinoNucleusTotXsc::~G4MuNeutrinoNucleusTotXsc()
//////////////////////////////////////////////////////
G4bool
G4MuNeutrinoNucleusTotXsc::IsElementApplicable( const G4DynamicParticle* aPart, G4int, const G4Material*)
G4MuNeutrinoNucleusTotXsc::IsIsoApplicable( const G4DynamicParticle* aPart, G4int, G4int, const G4Element*, const G4Material*)
{
G4bool result = false;
G4String pName = aPart->GetDefinition()->GetParticleName();
@@ -86,6 +94,43 @@ G4MuNeutrinoNucleusTotXsc::IsElementApplicable( const G4DynamicParticle* aPart,
return result;
}
//////////////////////////////////////
G4double G4MuNeutrinoNucleusTotXsc::GetElementCrossSection(const G4DynamicParticle* part,
G4int Z, const G4Material* mat )
{
G4int Zi(0);
size_t i(0), j(0);
const G4ElementVector* theElementVector = mat->GetElementVector();
for ( i = 0; i < theElementVector->size(); ++i )
{
Zi = (*theElementVector)[i]->GetZasInt();
if( Zi == Z ) break;
}
const G4Element* elm = (*theElementVector)[i];
size_t nIso = elm->GetNumberOfIsotopes();
G4double fact = 0.0;
G4double xsec = 0.0;
const G4Isotope* iso = nullptr;
const G4IsotopeVector* isoVector = elm->GetIsotopeVector();
const G4double* abundVector = elm->GetRelativeAbundanceVector();
for (j = 0; j<nIso; ++j)
{
iso = (*isoVector)[j];
G4int A = iso->GetN();
if( abundVector[j] > 0.0 && IsIsoApplicable(part, Z, A, elm, mat) )
{
fact += abundVector[j];
xsec += abundVector[j]*GetIsoCrossSection( part, Z, A, iso, elm, mat);
}
}
if( fact > 0.0) { xsec /= fact; }
return xsec;
}
////////////////////////////////////////////////////
//
//
@@ -93,6 +138,9 @@ G4MuNeutrinoNucleusTotXsc::IsElementApplicable( const G4DynamicParticle* aPart,
G4double G4MuNeutrinoNucleusTotXsc::GetIsoCrossSection(const G4DynamicParticle* aPart, G4int, G4int A,
const G4Isotope*, const G4Element*, const G4Material* )
{
fCcFactor = fNcFactor = 1.;
fCcTotRatio = 0.25;
G4double ccnuXsc, ccanuXsc, ncXsc, totXsc(0.);
G4double energy = aPart->GetTotalEnergy();
@@ -100,29 +148,46 @@ G4double G4MuNeutrinoNucleusTotXsc::GetIsoCrossSection(const G4DynamicParticle*
G4int index = GetEnergyIndex(energy);
if( index >= fIndex )
{
G4double pm = proton_mass_c2;
G4double s2 = 2.*energy*pm+pm*pm;
G4double aa = 1.;
G4double bb = 1.085;
G4double mw = 80.385*GeV;
fCcFactor = bb/(1.+ aa*s2/mw/mw);
G4double mz = 91.1876*GeV;
fNcFactor = bb/(1.+ aa*s2/mz/mz);
}
ccnuXsc = GetNuMuTotCsXsc(index, energy);
ccnuXsc *= fCcFactor;
ccanuXsc = GetANuMuTotCsXsc(index, energy);
ccanuXsc *= fCcFactor;
if( pName == "nu_mu")
{
ncXsc = fCofL*ccnuXsc + fCofS*ccanuXsc;
ncXsc *= fNcFactor/fCcFactor;
totXsc = ccnuXsc + ncXsc;
if( totXsc > 0.) fCcTotRatio = ccnuXsc/totXsc;
}
else if( pName == "anti_nu_mu")
{
ncXsc = fCofL*ccanuXsc + fCofS*ccnuXsc;
ncXsc *= fNcFactor/fCcFactor;
totXsc = ccanuXsc + ncXsc;
if( totXsc > 0.) fCcTotRatio = ccanuXsc/totXsc;
}
else return totXsc;
// totXsc -= ncXsc; // to test experimentally available cc part
totXsc *= fCofXsc; //*energy;
totXsc *= energy; // + 0.5*emass;
totXsc *= fCofXsc;
totXsc *= energy;
totXsc *= A; // incoherent sum over all isotope nucleons
totXsc *= fBiasingFactor; // biasing up, if set >1
fTotXsc = totXsc;
return totXsc;
}
@@ -156,7 +221,7 @@ G4double G4MuNeutrinoNucleusTotXsc::GetNuMuTotCsXsc(G4int index, G4double energy
{
G4double xsc(0.);
if( index <= 0 || energy < theMuonMinus->GetPDGMass() ) xsc = 0.;
if( index <= 0 || energy < theMuonMinus->GetPDGMass() ) xsc = fNuMuTotXsc[0];
else if (index >= fIndex) xsc = fNuMuTotXsc[fIndex-1];
else
{
@@ -183,7 +248,7 @@ G4double G4MuNeutrinoNucleusTotXsc::GetANuMuTotCsXsc(G4int index, G4double energ
{
G4double xsc(0.);
if( index <= 0 || energy < theMuonPlus->GetPDGMass() ) xsc = 0.;
if( index <= 0 || energy < theMuonPlus->GetPDGMass() ) xsc = fANuMuTotXsc[0];
else if (index >= fIndex) xsc = fANuMuTotXsc[fIndex-1];
else
{
@@ -263,7 +328,7 @@ const G4double G4MuNeutrinoNucleusTotXsc::fNuMuTotXsc[50] =
0.857978, 0.835424, 0.814112, 0.794314, 0.776204,
0.759884, 0.745394, 0.732719, 0.721809, 0.712164,
0.704299, 0.697804, 0.692491, 0.688137, 0.68448,
0.681232, 0.676128, 0.674154, 0.670553, 0.666034};
0.681232, 0.676128, 0.674154, 0.670553, 0.666034 };
@@ -273,13 +338,13 @@ const G4double G4MuNeutrinoNucleusTotXsc::fNuMuTotXsc[50] =
const G4double G4MuNeutrinoNucleusTotXsc::fANuMuTotXsc[50] =
{
0.0291812, 0.0979725, 0.136884, 0.16794, 0.194698,
0.218468, 0.23992, 0.259241, 0.27665, 0.292251,
0.30612, 0.318314, 0.328886, 0.337885, 0.345464,
0.351495, 0.356131, 0.359448, 0.361531, 0.362474,
0.362382, 0.361365, 0.359538, 0.357024, 0.353943,
0.350422, 0.346685, 0.342662, 0.338567, 0.334514,
0.330612, 0.326966, 0.323668, 0.320805, 0.318451,
0.316671, 0.315514, 0.315013, 0.315187, 0.316036,
0.317541, 0.319667, 0.322362, 0.325556, 0.329159,
0.332577, 0.337133, 0.341214, 0.345128, 0.347657};
0.0291812, 0.0979725, 0.136884, 0.16794, 0.194698,
0.218468, 0.23992, 0.259241, 0.27665, 0.292251,
0.30612, 0.318314, 0.328886, 0.337885, 0.345464,
0.351495, 0.356131, 0.359448, 0.361531, 0.362474,
0.362382, 0.361365, 0.359538, 0.357024, 0.353943,
0.350422, 0.346685, 0.342662, 0.338567, 0.334514,
0.330612, 0.326966, 0.323668, 0.320805, 0.318451,
0.316671, 0.315514, 0.315013, 0.315187, 0.316036,
0.317541, 0.319667, 0.322362, 0.325556, 0.329159,
0.332577, 0.337133, 0.341214, 0.345128, 0.347657 };
@@ -79,7 +79,7 @@ G4NeutrinoElectronCcXsc::IsElementApplicable( const G4DynamicParticle* aPart, G4
G4double minEnergy = 0., energy = aPart->GetTotalEnergy();
G4double fmass, emass = electron_mass_c2;
if( pName == "nu_mu" || pName == "anti_nu_mu" ) fmass = theMuonMinus->GetPDGMass();
if( pName == "anti_nu_e" || pName == "nu_mu" || pName == "anti_nu_mu" ) fmass = theMuonMinus->GetPDGMass();
else if( pName == "nu_tau" || pName == "anti_nu_tau" ) fmass = theTauMinus->GetPDGMass();
else fmass = emass;
@@ -108,7 +108,7 @@ GetElementCrossSection(const G4DynamicParticle* aPart, G4int ZZ,
emass2 = emass*emass;
totS = 2.*energy*emass + emass2;
if( pName == "nu_mu")
if( pName == "anti_nu_e" || pName == "nu_mu")
{
fmass = theMuonMinus->GetPDGMass();
fmass2 = fmass*fmass;
@@ -144,6 +144,22 @@ GetElementCrossSection(const G4DynamicParticle* aPart, G4int ZZ,
}
// if( energy <= electron_mass_c2 ) return result;
G4double aa = 1.;
G4double bb = 1.7;
G4double gw = 2.141*GeV;
G4double dd = 5000.;
G4double mw = 80.385*GeV;
if( energy > 50.*GeV )
{
result *= bb;
result /= 1.+ aa*totS/mw/mw;
if( pName == "anti_nu_e")
{
result *= 1. + dd*gw*gw*totS/( (totS-mw*mw)*(totS-mw*mw)+gw*gw*mw*mw );
}
}
result *= fCofXsc; //*energy;
result *= energy + 0.5*emass;
result *= ZZ; // incoherent sum over all element electrons
@@ -162,6 +162,27 @@ GetElementCrossSection(const G4DynamicParticle* aPart, G4int ZZ,
// G4cout<<"cofL2 + cofR2/3. = "<<result<<G4endl;
// result -= 0.5*cofL*cofR*electron_mass_c2/energy;
G4double aa = 1.;
G4double bb = 1.7;
G4double gw = 2.141*GeV;
G4double dd = 5000.;
G4double mw = 80.385*GeV;
G4double mz = 91.1876*GeV;
G4double emass = electron_mass_c2;
G4double totS = 2.*energy*emass + emass*emass;
if( energy > 50.*GeV )
{
result *= bb;
result /= 1.+ aa*totS/mz/mz;
if( pName == "anti_nu_e")
{
result *= 1. + dd*gw*gw*totS/( (totS-mw*mw)*(totS-mw*mw)+gw*gw*mw*mw );
}
}
result *= fCofXsc; //*energy;
result *= ZZ; // incoherent sum over all element electrons
@@ -47,6 +47,7 @@
#include "G4PhysicsVector.hh"
#include "G4DynamicParticle.hh"
#include "Randomize.hh"
#include "G4Log.hh"
// factory
#include "G4CrossSectionFactory.hh"
@@ -69,7 +70,7 @@ const G4int G4NeutronCaptureXS::amin[] = {
0, 235};
const G4int G4NeutronCaptureXS::amax[] = {
0,
1, 4, 7, 9, 11, 13, 15, 18, 19, 22, //1-10
2, 4, 7, 9, 11, 13, 15, 18, 19, 22, //1-10
23, 26, 27, 30, 31, 34, 37, 40, 41, 48, //11-20
45, 50, 51, 54, 55, 58, 59, 64, 65, 70, //21-30
71, 76, 75, 0, 0, 0, 0, 0, 0, 96, //31-40
@@ -95,7 +96,9 @@ G4NeutronCaptureXS::G4NeutronCaptureXS()
G4cout << "G4NeutronCaptureXS::G4NeutronCaptureXS: Initialise for Z < "
<< MAXZCAPTURE << G4endl;
}
isMaster = false;
logElimit = G4Log(elimit);
isMaster = false;
fIdxXSTable = 0;
}
G4NeutronCaptureXS::~G4NeutronCaptureXS()
@@ -129,20 +132,26 @@ G4NeutronCaptureXS::IsIsoApplicable(const G4DynamicParticle*,
G4double
G4NeutronCaptureXS::GetElementCrossSection(const G4DynamicParticle* aParticle,
G4int Z, const G4Material*)
G4int ZZ, const G4Material*)
{
G4double xs = 0.0;
G4double ekin = aParticle->GetKineticEnergy();
if(ekin > emax || Z < 1 || Z >= MAXZCAPTURE) { return xs; }
if(ekin < elimit) { ekin = elimit; }
if(ekin > emax) { return xs; }
G4int Z = std::min(ZZ, MAXZCAPTURE-1);
G4double logEkin = aParticle->GetLogKineticEnergy();
if(ekin < elimit) { ekin = elimit; logEkin = logElimit; }
// element was not initialised
G4PhysicsVector* pv = data->GetElementData(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); }
if(ekin < e1) {
xs = (*pv)[0]*std::sqrt(e1/ekin);
} else if(ekin <= pv->GetMaxEnergy()) {
xs = pv->Value(ekin, logEkin, fIdxXSTable);
}
if(verboseLevel > 0){
G4cout << "ekin= " << ekin << ", xs= " << xs << G4endl;
@@ -156,45 +165,60 @@ G4NeutronCaptureXS::GetIsoCrossSection(const G4DynamicParticle* aParticle,
const G4Isotope*, const G4Element*,
const G4Material*)
{
return IsoCrossSection(aParticle->GetKineticEnergy(), Z, A);
return IsoCrossSection(aParticle->GetKineticEnergy(),
aParticle->GetLogKineticEnergy(),
Z, A);
}
G4double G4NeutronCaptureXS::IsoCrossSection(G4double ekin, G4int Z, G4int A)
G4double G4NeutronCaptureXS::IsoCrossSection(G4double eKin, G4double logE,
G4int ZZ, G4int A)
{
G4double xs = 0.0;
if(ekin > emax || Z < 1 || Z >= MAXZCAPTURE) { return xs; }
if(ekin < elimit) { ekin = elimit; }
if(eKin > emax) { return xs; }
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); }
if(verboseLevel > 0) {
G4cout << "G4NeutronCaptureXS::IsoXS: Ekin(MeV)= " << ekin/MeV
<< " xs(b)= " << xs/barn
<< " Z= " << Z << " A= " << A << G4endl;
}
return xs;
G4int Z = std::min(ZZ, MAXZCAPTURE-1);
G4double ekin = eKin;
G4double logEkin = logE;
if(ekin < elimit) {
ekin = elimit;
logEkin = logElimit;
}
// isotope data are not available or applicable
G4PhysicsVector* pv = data->GetElementData(Z);
if(pv) {
G4double e1 = pv->Energy(1);
if(ekin < e1) { xs = (*pv)[1]*std::sqrt(e1/ekin); }
else if(ekin <= pv->GetMaxEnergy()) { xs = pv->Value(ekin); }
if(verboseLevel > 0) {
G4cout << "G4NeutronCaptureXS::IsoXS: Ekin(MeV)= " << ekin/MeV
<< " xs(b)= " << xs/barn
<< " Z= " << Z << " A= " << A << G4endl;
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);
if(ekin < e1) {
xs = (*pv)[1]*std::sqrt(e1/ekin);
} else if(ekin <= pv->GetMaxEnergy()) {
xs = pv->Value(ekin, logEkin, fIdxXSTable);
}
}
}
if(verboseLevel > 0) {
G4cout << "G4NeutronCaptureXS::IsoXS: Ekin(MeV)= " << ekin/MeV
<< " xs(b)= " << xs/barn
<< " Z= " << Z << " A= " << A << G4endl;
}
return xs;
}
const G4Isotope*
G4NeutronCaptureXS::SelectIsotope(const G4Element* anElement,
G4double kinEnergy)
G4double kinEnergy, G4double logE)
{
size_t nIso = anElement->GetNumberOfIsotopes();
const G4Isotope* iso = anElement->GetIsotope(0);
@@ -222,7 +246,7 @@ G4NeutronCaptureXS::SelectIsotope(const G4Element* anElement,
if(nn < nIso) { temp.resize(nIso, 0.); }
for (j=0; j<nIso; ++j) {
sum += abundVector[j]*IsoCrossSection(kinEnergy, Z,
sum += abundVector[j]*IsoCrossSection(kinEnergy, logE, Z,
anElement->GetIsotope(j)->GetN());
temp[j] = sum;
}
@@ -280,10 +304,7 @@ G4NeutronCaptureXS::BuildPhysicsTable(const G4ParticleDefinition& p)
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 >= MAXZCAPTURE) { Z = MAXZCAPTURE-1; }
//G4cout << "Z= " << Z << G4endl;
// Initialisation
G4int Z = std::min(((*theElmTable)[i])->GetZasInt(),MAXZCAPTURE-1);
if(!data->GetElementData(Z)) { Initialise(Z, path); }
}
}
@@ -44,9 +44,8 @@
#include "G4PhysicsLogVector.hh"
#include "G4PhysicsVector.hh"
#include "G4ComponentGGHadronNucleusXsc.hh"
#include "G4HadronNucleonXsc.hh"
#include "G4NistManager.hh"
#include "G4Proton.hh"
#include "G4Neutron.hh"
#include <iostream>
#include <fstream>
@@ -60,7 +59,7 @@ G4_DECLARE_XS_FACTORY(G4NeutronElasticXS);
using namespace std;
G4PhysicsVector* G4NeutronElasticXS::data[] = {nullptr};
G4double G4NeutronElasticXS::coeff[] = {1.0};
G4double G4NeutronElasticXS::coeff[] = {0.0};
#ifdef G4MULTITHREADED
G4Mutex G4NeutronElasticXS::neutronElasticXSMutex = G4MUTEX_INITIALIZER;
@@ -69,8 +68,8 @@ G4double G4NeutronElasticXS::coeff[] = {1.0};
G4NeutronElasticXS::G4NeutronElasticXS()
: G4VCrossSectionDataSet(Default_Name()),
ggXsection(nullptr),
fNucleon(nullptr),
proton(G4Proton::Proton()),
neutron(G4Neutron::Neutron()),
fIdxXSTable(0),
isMaster(false)
{
// verboseLevel = 0;
@@ -78,21 +77,19 @@ G4NeutronElasticXS::G4NeutronElasticXS()
G4cout << "G4NeutronElasticXS::G4NeutronElasticXS Initialise for Z < "
<< MAXZEL << G4endl;
}
nist = G4NistManager::Instance();
ggXsection = new G4ComponentGGHadronNucleusXsc();
SetForAllAtomsAndEnergies(true);
}
G4NeutronElasticXS::~G4NeutronElasticXS()
{
//std::cout << "delete G4NeutronElasticXS " << fNucleon
// << " " << ggXsection << std::endl;
delete fNucleon;
if(isMaster) {
for(G4int i=0; i<MAXZEL; ++i) {
delete data[i];
data[i] = nullptr;
}
}
//std::cout << "delete G4NeutronElasticXS done " << std::endl;
}
void G4NeutronElasticXS::CrossSectionDescription(std::ostream& outFile) const
@@ -127,18 +124,13 @@ G4NeutronElasticXS::GetElementCrossSection(const G4DynamicParticle* aParticle,
// element was not initialised
if(!pv) { return xs; }
if(ekin <= pv->Energy(0)) { return (*pv)[0]; }
if(ekin <= pv->GetMaxEnergy()) {
xs = pv->Value(ekin);
} else if(1 == Z) {
fNucleon->GetHadronNucleonXscNS(aParticle, proton);
xs = coeff[1]*fNucleon->GetElasticHadronNucleonXsc();
if(ekin <= pv->Energy(0)) {
xs = (*pv)[0];
} else if(ekin <= pv->GetMaxEnergy()) {
xs = pv->Value(ekin, aParticle->GetLogKineticEnergy(), fIdxXSTable);
} else {
G4int Amean =
G4lrint(G4NistManager::Instance()->GetAtomicMassAmu(Z));
ggXsection->GetIsoCrossSection(aParticle, Z, Amean);
xs = coeff[Z]*ggXsection->GetElasticGlauberGribovXsc();
xs = coeff[Z]*ggXsection->GetElasticElementCrossSection(neutron,
ekin, Z, nist->GetAtomicMassAmu(Z));
}
if(verboseLevel > 0){
@@ -164,14 +156,12 @@ G4NeutronElasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
FatalException, ed, "");
return;
}
if(!ggXsection) { ggXsection = new G4ComponentGGHadronNucleusXsc(); }
if(!fNucleon) { fNucleon = new G4HadronNucleonXsc(); }
if(!data[1]) {
if(0. == coeff[0]) {
#ifdef G4MULTITHREADED
G4MUTEXLOCK(&neutronElasticXSMutex);
if(!data[1]) {
if(0. == coeff[0]) {
#endif
for(G4int i=0; i<MAXZEL; ++i) { coeff[i] = 1.0; }
isMaster = true;
#ifdef G4MULTITHREADED
}
@@ -186,26 +176,17 @@ G4NeutronElasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
// Build the complete string identifying the file with the data set
char* path = getenv("G4PARTICLEXSDATA");
G4DynamicParticle* dynParticle =
new G4DynamicParticle(G4Neutron::Neutron(),G4ThreeVector(1,0,0),1);
// 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 >= MAXZEL) { Z = MAXZEL-1; }
//G4cout << "Z= " << Z << G4endl;
// Initialisation
if(!data[Z]) { Initialise(Z, dynParticle, path); }
G4int Z = std::min(((*theElmTable)[i])->GetZasInt(),MAXZEL-1);
if(!data[Z]) { Initialise(Z, path); }
}
delete dynParticle;
}
}
void
G4NeutronElasticXS::Initialise(G4int Z, G4DynamicParticle* dp,
const char* p)
void G4NeutronElasticXS::Initialise(G4int Z, const char* p)
{
if(data[Z]) { return; }
const char* path = p;
@@ -234,7 +215,7 @@ G4NeutronElasticXS::Initialise(G4int Z, G4DynamicParticle* dp,
G4Exception("G4NeutronElasticXS::Initialise(..)","had014",
FatalException, ed, "Check G4PARTICLEXSDATA");
return;
}else{
} else {
if(verboseLevel > 1) {
G4cout << "file " << ost.str()
<< " is opened by G4NeutronElasticXS" << G4endl;
@@ -249,20 +230,11 @@ G4NeutronElasticXS::Initialise(G4int Z, G4DynamicParticle* dp,
FatalException, ed, "Check G4PARTICLEXSDATA");
return;
}
// smooth transition
G4double sig1 = (*(data[Z]))[data[Z]->GetVectorLength()-1];
dp->SetKineticEnergy(data[Z]->GetMaxEnergy());
G4double sig2 = 0.0;
if(1 == Z) {
fNucleon->GetHadronNucleonXscNS(dp, proton);
sig2 = fNucleon->GetElasticHadronNucleonXsc();
} else {
G4int Amean =
G4lrint(G4NistManager::Instance()->GetAtomicMassAmu(Z));
ggXsection->GetIsoCrossSection(dp, Z, Amean);
sig2 = ggXsection->GetElasticGlauberGribovXsc();
}
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; }
}
}
@@ -33,8 +33,7 @@
//
// Author Ivantchenko, Geant4, 3-Aug-09
//
// Modifications:
//
#include "G4NeutronInelasticXS.hh"
#include "G4Neutron.hh"
@@ -44,9 +43,7 @@
#include "G4PhysicsLogVector.hh"
#include "G4PhysicsVector.hh"
#include "G4ComponentGGHadronNucleusXsc.hh"
#include "G4HadronNucleonXsc.hh"
#include "G4NistManager.hh"
#include "G4Proton.hh"
#include "Randomize.hh"
#include <iostream>
@@ -74,7 +71,7 @@ const G4int G4NeutronInelasticXS::amin[] = {
0, 235};
const G4int G4NeutronInelasticXS::amax[] = {
0,
1, 4, 7, 9, 11, 13, 15, 18, 19, 22, //1-10
2, 4, 7, 9, 11, 13, 15, 18, 19, 22, //1-10
23, 26, 27, 30, 31, 34, 37, 40, 41, 48, //11-20
45, 50, 51, 54, 55, 58, 59, 64, 65, 70, //21-30
71, 76, 75, 0, 0, 0, 0, 0, 0, 96, //31-40
@@ -95,7 +92,8 @@ G4ElementData* G4NeutronInelasticXS::data = nullptr;
G4NeutronInelasticXS::G4NeutronInelasticXS()
: G4VCrossSectionDataSet(Default_Name()),
proton(G4Proton::Proton()), emax(20*CLHEP::MeV)
neutron(G4Neutron::Neutron()),
emax(20*CLHEP::MeV)
{
// verboseLevel = 0;
if(verboseLevel > 0){
@@ -103,16 +101,14 @@ G4NeutronInelasticXS::G4NeutronInelasticXS()
<< MAXZINEL << G4endl;
}
ggXsection = new G4ComponentGGHadronNucleusXsc();
fNucleon = new G4HadronNucleonXsc();
nist = G4NistManager::Instance();
SetForAllAtomsAndEnergies(true);
isMaster = false;
fIdxXSTable = 0;
}
G4NeutronInelasticXS::~G4NeutronInelasticXS()
{
//G4cout << "G4NeutronInelasticXS::~G4NeutronInelasticXS() "
// << " isMaster= " << isMaster << " data: " << data << G4endl;
delete fNucleon;
if(isMaster) { delete data; data = nullptr; }
}
@@ -149,23 +145,18 @@ G4double G4NeutronInelasticXS::GetElementCrossSection(
G4int Z = (ZZ >= MAXZINEL) ? MAXZINEL - 1 : ZZ;
G4PhysicsVector* pv = data->GetElementData(Z);
const G4PhysicsVector* pv = data->GetElementData(Z);
// G4cout << "G4NeutronInelasticXS::GetCrossSection e= " << ekin
// << " Z= " << Z << G4endl;
// element was not initialised
// element was not initialised or low energy
if(!pv || ekin <= pv->Energy(0)) { return xs; }
if(ekin <= pv->GetMaxEnergy()) {
xs = pv->Value(ekin);
} else if(1 == Z) {
fNucleon->GetHadronNucleonXscNS(aParticle, proton);
xs = coeff[1]*fNucleon->GetInelasticHadronNucleonXsc();
} else {
G4int Amean =
G4lrint(G4NistManager::Instance()->GetAtomicMassAmu(Z));
ggXsection->GetIsoCrossSection(aParticle, Z, Amean);
xs = coeff[Z]*ggXsection->GetInelasticGlauberGribovXsc();
xs = pv->Value(ekin, aParticle->GetLogKineticEnergy(), fIdxXSTable);
} else {
xs = coeff[Z]*ggXsection->GetInelasticElementCrossSection(neutron,
ekin, Z, nist->GetAtomicMassAmu(Z));
}
if(verboseLevel > 0) {
@@ -182,11 +173,13 @@ G4double G4NeutronInelasticXS::GetIsoCrossSection(
const G4Isotope*, const G4Element*,
const G4Material*)
{
return IsoCrossSection(aParticle->GetKineticEnergy(), Z, A);
return IsoCrossSection(aParticle->GetKineticEnergy(),
aParticle->GetLogKineticEnergy(), Z, A);
}
G4double
G4NeutronInelasticXS::IsoCrossSection(G4double ekin, G4int ZZ, G4int A)
G4NeutronInelasticXS::IsoCrossSection(G4double ekin, G4double logekin,
G4int ZZ, G4int A)
{
G4double xs = 0.0;
G4int Z = (ZZ >= MAXZINEL) ? MAXZINEL - 1 : ZZ;
@@ -196,22 +189,17 @@ G4NeutronInelasticXS::IsoCrossSection(G4double ekin, G4int ZZ, G4int A)
<< " Amin= " << amin[Z] << " Amax= " << amax[Z]
<< " E(MeV)= " << ekin << G4endl;
*/
// first compute isotope cross section
if(ekin <=emax && amin[Z]>0 && A >= amin[Z] && A <= amax[Z]) {
G4PhysicsVector* pviso = data->GetComponentDataByIndex(Z, A - amin[Z]);
if(pviso) {
xs = pviso->Value(ekin);
if(verboseLevel > 0) {
G4cout << "IsoXS: Z= " << Z << " A= " << A
<< " Ekin(MeV)= " << ekin/CLHEP::MeV
<< ", nElmXSinel(bn)= " << xs/CLHEP::barn << G4endl;
}
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, logekin, fIdxXSTable); }
}
} else {
// isotope data are not available or applicable
G4PhysicsVector* pv = data->GetElementData(Z);
if(pv) { xs = pv->Value(ekin, logekin, fIdxXSTable); }
}
// isotope data are not available or applicable
G4PhysicsVector* pv = data->GetElementData(Z);
if(pv) { xs = pv->Value(ekin); }
if(verboseLevel > 0) {
G4cout << "IsoXS: Z= " << Z << " A= " << A
<< " Ekin(MeV)= " << ekin/CLHEP::MeV
@@ -221,7 +209,7 @@ G4NeutronInelasticXS::IsoCrossSection(G4double ekin, G4int ZZ, G4int A)
}
const G4Isotope* G4NeutronInelasticXS::SelectIsotope(
const G4Element* anElement, G4double kinEnergy)
const G4Element* anElement, G4double kinEnergy, G4double logE)
{
size_t nIso = anElement->GetNumberOfIsotopes();
const G4Isotope* iso = anElement->GetIsotope(0);
@@ -257,7 +245,7 @@ const G4Isotope* G4NeutronInelasticXS::SelectIsotope(
for (j=0; j<nIso; ++j) {
//G4cout << j << "-th isotope " << (*isoVector)[j]->GetN()
// << " abund= " << abundVector[j] << G4endl;
sum += abundVector[j]*IsoCrossSection(kinEnergy, Z,
sum += abundVector[j]*IsoCrossSection(kinEnergy, logE, Z,
anElement->GetIsotope(j)->GetN());
temp[j] = sum;
}
@@ -309,28 +297,22 @@ G4NeutronInelasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
// Build the complete string identifying the file with the data set
char* path = getenv("G4PARTICLEXSDATA");
G4DynamicParticle* dynParticle =
new G4DynamicParticle(G4Neutron::Neutron(),G4ThreeVector(1,0,0),1);
// 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; }
//G4cout << "Z= " << Z << G4endl;
// Initialisation
if(!(data->GetElementData(Z))) {
Initialise(Z, dynParticle, path);
Initialise(Z, path);
}
}
delete dynParticle;
}
}
void
G4NeutronInelasticXS::Initialise(G4int Z, G4DynamicParticle* dp,
const char* p)
G4NeutronInelasticXS::Initialise(G4int Z, const char* p)
{
if(data->GetElementData(Z) || Z < 1 || Z >= MAXZINEL) { return; }
const char* path = p;
@@ -370,17 +352,9 @@ G4NeutronInelasticXS::Initialise(G4int Z, G4DynamicParticle* dp,
// smooth transition
G4double sig1 = (*v)[v->GetVectorLength()-1];
dp->SetKineticEnergy(v->GetMaxEnergy());
G4double sig2 = 0.0;
if(1 == Z) {
fNucleon->GetHadronNucleonXscNS(dp, proton);
sig2 = fNucleon->GetInelasticHadronNucleonXsc();
} else {
G4int Amean =
G4lrint(G4NistManager::Instance()->GetAtomicMassAmu(Z));
ggXsection->GetIsoCrossSection(dp, Z, Amean);
sig2 = ggXsection->GetInelasticGlauberGribovXsc();
}
G4double ehigh= v->GetMaxEnergy();
G4double sig2 = ggXsection->GetInelasticElementCrossSection(neutron,
ehigh, Z, nist->GetAtomicMassAmu(Z));
if(sig2 > 0.) { coeff[Z] = sig1/sig2; }
}
@@ -33,8 +33,8 @@
//
#include "G4NucleonNuclearCrossSection.hh"
#include "G4SystemOfUnits.hh"
#include "G4DynamicParticle.hh"
#include "G4ParticleDefinition.hh"
#include "G4Neutron.hh"
#include "G4Proton.hh"
#include "G4ComponentBarNucleonNucleusXsc.hh"
@@ -44,9 +44,6 @@
//
G4_DECLARE_XS_FACTORY(G4NucleonNuclearCrossSection);
using namespace std;
///////////////////////////////////////////////////////////////////////////////
G4NucleonNuclearCrossSection::G4NucleonNuclearCrossSection()
@@ -65,7 +62,6 @@ G4NucleonNuclearCrossSection::~G4NucleonNuclearCrossSection()
{}
////////////////////////////////////////////////////////////////////////////
//
G4bool G4NucleonNuclearCrossSection::IsElementApplicable(
const G4DynamicParticle*, G4int Z, const G4Material*)
@@ -74,7 +70,6 @@ G4bool G4NucleonNuclearCrossSection::IsElementApplicable(
}
////////////////////////////////////////////////////////////////////////////
//
G4double G4NucleonNuclearCrossSection::GetElementCrossSection(
const G4DynamicParticle* dp, G4int Z, const G4Material*)
@@ -84,7 +79,6 @@ G4double G4NucleonNuclearCrossSection::GetElementCrossSection(
}
////////////////////////////////////////////////////////////////////////////
//
void G4NucleonNuclearCrossSection::ComputeCrossSections(
const G4ParticleDefinition* pd,
@@ -96,9 +90,14 @@ void G4NucleonNuclearCrossSection::ComputeCrossSections(
fElasticXsc = fBarash->GetElasticXsc();
}
////////////////////////////////////////////////////////////////////////////
void G4NucleonNuclearCrossSection::BuildPhysicsTable(const G4ParticleDefinition& part)
{
fBarash->BuildPhysicsTable(part);
}
////////////////////////////////////////////////////////////////////////////
//
void
G4NucleonNuclearCrossSection::CrossSectionDescription(std::ostream& outFile) const
@@ -111,3 +110,5 @@ G4NucleonNuclearCrossSection::CrossSectionDescription(std::ostream& outFile) con
<< "to 1 TeV.\n";
}
////////////////////////////////////////////////////////////////////////////
@@ -45,7 +45,6 @@
#include "G4PhysicsVector.hh"
#include "G4ComponentGGHadronNucleusXsc.hh"
#include "G4ComponentGGNuclNuclXsc.hh"
#include "G4HadronNucleonXsc.hh"
#include "G4NistManager.hh"
#include "G4Proton.hh"
#include "Randomize.hh"
@@ -70,7 +69,7 @@ const G4int G4ParticleInelasticXS::amin[] = {
0, 235};
const G4int G4ParticleInelasticXS::amax[] = {
0,
1, 4, 7, 9, 11, 13, 15, 18, 19, 22, //1-10
2, 4, 7, 9, 11, 13, 15, 18, 19, 22, //1-10
23, 26, 27, 30, 31, 34, 37, 40, 41, 48, //11-20
45, 50, 51, 54, 55, 58, 59, 64, 65, 70, //21-30
71, 76, 75, 0, 0, 0, 0, 0, 0, 96, //31-40
@@ -93,39 +92,34 @@ G4ParticleInelasticXS::G4ParticleInelasticXS(const G4ParticleDefinition* part)
: G4VCrossSectionDataSet("G4ParticleInelasticXS"),
ggXsection(nullptr),
nnXsection(nullptr),
fNucleon(nullptr),
particle(part),
proton(G4Proton::Proton()),
particleName(""),
isMaster(false),
emax(20*CLHEP::MeV)
emax(20*CLHEP::MeV),
fIdxXSTable(0),
isMaster(false)
{
if(!part) {
G4Exception("G4ParticleInelasticXS::G4ParticleInelasticXS(..)","had015",
FatalException, "NO particle definition in constructor");
} else {
// verboseLevel = 0;
particleName = particle->GetParticleName();
verboseLevel = 0;
G4String particleName = particle->GetParticleName();
if(verboseLevel > 0){
G4cout << "G4ParticleInelasticXS::G4ParticleInelasticXS for "
<< particleName << " on atoms with Z < " << MAXZINELP << G4endl;
}
if(particleName == "neutron" || particleName == "proton") {
ggXsection = new G4ComponentGGHadronNucleusXsc();
fNucleon = new G4HadronNucleonXsc();
} else {
nnXsection = new G4ComponentGGNuclNuclXsc();
}
}
SetForAllAtomsAndEnergies(true);
fNist = G4NistManager::Instance();
fNist = G4NistManager::Instance();
}
G4ParticleInelasticXS::~G4ParticleInelasticXS()
{
//G4cout << "G4ParticleInelasticXS::~G4ParticleInelasticXS() "
// << " isMaster= " << isMaster << " data: " << data << G4endl;
delete fNucleon;
if(isMaster) { delete data; data = nullptr; }
}
@@ -170,30 +164,22 @@ G4double G4ParticleInelasticXS::GetElementCrossSection(
if(!pv || ekin <= pv->Energy(0)) { return xs; }
if(ekin <= pv->GetMaxEnergy()) {
xs = pv->Value(ekin);
} else if(1 == Z) {
if(fNucleon) {
fNucleon->GetHadronNucleonXscNS(aParticle, proton);
xs = coeff[1]*fNucleon->GetInelasticHadronNucleonXsc();
} else {
nnXsection->GetZandACrossSection(aParticle, 1, 1);
xs = coeff[1]*nnXsection->GetInelasticGlauberGribovXsc();
}
xs = pv->Value(ekin, aParticle->GetLogKineticEnergy(), fIdxXSTable);
} else {
G4int Amean = G4lrint(fNist->GetAtomicMassAmu(Z));
G4double Amean = fNist->GetAtomicMassAmu(Z);
if(ggXsection) {
ggXsection->GetIsoCrossSection(aParticle, Z, Amean);
xs = coeff[Z]*ggXsection->GetInelasticGlauberGribovXsc();
xs = coeff[Z]*ggXsection->GetInelasticElementCrossSection(particle,
ekin, Z, Amean);
} else {
nnXsection->GetZandACrossSection(aParticle, Z, Amean);
xs = coeff[Z]*nnXsection->GetInelasticGlauberGribovXsc();
xs = coeff[Z]*nnXsection->GetInelasticElementCrossSection(particle,
ekin, Z, Amean);
}
}
if(verboseLevel > 1) {
G4cout << "ElmXS: Z= " << Z << " Ekin(MeV)= " << ekin/CLHEP::MeV
<< " xs(bn)= " << xs/CLHEP::barn << " element data for "
<< particleName << G4endl;
<< particle->GetParticleName() << G4endl;
}
return xs;
}
@@ -204,11 +190,13 @@ G4double G4ParticleInelasticXS::GetIsoCrossSection(
const G4Isotope*, const G4Element*,
const G4Material*)
{
return IsoCrossSection(aParticle->GetKineticEnergy(), Z, A);
return IsoCrossSection(aParticle->GetKineticEnergy(),
aParticle->GetLogKineticEnergy(),Z, A);
}
G4double
G4ParticleInelasticXS::IsoCrossSection(G4double ekin, G4int ZZ, G4int A)
G4ParticleInelasticXS::IsoCrossSection(G4double ekin, G4double logE,
G4int ZZ, G4int A)
{
G4double xs = 0.0;
G4int Z = (ZZ >= MAXZINELP) ? MAXZINELP - 1 : ZZ;
@@ -217,25 +205,19 @@ G4ParticleInelasticXS::IsoCrossSection(G4double ekin, G4int ZZ, G4int A)
<< " Amin= " << amin[Z] << " Amax= " << amax[Z]
<< " E(MeV)= " << ekin << G4endl;
*/
// first compute isotope cross section
if(ekin <=emax && amin[Z]>0 && A >= amin[Z] && A <= amax[Z]) {
G4PhysicsVector* pviso = data->GetComponentDataByIndex(Z, A - amin[Z]);
if(pviso) {
xs = pviso->Value(ekin);
if(verboseLevel > 0){
G4cout << "IsoXS for " << particleName
<< " Target Z= " << Z << " A= " << A
<< " Ekin(MeV)= " << ekin/CLHEP::MeV
<< " xs(bn)= " << xs/CLHEP::barn << G4endl;
}
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); }
}
} else {
// isotope data are not available or applicable
G4PhysicsVector* pv = data->GetElementData(Z);
if(pv) { xs = pv->Value(ekin, logE, fIdxXSTable); }
}
// isotope data are not available or applicable
G4PhysicsVector* pv = data->GetElementData(Z);
if(pv) { xs = pv->Value(ekin); }
if(verboseLevel > 0) {
G4cout << "IsoXS for " << particleName
G4cout << "IsoXS for " << particle->GetParticleName()
<< " Target Z= " << Z << " A= " << A
<< " Ekin(MeV)= " << ekin/CLHEP::MeV
<< " xs(bn)= " << xs/CLHEP::barn << G4endl;
@@ -244,7 +226,7 @@ G4ParticleInelasticXS::IsoCrossSection(G4double ekin, G4int ZZ, G4int A)
}
const G4Isotope* G4ParticleInelasticXS::SelectIsotope(
const G4Element* anElement, G4double kinEnergy)
const G4Element* anElement, G4double kinEnergy, G4double logE)
{
size_t nIso = anElement->GetNumberOfIsotopes();
const G4Isotope* iso = anElement->GetIsotope(0);
@@ -279,7 +261,7 @@ const G4Isotope* G4ParticleInelasticXS::SelectIsotope(
for (j=0; j<nIso; ++j) {
//G4cout << j << "-th isotope " << (*isoVector)[j]->GetN()
// << " abund= " << abundVector[j] << G4endl;
sum += abundVector[j]*IsoCrossSection(kinEnergy, Z,
sum += abundVector[j]*IsoCrossSection(kinEnergy, logE, Z,
anElement->GetIsotope(j)->GetN());
temp[j] = sum;
}
@@ -303,7 +285,7 @@ G4ParticleInelasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
if(&p != particle) {
G4ExceptionDescription ed;
ed << p.GetParticleName() << " is a wrong particle type -"
<< particleName << " is expected";
<< particle->GetParticleName() << " is expected";
G4Exception("G4ParticleInelasticXS::BuildPhysicsTable(..)","had012",
FatalException, ed, "");
return;
@@ -316,7 +298,7 @@ G4ParticleInelasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
#endif
isMaster = true;
data = new G4ElementData();
data->SetName(particleName + "Inelastic");
data->SetName(particle->GetParticleName() + "Inelastic");
temp.resize(13,0.0);
#ifdef G4MULTITHREADED
}
@@ -331,27 +313,17 @@ G4ParticleInelasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
// Build the complete string identifying the file with the data set
char* path = getenv("G4PARTICLEXSDATA");
G4DynamicParticle* dynParticle =
new G4DynamicParticle(particle,G4ThreeVector(1,0,0),1);
// 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 >= MAXZINELP) { Z = MAXZINELP-1; }
//G4cout << "Z= " << Z << G4endl;
// Initialisation
if(!(data->GetElementData(Z))) {
Initialise(Z, dynParticle, path);
}
G4int Z = std::min(((*theElmTable)[i])->GetZasInt(), MAXZINELP-1);
if(!(data->GetElementData(Z))) { Initialise(Z, path); }
}
delete dynParticle;
}
}
void G4ParticleInelasticXS::Initialise(G4int Z, G4DynamicParticle* dp,
const char* p)
void G4ParticleInelasticXS::Initialise(G4int Z, const char* p)
{
if(data->GetElementData(Z)) { return; }
const char* path = p;
@@ -368,6 +340,7 @@ void G4ParticleInelasticXS::Initialise(G4int Z, G4DynamicParticle* dp,
}
// upload element data
G4String particleName = particle->GetParticleName();
std::ostringstream ost;
ost << path << "/" << particleName << "/inel" << Z ;
G4PhysicsVector* v = RetrieveVector(ost, true);
@@ -389,28 +362,17 @@ void G4ParticleInelasticXS::Initialise(G4int Z, G4DynamicParticle* dp,
data->AddComponent(Z, A, v1);
}
}
// smooth transition
G4double sig1 = (*v)[v->GetVectorLength()-1];
dp->SetKineticEnergy(v->GetMaxEnergy());
G4double sig2 = 0.0;
if(1 == Z) {
if(fNucleon) {
fNucleon->GetHadronNucleonXscNS(dp, proton);
sig2 = fNucleon->GetInelasticHadronNucleonXsc();
} else {
nnXsection->GetZandACrossSection(dp, 1, 1);
sig2 = nnXsection->GetInelasticGlauberGribovXsc();
}
G4double sig1 = (*v)[v->GetVectorLength()-1];
G4double sig2 = 0.0;
G4double ehigh = v->GetMaxEnergy();
G4double Amean = fNist->GetAtomicMassAmu(Z);
if(ggXsection) {
sig2 = ggXsection->GetInelasticElementCrossSection(particle,
ehigh, Z, Amean);
} else {
G4int Amean = G4lrint(fNist->GetAtomicMassAmu(Z));
if(ggXsection) {
ggXsection->GetIsoCrossSection(dp, Z, Amean);
sig2 = ggXsection->GetInelasticGlauberGribovXsc();
} else {
nnXsection->GetZandACrossSection(dp, Z, Amean);
sig2 = nnXsection->GetInelasticGlauberGribovXsc();
}
sig2 = nnXsection->GetInelasticElementCrossSection(particle,
ehigh, Z, Amean);
}
if(sig2 > 0.) { coeff[Z] = sig1/sig2; }
}
@@ -29,7 +29,6 @@
#include "G4PiData.hh"
#include "G4SystemOfUnits.hh"
#include "G4HadronicException.hh"
///////////////////////////////////////////////////////////////////////
@@ -66,8 +65,10 @@ G4double G4PiData::ReactionXSection(G4double kineticEnergy)
while(it!=end()&&kineticEnergy>(*it).first) {it++;} /* Loop checking, 08.01.2016, W. Pokorski */
if(it==end())
{
throw G4HadronicException(__FILE__, __LINE__,
"G4PiData::ReactionXSection: used outside validity range");
G4ExceptionDescription ed;
ed << "This cross section is applied for E(MeV)= " << kineticEnergy
<< " outside allowed energy interval" << G4endl;
G4Exception("G4PiData::ReactionXSection", "had001", FatalException, ed);
}
if(it==begin()) it++;
G4double x1,x2,e1,e2;
@@ -88,8 +89,10 @@ G4double G4PiData::ElasticXSection(G4double kineticEnergy)
while(it!=end()&&kineticEnergy>(*it).first) {it++;} /* Loop checking, 08.01.2016, W. Pokorski */
if(it==end())
{
throw G4HadronicException(__FILE__, __LINE__,
"G4PiData::ElasticXSection: used outside validity range");
G4ExceptionDescription ed;
ed << "This cross section is applied for E(MeV)= " << kineticEnergy
<< " outside allowed energy interval" << G4endl;
G4Exception("G4PiData::ElasticXSection", "had001", FatalException, ed);
}
if(it==begin()) it++;
G4double x1,x2,e1,e2;
@@ -110,8 +113,10 @@ G4double G4PiData::TotalXSection(G4double kineticEnergy)
while(it!=end()&&kineticEnergy>(*it).first) {it++;} /* Loop checking, 08.01.2016, W. Pokorski */
if(it==end())
{
throw G4HadronicException(__FILE__, __LINE__,
"G4PiData::TotalXSection: used outside validity range");
G4ExceptionDescription ed;
ed << "This cross section is applied for E(MeV)= " << kineticEnergy
<< " outside allowed energy interval" << G4endl;
G4Exception("G4PiData::TotalXSection", "had001", FatalException, ed);
}
if(it==begin()) it++;
G4double x1,x2,e1,e2;
@@ -27,8 +27,6 @@
#include "G4PiNuclearCrossSection.hh"
#include "G4SystemOfUnits.hh"
#include "G4DynamicParticle.hh"
#include "G4HadronicException.hh"
#include "G4HadTmpUtil.hh"
#include "G4Pow.hh"
// factory
@@ -470,8 +468,13 @@ G4PiNuclearCrossSection::IsElementApplicable(const G4DynamicParticle*,
void G4PiNuclearCrossSection::BuildPhysicsTable(const G4ParticleDefinition& p)
{
if(&p == G4PionMinus::PionMinus() || &p == G4PionPlus::PionPlus()) { return; }
throw G4HadronicException(__FILE__, __LINE__,"Is applicable only for pions");
if(&p != G4PionMinus::PionMinus() && &p != G4PionPlus::PionPlus()) {
G4ExceptionDescription ed;
ed << "This cross section is applicable only to pions and not to "
<< p.GetParticleName() << G4endl;
G4Exception("G4PiNuclearCrossSection::BuildPhysicsTable", "had001",
FatalException, ed);
}
}
G4double
@@ -498,7 +501,7 @@ G4PiNuclearCrossSection::GetElementCrossSection(const G4DynamicParticle* particl
const G4bool isHeavyElementAllowed = true;
if ( isHeavyElementAllowed ) {
it--;
if ( Z > 100 ) Z = 100; // Above Fermium, treat it as Fermium
G4int zz = (Z > 100) ? 100 : Z; // Above Fermium, treat it as Fermium
// The cross section for a transuranic element is scaled from the
// corresponding cross section of Uranium, as follows:
// (atomic_weight_element/atomic_weight_uranium)^0.75
@@ -515,14 +518,16 @@ G4PiNuclearCrossSection::GetElementCrossSection(const G4DynamicParticle* particl
1.040598, // <A>=251.0 for Cf (Z=98)
1.043706, // <A>=252.0 for Es (Z=99)
1.059199 }; // <A>=257.0 for Fm (Z=100)
result = vecScaling[Z-93] * thePimData[it]->ReactionXSection( kineticEnergy );
fTotalXsc = vecScaling[Z-93] * thePimData[it]->TotalXSection( kineticEnergy );
fElasticXsc = fTotalXsc - result;
if ( fElasticXsc < 0.0 ) fElasticXsc = 0.0;
result = vecScaling[zz-93] * thePimData[it]->ReactionXSection( kineticEnergy );
fTotalXsc = vecScaling[zz-93] * thePimData[it]->TotalXSection( kineticEnergy );
fElasticXsc = std::max(fTotalXsc - result, 0.0);
return result;
} else {
throw G4HadronicException(__FILE__, __LINE__,
"Called G4PiNuclearCrossSection outside parametrization");
G4ExceptionDescription ed;
ed << "This cross section not applicable to Z= " << Z << " projectile: "
<< particle->GetParticleDefinition()->GetParticleName() << G4endl;
G4Exception("G4PiNuclearCrossSection::GetElementCrossSection", "had001",
FatalException, ed);
}
}
G4int Z1, Z2;
@@ -42,37 +42,62 @@
#include "G4PionPlus.hh"
#include "G4PhysicsTable.hh"
#include "G4NistManager.hh"
#include "G4HadTmpUtil.hh"
#include "G4HadronicException.hh"
G4int G4UPiNuclearCrossSection::theZ[NZ] =
{2,4,6,7,8,11,13,20,26,29,42,48,50,74,82,92};
G4double G4UPiNuclearCrossSection::theA[NZ] = {0.0};
G4double G4UPiNuclearCrossSection::APower[93] = {0.0};
G4PhysicsTable* G4UPiNuclearCrossSection::piPlusElastic = nullptr;
G4PhysicsTable* G4UPiNuclearCrossSection::piPlusInelastic = nullptr;
G4PhysicsTable* G4UPiNuclearCrossSection::piMinusElastic = nullptr;
G4PhysicsTable* G4UPiNuclearCrossSection::piMinusInelastic = nullptr;
#ifdef G4MULTITHREADED
G4Mutex G4UPiNuclearCrossSection::pionUXSMutex = G4MUTEX_INITIALIZER;
#endif
G4UPiNuclearCrossSection::G4UPiNuclearCrossSection()
: G4VCrossSectionDataSet("G4UPiNuclearCrossSection")
{
isInitialized = false;
piPlusElastic = piPlusInelastic = piMinusElastic = piMinusInelastic = nullptr;
isMaster = false;
piPlus = G4PionPlus::PionPlus();
piMinus = G4PionMinus::PionMinus();
NZ = 16;
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::GetInstance()->powA(nist->GetAtomicMassAmu(i),aPower);
APower[i] = g4pow->powA(nist->GetAtomicMassAmu(i),aPower);
}
}
G4UPiNuclearCrossSection::~G4UPiNuclearCrossSection()
{
piPlusElastic->clearAndDestroy();
piPlusInelastic->clearAndDestroy();
piMinusElastic->clearAndDestroy();
piMinusInelastic->clearAndDestroy();
delete piPlusElastic;
delete piPlusInelastic;
delete piMinusElastic;
delete piMinusInelastic;
if(isMaster) {
if(piPlusElastic) {
piPlusElastic->clearAndDestroy();
delete piPlusElastic;
piPlusElastic = nullptr;
}
if(piPlusInelastic) {
piPlusInelastic->clearAndDestroy();
delete piPlusInelastic;
piPlusInelastic = nullptr;
}
if(piMinusElastic) {
piMinusElastic->clearAndDestroy();
delete piMinusElastic;
piMinusElastic = nullptr;
}
if(piMinusInelastic) {
piMinusInelastic->clearAndDestroy();
delete piMinusInelastic;
piMinusInelastic = nullptr;
}
}
}
G4bool
@@ -84,7 +109,7 @@ G4UPiNuclearCrossSection::IsElementApplicable(const G4DynamicParticle*,
G4double
G4UPiNuclearCrossSection::GetElasticCrossSection(const G4DynamicParticle* dp,
G4int Z, G4int A)
G4int Z, G4int A) const
{
G4double cross = 0.0;
const G4ParticleDefinition* part = dp->GetDefinition();
@@ -97,12 +122,12 @@ G4UPiNuclearCrossSection::GetElasticCrossSection(const G4DynamicParticle* dp,
G4double
G4UPiNuclearCrossSection::GetInelasticCrossSection(const G4DynamicParticle* dp,
G4int Z, G4int A)
G4int Z, G4int A) const
{
G4double cross = 0.0;
G4double fact = 1.0;
G4double ekin = dp->GetKineticEnergy();
G4PhysicsTable* table = 0;
G4PhysicsTable* table = nullptr;
const G4ParticleDefinition* part = dp->GetDefinition();
// Coulomb barrier
@@ -116,7 +141,7 @@ G4UPiNuclearCrossSection::GetInelasticCrossSection(const G4DynamicParticle* dp,
}
} else if(part == piMinus) {
table = piMinusInelastic;
if(ekin < elow) { ekin = elow; }
ekin = std::max(ekin,elow);
}
if(table) {
cross = fact*Interpolate(Z, A, ekin, table);
@@ -125,14 +150,13 @@ G4UPiNuclearCrossSection::GetInelasticCrossSection(const G4DynamicParticle* dp,
}
G4double G4UPiNuclearCrossSection::Interpolate(
G4int Z, G4int A, G4double ekin, G4PhysicsTable* table)
G4int Z, G4int A, G4double ekin, G4PhysicsTable* table) const
{
G4double res = 0.0;
G4int idx;
G4int iz = Z;
if(iz > 92) iz = 92;
for(idx=0; idx<NZ; idx++) {if(theZ[idx] >= iz) break;}
if(idx >= NZ) idx = NZ - 1;
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;
@@ -161,9 +185,9 @@ void G4UPiNuclearCrossSection::AddDataSet(const G4String& p,
G4int n)
{
G4LPhysicsFreeVector* pvin = new G4LPhysicsFreeVector(n,e[0]*GeV,e[n-1]*GeV);
//pvin->SetSpline(true);
pvin->SetSpline(true);
G4LPhysicsFreeVector* pvel = new G4LPhysicsFreeVector(n,e[0]*GeV,e[n-1]*GeV);
//pvel->SetSpline(true);
pvel->SetSpline(true);
for(G4int i=0; i<n; ++i) {
pvin->PutValues(i,e[i]*GeV,in[i]*millibarn);
pvel->PutValues(i,e[i]*GeV,std::max(0.0,(tot[i]-in[i])*millibarn));
@@ -194,24 +218,33 @@ void G4UPiNuclearCrossSection::DumpPhysicsTable(const G4ParticleDefinition& p)
void G4UPiNuclearCrossSection::BuildPhysicsTable(const G4ParticleDefinition& p)
{
if(isInitialized) { return; }
if(piPlusElastic) { return; }
if(&p != piPlus && &p != piMinus) {
throw G4HadronicException(__FILE__, __LINE__,"Is applicable only for pions");
G4ExceptionDescription ed;
ed << "This cross section is applicable only to pions and not to "
<< p.GetParticleName() << G4endl;
G4Exception("G4UPiNuclearCrossSection::BuildPhysicsTable", "had001",
FatalException, ed);
return;
}
isInitialized = true;
const G4int n = 16;
const G4int iz[n] = {2,4,6,7,8,11,13,20,26,29,42,48,50,74,82,92};
NZ = n;
theZ.reserve(n);
theA.reserve(n);
if(!piPlusElastic) {
#ifdef G4MULTITHREADED
G4MUTEXLOCK(&pionUXSMutex);
if(!piPlusElastic) {
#endif
isMaster = true;
#ifdef G4MULTITHREADED
}
G4MUTEXUNLOCK(&pionUXSMutex);
#endif
}
if(!isMaster) { return; }
G4NistManager* nist = G4NistManager::Instance();
G4int i;
for(i=0; i<n; ++i) {
theZ.push_back(iz[i]);
theA.push_back(nist->GetAtomicMassAmu(iz[i]));
for(G4int i=0; i<NZ; ++i) {
theA[i] = nist->GetAtomicMassAmu(theZ[i]);
}
piPlusElastic = new G4PhysicsTable();
@@ -219,6 +252,11 @@ void G4UPiNuclearCrossSection::BuildPhysicsTable(const G4ParticleDefinition& p)
piMinusElastic = new G4PhysicsTable();
piMinusInelastic = new G4PhysicsTable();
LoadData();
}
void G4UPiNuclearCrossSection::LoadData()
{
static const G4double e1[38] = {
0.02, 0.04, 0.06, 0.08, 0.1, 0.12, 0.13, 0.14, 0.15, 0.16,
0.17, 0.18, 0.19, 0.2, 0.22,0.24, 0.26, 0.28, 0.3, 0.35,
@@ -244,7 +282,7 @@ void G4UPiNuclearCrossSection::BuildPhysicsTable(const G4ParticleDefinition& p)
static const G4double e6[35] = {
0.02, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.1, 0.12, 0.14,
0.16, 0.18, 0.2, 0.22, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5,
0.55, 0.6, 0.7, 0.8, 0.9, 1, 2, 3, 5, 10, 20, 50, 100, 500, 1000};
0.55, 0.6, 0.7, 0.8, 0.9, 1, 2, 3, 5, 10, 20, 50, 100, 500, 1000};
static const G4double he_t[38] = {
40, 70, 108, 152, 208, 276, 300, 320, 329, 333,
@@ -23,12 +23,10 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
//
// File name: G4VCrossSectionDataSet
//
// Author F.W. Jones, TRIUMF, 20-JAN-97
@@ -45,12 +43,12 @@
#include "G4Element.hh"
#include "G4Isotope.hh"
#include "G4NistManager.hh"
#include "G4HadronicException.hh"
#include "Randomize.hh"
#include "G4HadronicParameters.hh"
G4VCrossSectionDataSet::G4VCrossSectionDataSet(const G4String& nam) :
verboseLevel(0),minKinEnergy(0.0),maxKinEnergy( G4HadronicParameters::Instance()->GetMaxEnergy() ),
verboseLevel(0),minKinEnergy(0.0),
maxKinEnergy(G4HadronicParameters::Instance()->GetMaxEnergy()),
isForAllAtomsAndEnergies(false),name(nam)
{
registry = G4CrossSectionDataSetRegistry::Instance();
@@ -93,25 +91,23 @@ G4VCrossSectionDataSet::ComputeCrossSection(const G4DynamicParticle* part,
// isotope-wise cross section making sum over available
// isotope cross sections, which may be incomplete, so
// the result is corrected
G4int nIso = elm->GetNumberOfIsotopes();
size_t nIso = elm->GetNumberOfIsotopes();
G4double fact = 0.0;
G4double xsec = 0.0;
const G4Isotope* iso = nullptr;
// user-defined isotope abundances
const G4IsotopeVector* isoVector = elm->GetIsotopeVector();
const G4double* abundVector = elm->GetRelativeAbundanceVector();
for (G4int j = 0; j<nIso; ++j) {
iso = (*isoVector)[j];
for (size_t j=0; j<nIso; ++j) {
const G4Isotope* iso = (*isoVector)[j];
G4int A = iso->GetN();
if(abundVector[j] > 0.0 && IsIsoApplicable(part, Z, A, elm, mat)) {
fact += abundVector[j];
xsec += abundVector[j]*GetIsoCrossSection(part, Z, A, iso, elm, mat);
}
}
if(fact > 0.0) { xsec /= fact; }
return xsec;
return (fact > 0.0) ? xsec/fact : 0.0;
}
G4double
@@ -119,14 +115,15 @@ G4VCrossSectionDataSet::GetElementCrossSection(const G4DynamicParticle* dynPart,
G4int Z,
const G4Material* mat)
{
G4cout << "G4VCrossSectionDataSet::GetCrossSection per element ERROR: "
<< " there is no cross section for "
<< dynPart->GetDefinition()->GetParticleName()
<< " E(MeV)= " << dynPart->GetKineticEnergy()/MeV;
if(mat) { G4cout << " inside " << mat->GetName(); }
G4cout << " for Z= " << Z << G4endl;
throw G4HadronicException(__FILE__, __LINE__,
"G4VCrossSectionDataSet::GetElementCrossSection is absent");
G4ExceptionDescription ed;
ed << "GetElementCrossSection is not implemented in <" << name << ">\n"
<< "Particle: " << dynPart->GetDefinition()->GetParticleName()
<< " Ekin(MeV)= " << dynPart->GetKineticEnergy()/MeV;
if(mat) { ed << " material: " << mat->GetName(); }
ed << " target Z= " << Z << G4endl;
G4Exception("G4VCrossSectionDataSet::GetElementCrossSection", "had001",
FatalException, ed);
return 0.0;
}
G4double
@@ -136,21 +133,23 @@ G4VCrossSectionDataSet::GetIsoCrossSection(const G4DynamicParticle* dynPart,
const G4Element* elm,
const G4Material* mat)
{
G4cout << "G4VCrossSectionDataSet::GetCrossSection per isotope ERROR: "
<< " there is no cross section for "
<< dynPart->GetDefinition()->GetParticleName()
<< " E(MeV)= " << dynPart->GetKineticEnergy()/MeV;
if(mat) { G4cout << " inside " << mat->GetName(); }
if(elm) { G4cout << " for " << elm->GetName(); }
G4cout << " Z= " << Z << " A= " << A << G4endl;
throw G4HadronicException(__FILE__, __LINE__,
"G4VCrossSectionDataSet::GetIsoCrossSection is absent");
G4ExceptionDescription ed;
ed << "GetIsoCrossSection is not implemented in <" << name << ">\n"
<< "Particle: " << dynPart->GetDefinition()->GetParticleName()
<< " Ekin(MeV)= " << dynPart->GetKineticEnergy()/MeV;
if(mat) { ed << " material: " << mat->GetName(); }
if(elm) { ed << " element: " << elm->GetName(); }
ed << " target Z= " << Z << " A= " << A << G4endl;
G4Exception("G4VCrossSectionDataSet::GetIsoCrossSection", "had001",
FatalException, ed);
return 0.0;
}
const G4Isotope*
G4VCrossSectionDataSet::SelectIsotope(const G4Element* anElement, G4double)
G4VCrossSectionDataSet::SelectIsotope(const G4Element* anElement,
G4double, G4double)
{
G4int nIso = anElement->GetNumberOfIsotopes();
size_t nIso = anElement->GetNumberOfIsotopes();
const G4Isotope* iso = anElement->GetIsotope(0);
// more than 1 isotope
@@ -158,7 +157,7 @@ G4VCrossSectionDataSet::SelectIsotope(const G4Element* anElement, G4double)
const G4double* abundVector = anElement->GetRelativeAbundanceVector();
G4double sum = 0.0;
G4double q = G4UniformRand();
for (G4int j = 0; j<nIso; ++j) {
for (size_t j=0; j<nIso; ++j) {
sum += abundVector[j];
if(q <= sum) {
iso = anElement->GetIsotope(j);