Import Geant4 9.2.0 source tree

This commit is contained in:
Gabriele Cosmo
2016-06-09 15:58:43 +02:00
parent 96c8bcd0af
commit b79225fb37
7544 changed files with 245407 additions and 91099 deletions
@@ -23,8 +23,8 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4BGGNucleonElasticXS.cc,v 1.1 2007/03/13 15:19:30 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-01 $
// $Id: G4BGGNucleonElasticXS.cc,v 1.3 2008/12/01 16:50:23 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-02 $
//
// -------------------------------------------------------------------
//
@@ -45,31 +45,24 @@
#include "G4BGGNucleonElasticXS.hh"
#include "G4GlauberGribovCrossSection.hh"
#include "G4NucleonNuclearCrossSection.hh"
#include "G4HadronNucleonXsc.hh"
#include "G4Proton.hh"
#include "G4Neutron.hh"
#include "G4NistManager.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4BGGNucleonElasticXS::G4BGGNucleonElasticXS(const G4ParticleDefinition* p)
G4BGGNucleonElasticXS::G4BGGNucleonElasticXS(const G4ParticleDefinition*)
{
verboseLevel = 0;
thEnergy = 100.*GeV;
if(p == G4Proton::Proton() || p == G4Neutron::Neutron()) {
fNucleon = new G4NucleonNuclearCrossSection();
fGlauber = new G4GlauberGribovCrossSection();
particle = p;
Initialise();
} else {
fNucleon = 0;
fGlauber = 0;
particle = 0;
if(p) G4cout << "### G4BGGNucleonElasticXS WARNING: is not applicable to "
<< p->GetParticleName()
<< G4endl;
else G4cout << "### G4BGGNucleonElasticXS WARNING: particle is not defined "
<< G4endl;
}
fGlauberEnergy = 91.*GeV;
fLowEnergy = 20.*MeV;
fNucleon = 0;
fGlauber = 0;
fHadron = 0;
particle = 0;
isProton = false;
isInitialized = false;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -78,6 +71,7 @@ G4BGGNucleonElasticXS::~G4BGGNucleonElasticXS()
{
delete fGlauber;
delete fNucleon;
delete fHadron;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -89,13 +83,30 @@ G4double G4BGGNucleonElasticXS::GetIsoZACrossSection(const G4DynamicParticle* dp
{
G4double cross = 0.0;
G4double ekin = dp->GetKineticEnergy();
G4int iz = G4int(Z + 0.5);
G4int iz = G4int(Z);
if(iz > 92) iz = 92;
if(ekin > thEnergy) {
cross = theFac[iz]*fGlauber->GetElasticGlauberGribov(dp, Z, A);
if(ekin <= fLowEnergy) {
cross = theCoulombFac[iz];
if(isProton) { cross *= CoulombFactor(ekin, A); }
} else if(iz == 1) {
if( A < 1.5) {
//fHadron->GetHadronNucleonXscPDG(dp, G4Proton::Proton());
//fHadron->GetHadronNucleonXscEL(dp, G4Proton::Proton());
//fHadron->GetHadronNucleonXscNS(dp, G4Proton::Proton());
fHadron->GetHadronNucleonXscMK(dp, G4Proton::Proton());
cross = fHadron->GetElasticHadronNucleonXsc();
} else {
fHadron->GetHadronNucleonXscMK(dp, G4Proton::Proton());
cross = fHadron->GetElasticHadronNucleonXsc();
fHadron->GetHadronNucleonXscMK(dp, G4Neutron::Neutron());
cross += fHadron->GetElasticHadronNucleonXsc();
}
} else if(ekin > fGlauberEnergy) {
cross = theGlauberFac[iz]*fGlauber->GetElasticGlauberGribov(dp, Z, A);
} else {
cross = fNucleon->GetIsoZACrossSection(dp, Z, A);
cross = fNucleon->GetElasticCrossSection(dp, Z, A);
}
if(verboseLevel > 1)
@@ -111,8 +122,16 @@ G4double G4BGGNucleonElasticXS::GetIsoZACrossSection(const G4DynamicParticle* dp
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4BGGNucleonElasticXS::BuildPhysicsTable(const G4ParticleDefinition&)
void G4BGGNucleonElasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
{
if(&p == G4Proton::Proton() || &p == G4Neutron::Neutron()) {
particle = &p;
Initialise();
} else {
G4cout << "### G4BGGNucleonElasticXS WARNING: is not applicable to "
<< p.GetParticleName()
<< G4endl;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -126,14 +145,23 @@ void G4BGGNucleonElasticXS::DumpPhysicsTable(const G4ParticleDefinition&)
void G4BGGNucleonElasticXS::Initialise()
{
if(isInitialized) return;
isInitialized = true;
fNucleon = new G4NucleonNuclearCrossSection();
fGlauber = new G4GlauberGribovCrossSection();
fHadron = new G4HadronNucleonXsc();
fNucleon->BuildPhysicsTable(*particle);
fGlauber->BuildPhysicsTable(*particle);
if(particle == G4Proton::Proton()) isProton = true;
G4ParticleDefinition* part = const_cast<G4ParticleDefinition*>(particle);
G4ThreeVector mom(0.0,0.0,1.0);
G4DynamicParticle dp(part, mom, thEnergy);
G4DynamicParticle dp(part, mom, fGlauberEnergy);
G4NistManager* nist = G4NistManager::Instance();
G4double A = nist->GetAtomicMassAmu(2);
G4double csup, csdn;
G4double A, csup, csdn;
if(verboseLevel > 0) G4cout << "### G4BGGNucleonElasticXS::Initialise for "
<< particle->GetParticleName() << G4endl;
@@ -144,14 +172,51 @@ void G4BGGNucleonElasticXS::Initialise()
A = nist->GetAtomicMassAmu(iz);
csup = fGlauber->GetElasticGlauberGribov(&dp, Z, A);
csdn = fNucleon->GetIsoZACrossSection(&dp, Z, A);
csdn = fNucleon->GetElasticCrossSection(&dp, Z, A);
theFac[iz] = csdn/csup;
theGlauberFac[iz] = csdn/csup;
if(verboseLevel > 0) G4cout << "Z= " << Z << " A= " << A
<< " factor= " << theFac[iz] << G4endl;
<< " factor= " << theGlauberFac[iz] << G4endl;
}
dp.SetKineticEnergy(fLowEnergy);
fHadron->GetHadronNucleonXscMK(&dp, G4Proton::Proton());
theCoulombFac[1] = fHadron->GetElasticHadronNucleonXsc();
if(isProton) { theCoulombFac[1] /= CoulombFactor(fLowEnergy, 1.0); }
for(G4int iz=2; iz<93; iz++) {
G4double Z = G4double(iz);
A = nist->GetAtomicMassAmu(iz);
theCoulombFac[iz] = fNucleon->GetElasticCrossSection(&dp, Z, A);
if(isProton) { theCoulombFac[iz] /= CoulombFactor(fLowEnergy, A); }
if(verboseLevel > 0) G4cout << "Z= " << Z << " A= " << A
<< " factor= " << theCoulombFac[iz] << G4endl;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4BGGNucleonElasticXS::CoulombFactor(G4double kinEnergy, G4double A)
{
G4double res= 0.0;
if(kinEnergy <= DBL_MIN) return res;
else if(A < 1.5) return kinEnergy*kinEnergy;
G4double elog = std::log10(kinEnergy/GeV);
// from G4ProtonInelasticCrossSection
G4double f1 = 8.0 - 8.0/A - 0.008*A;
G4double f2 = 2.34 - 5.4/A - 0.0028*A;
res = 1.0/(1.0 + std::exp(-f1*(elog + f2)));
f1 = 5.6 - 0.016*A;
f2 = 1.37 + 1.37/A;
res *= ( 1.0 + (0.8 + 18./A - 0.002*A)/(1.0 + std::exp(f1*(elog + f2))));
return res;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -23,8 +23,8 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4BGGNucleonInelasticXS.cc,v 1.1 2007/03/13 15:19:30 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-01 $
// $Id: G4BGGNucleonInelasticXS.cc,v 1.3 2008/12/01 16:50:23 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-02 $
//
// -------------------------------------------------------------------
//
@@ -45,6 +45,7 @@
#include "G4BGGNucleonInelasticXS.hh"
#include "G4GlauberGribovCrossSection.hh"
#include "G4NucleonNuclearCrossSection.hh"
#include "G4HadronNucleonXsc.hh"
#include "G4Proton.hh"
#include "G4Neutron.hh"
#include "G4NistManager.hh"
@@ -54,22 +55,14 @@
G4BGGNucleonInelasticXS::G4BGGNucleonInelasticXS(const G4ParticleDefinition* p)
{
verboseLevel = 0;
thEnergy = 100.*GeV;
if(p == G4Proton::Proton() || p == G4Neutron::Neutron()) {
fNucleon = new G4NucleonNuclearCrossSection();
fGlauber = new G4GlauberGribovCrossSection();
particle = p;
Initialise();
} else {
fNucleon = 0;
fGlauber = 0;
particle = 0;
if(p) G4cout << "### G4BGGNucleonInelasticXS WARNING: is not applicable to "
<< p->GetParticleName()
<< G4endl;
else G4cout << "### G4BGGNucleonInelasticXS WARNING: particle is not defined "
<< G4endl;
}
fGlauberEnergy = 91.*GeV;
fLowEnergy = 20.*MeV;
fNucleon = 0;
fGlauber = 0;
fHadron = 0;
particle = p;
isProton = false;
isInitialized = false;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -78,6 +71,7 @@ G4BGGNucleonInelasticXS::~G4BGGNucleonInelasticXS()
{
delete fGlauber;
delete fNucleon;
delete fHadron;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -89,11 +83,27 @@ G4double G4BGGNucleonInelasticXS::GetIsoZACrossSection(const G4DynamicParticle*
{
G4double cross = 0.0;
G4double ekin = dp->GetKineticEnergy();
G4int iz = G4int(Z + 0.5);
G4int iz = G4int(Z);
if(iz > 92) iz = 92;
if(ekin > thEnergy) {
cross = theFac[iz]*fGlauber->GetInelasticGlauberGribov(dp, Z, A);
if(ekin <= fLowEnergy) {
cross = theCoulombFac[iz]*CoulombFactor(ekin, A);
} else if(iz == 1) {
if( A < 1.5) {
//fHadron->GetHadronNucleonXscPDG(dp, G4Proton::Proton());
//fHadron->GetHadronNucleonXscEL(dp, G4Proton::Proton());
//fHadron->GetHadronNucleonXscNS(dp, G4Proton::Proton());
//fHadron->GetHadronNucleonXscVU(dp, G4Proton::Proton());
fHadron->GetHadronNucleonXscMK(dp, G4Proton::Proton());
cross = fHadron->GetInelasticHadronNucleonXsc();
} else {
fHadron->GetHadronNucleonXscMK(dp, G4Proton::Proton());
cross = fHadron->GetInelasticHadronNucleonXsc();
fHadron->GetHadronNucleonXscMK(dp, G4Neutron::Neutron());
cross += fHadron->GetInelasticHadronNucleonXsc();
}
} else if(ekin > fGlauberEnergy) {
cross = theGlauberFac[iz]*fGlauber->GetInelasticGlauberGribov(dp, Z, A);
} else {
cross = fNucleon->GetIsoZACrossSection(dp, Z, A);
}
@@ -111,8 +121,16 @@ G4double G4BGGNucleonInelasticXS::GetIsoZACrossSection(const G4DynamicParticle*
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4BGGNucleonInelasticXS::BuildPhysicsTable(const G4ParticleDefinition&)
void G4BGGNucleonInelasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
{
if(&p == G4Proton::Proton() || &p == G4Neutron::Neutron()) {
particle = &p;
Initialise();
} else {
G4cout << "### G4BGGNucleonInelasticXS WARNING: is not applicable to "
<< p.GetParticleName()
<< G4endl;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -126,9 +144,19 @@ void G4BGGNucleonInelasticXS::DumpPhysicsTable(const G4ParticleDefinition&)
void G4BGGNucleonInelasticXS::Initialise()
{
if(isInitialized) return;
isInitialized = true;
fNucleon = new G4NucleonNuclearCrossSection();
fGlauber = new G4GlauberGribovCrossSection();
fHadron = new G4HadronNucleonXsc();
fNucleon->BuildPhysicsTable(*particle);
fGlauber->BuildPhysicsTable(*particle);
if(particle == G4Proton::Proton()) isProton = true;
G4ParticleDefinition* part = const_cast<G4ParticleDefinition*>(particle);
G4ThreeVector mom(0.0,0.0,1.0);
G4DynamicParticle dp(part, mom, thEnergy);
G4DynamicParticle dp(part, mom, fGlauberEnergy);
G4NistManager* nist = G4NistManager::Instance();
G4double A = nist->GetAtomicMassAmu(2);
@@ -146,12 +174,61 @@ void G4BGGNucleonInelasticXS::Initialise()
csup = fGlauber->GetInelasticGlauberGribov(&dp, Z, A);
csdn = fNucleon->GetIsoZACrossSection(&dp, Z, A);
theFac[iz] = csdn/csup;
theGlauberFac[iz] = csdn/csup;
if(verboseLevel > 0) G4cout << "Z= " << Z << " A= " << A
<< " factor= " << theFac[iz] << G4endl;
<< " factor= " << theGlauberFac[iz] << G4endl;
}
dp.SetKineticEnergy(fLowEnergy);
fHadron->GetHadronNucleonXscMK(&dp, G4Proton::Proton());
theCoulombFac[1] =
fHadron->GetInelasticHadronNucleonXsc()/CoulombFactor(fLowEnergy,1.0);
for(G4int iz=2; iz<93; iz++) {
G4double Z = G4double(iz);
A = nist->GetAtomicMassAmu(iz);
theCoulombFac[iz] =
fNucleon->GetIsoZACrossSection(&dp, Z, A)/CoulombFactor(fLowEnergy,A);
if(verboseLevel > 0) G4cout << "Z= " << Z << " A= " << A
<< " factor= " << theCoulombFac[iz] << G4endl;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4BGGNucleonInelasticXS::CoulombFactor(G4double kinEnergy, G4double A)
{
G4double res= 0.0;
if(kinEnergy <= DBL_MIN) return res;
else if (A < 1.5) return kinEnergy*kinEnergy;
G4double elog = std::log10(kinEnergy/GeV);
// from G4ProtonInelasticCrossSection
if(isProton) {
G4double f1 = 8.0 - 8.0/A - 0.008*A;
G4double f2 = 2.34 - 5.4/A - 0.0028*A;
res = 1.0/(1.0 + std::exp(-f1*(elog + f2)));
f1 = 5.6 - 0.016*A;
f2 = 1.37 + 1.37/A;
res *= ( 1.0 + (0.8 + 18./A - 0.002*A)/(1.0 + std::exp(f1*(elog + f2))));
} else {
G4double p3 = 0.6 + 13./A - 0.0005*A;
G4double p4 = 7.2449 - 0.018242*A;
G4double p5 = 1.36 + 1.8/A + 0.0005*A;
G4double p6 = 1. + 200./A + 0.02*A;
G4double p7 = 3.0 - (A-70.)*(A-200.)/11000.;
res = (1.+p3/(1. + std::exp(p4*(elog+p5))))/(1.+std::exp(-p6*(elog+p7)));
}
return res;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -23,8 +23,8 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4BGGPionElasticXS.cc,v 1.1 2007/03/13 15:19:30 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-01 $
// $Id: G4BGGPionElasticXS.cc,v 1.3 2008/12/01 16:50:23 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-02 $
//
// -------------------------------------------------------------------
//
@@ -45,31 +45,24 @@
#include "G4BGGPionElasticXS.hh"
#include "G4GlauberGribovCrossSection.hh"
#include "G4UPiNuclearCrossSection.hh"
#include "G4HadronNucleonXsc.hh"
#include "G4PionPlus.hh"
#include "G4PionMinus.hh"
#include "G4NistManager.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4BGGPionElasticXS::G4BGGPionElasticXS(const G4ParticleDefinition* p)
G4BGGPionElasticXS::G4BGGPionElasticXS(const G4ParticleDefinition*)
{
verboseLevel = 0;
thEnergy = 100.*GeV;
if(p == G4PionPlus::PionPlus() || p == G4PionMinus::PionMinus()) {
fPion = new G4UPiNuclearCrossSection();
fGlauber = new G4GlauberGribovCrossSection();
particle = p;
Initialise();
} else {
fPion = 0;
fGlauber = 0;
particle = 0;
if(p) G4cout << "### G4BGGPionElasticXS WARNING: is not applicable to "
<< p->GetParticleName()
<< G4endl;
else G4cout << "### G4BGGPionElasticXS WARNING: particle is not defined "
<< G4endl;
}
fGlauberEnergy = 91.*GeV;
fLowEnergy = 20.*MeV;
fPion = 0;
fGlauber = 0;
fHadron = 0;
particle = 0;
isPiplus = false;
isInitialized = false;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -78,6 +71,7 @@ G4BGGPionElasticXS::~G4BGGPionElasticXS()
{
delete fGlauber;
delete fPion;
delete fHadron;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -89,11 +83,29 @@ G4double G4BGGPionElasticXS::GetIsoZACrossSection(const G4DynamicParticle* dp,
{
G4double cross = 0.0;
G4double ekin = dp->GetKineticEnergy();
G4int iz = G4int(Z + 0.5);
G4int iz = G4int(Z);
if(iz > 92) iz = 92;
if(ekin > thEnergy) {
cross = theFac[iz]*fGlauber->GetElasticGlauberGribov(dp, Z, A);
if(ekin <= fLowEnergy) {
cross = theCoulombFac[iz];
if(isPiplus) { cross *= CoulombFactor(ekin, A); }
} else if(iz == 1) {
if( A < 1.5) {
//fHadron->GetHadronNucleonXscPDG(dp, G4Proton::Proton());
//fHadron->GetHadronNucleonXscEL(dp, G4Proton::Proton());
fHadron->GetHadronNucleonXscNS(dp, G4Proton::Proton());
//fHadron->GetHadronNucleonXscVU(dp, G4Proton::Proton());
//fHadron->GetHadronNucleonXscMK(dp, G4Proton::Proton());
cross = fHadron->GetElasticHadronNucleonXsc();
} else {
fHadron->GetHadronNucleonXscNS(dp, G4Proton::Proton());
cross = fHadron->GetElasticHadronNucleonXsc();
fHadron->GetHadronNucleonXscNS(dp, G4Neutron::Neutron());
cross += fHadron->GetElasticHadronNucleonXsc();
}
} else if(ekin > fGlauberEnergy) {
cross = theGlauberFac[iz]*fGlauber->GetElasticGlauberGribov(dp, Z, A);
} else {
cross = fPion->GetElasticCrossSection(dp, Z, A);
}
@@ -111,8 +123,16 @@ G4double G4BGGPionElasticXS::GetIsoZACrossSection(const G4DynamicParticle* dp,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4BGGPionElasticXS::BuildPhysicsTable(const G4ParticleDefinition&)
void G4BGGPionElasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
{
if(&p == G4PionPlus::PionPlus() || &p == G4PionMinus::PionMinus()) {
particle = &p;
Initialise();
} else {
G4cout << "### G4BGGPionElasticXS WARNING: is not applicable to "
<< p.GetParticleName()
<< G4endl;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -126,14 +146,23 @@ void G4BGGPionElasticXS::DumpPhysicsTable(const G4ParticleDefinition&)
void G4BGGPionElasticXS::Initialise()
{
if(isInitialized) return;
isInitialized = true;
fPion = new G4UPiNuclearCrossSection();
fGlauber = new G4GlauberGribovCrossSection();
fHadron = new G4HadronNucleonXsc();
fPion->BuildPhysicsTable(*particle);
fGlauber->BuildPhysicsTable(*particle);
if(particle == G4PionPlus::PionPlus()) isPiplus = true;
G4ParticleDefinition* part = const_cast<G4ParticleDefinition*>(particle);
G4ThreeVector mom(0.0,0.0,1.0);
G4DynamicParticle dp(part, mom, thEnergy);
G4DynamicParticle dp(part, mom, fGlauberEnergy);
G4NistManager* nist = G4NistManager::Instance();
G4double A = nist->GetAtomicMassAmu(2);
G4double csup, csdn;
G4double A, csup, csdn;
if(verboseLevel > 0) G4cout << "### G4BGGPionElasticXS::Initialise for "
<< particle->GetParticleName() << G4endl;
@@ -146,12 +175,49 @@ void G4BGGPionElasticXS::Initialise()
csup = fGlauber->GetElasticGlauberGribov(&dp, Z, A);
csdn = fPion->GetElasticCrossSection(&dp, Z, A);
theFac[iz] = csdn/csup;
theGlauberFac[iz] = csdn/csup;
if(verboseLevel > 0) G4cout << "Z= " << Z << " A= " << A
<< " factor= " << theFac[iz] << G4endl;
<< " factor= " << theGlauberFac[iz] << G4endl;
}
dp.SetKineticEnergy(fLowEnergy);
fHadron->GetHadronNucleonXscNS(&dp, G4Proton::Proton());
theCoulombFac[1] = fHadron->GetElasticHadronNucleonXsc();
if(isPiplus) { theCoulombFac[1] /= CoulombFactor(fLowEnergy,1.0); }
for(G4int iz=2; iz<93; iz++) {
G4double Z = G4double(iz);
A = nist->GetAtomicMassAmu(iz);
theCoulombFac[iz] = fPion->GetElasticCrossSection(&dp, Z, A);
if(isPiplus) { theCoulombFac[iz] /= CoulombFactor(fLowEnergy,A); }
if(verboseLevel > 0) G4cout << "Z= " << Z << " A= " << A
<< " factor= " << theCoulombFac[iz] << G4endl;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4BGGPionElasticXS::CoulombFactor(G4double kinEnergy, G4double A)
{
G4double res= 0.0;
if(kinEnergy <= DBL_MIN) return res;
else if(A < 1.5) return kinEnergy*kinEnergy;
G4double elog = std::log10(kinEnergy/GeV);
// from G4ProtonInelasticCrossSection
G4double f1 = 8.0 - 8.0/A - 0.008*A;
G4double f2 = 2.34 - 5.4/A - 0.0028*A;
res = 1.0/(1.0 + std::exp(-f1*(elog + f2)));
f1 = 5.6 - 0.016*A;
f2 = 1.37 + 1.37/A;
res *= ( 1.0 + (0.8 + 18./A - 0.002*A)/(1.0 + std::exp(f1*(elog + f2))));
return res;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -23,8 +23,8 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4BGGPionInelasticXS.cc,v 1.1 2007/03/13 15:19:30 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-01 $
// $Id: G4BGGPionInelasticXS.cc,v 1.3 2008/12/01 16:50:23 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-02 $
//
// -------------------------------------------------------------------
//
@@ -45,6 +45,7 @@
#include "G4BGGPionInelasticXS.hh"
#include "G4GlauberGribovCrossSection.hh"
#include "G4UPiNuclearCrossSection.hh"
#include "G4HadronNucleonXsc.hh"
#include "G4PionPlus.hh"
#include "G4PionMinus.hh"
#include "G4NistManager.hh"
@@ -54,22 +55,14 @@
G4BGGPionInelasticXS::G4BGGPionInelasticXS(const G4ParticleDefinition* p)
{
verboseLevel = 0;
thEnergy = 100.*GeV;
if(p == G4PionPlus::PionPlus() || p == G4PionMinus::PionMinus()) {
fPion = new G4UPiNuclearCrossSection();
fGlauber = new G4GlauberGribovCrossSection();
particle = p;
Initialise();
} else {
fPion = 0;
fGlauber = 0;
particle = 0;
if(p) G4cout << "### G4BGGPionInelasticXS WARNING: is not applicable to "
<< p->GetParticleName()
<< G4endl;
else G4cout << "### G4BGGPionInelasticXS WARNING: particle is not defined "
<< G4endl;
}
fGlauberEnergy = 91.*GeV;
fLowEnergy = 20.*MeV;
fPion = 0;
fGlauber = 0;
fHadron = 0;
particle = p;
isPiplus = false;
isInitialized = false;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -78,6 +71,7 @@ G4BGGPionInelasticXS::~G4BGGPionInelasticXS()
{
delete fGlauber;
delete fPion;
delete fHadron;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -89,13 +83,34 @@ G4double G4BGGPionInelasticXS::GetIsoZACrossSection(const G4DynamicParticle* dp,
{
G4double cross = 0.0;
G4double ekin = dp->GetKineticEnergy();
G4int iz = G4int(Z + 0.5);
G4int iz = G4int(Z);
if(iz > 92) iz = 92;
if(ekin > thEnergy) {
cross = theFac[iz]*fGlauber->GetInelasticGlauberGribov(dp, Z, A);
if(ekin <= fLowEnergy) {
cross = theCoulombFac[iz];
if(isPiplus) { cross *= CoulombFactor(ekin, A); }
} else if(iz == 1) {
if( A < 1.5) {
//fHadron->GetHadronNucleonXscPDG(dp, G4Proton::Proton());
//fHadron->GetHadronNucleonXscEL(dp, G4Proton::Proton());
fHadron->GetHadronNucleonXscNS(dp, G4Proton::Proton());
//fHadron->GetHadronNucleonXscVU(dp, G4Proton::Proton());
//fHadron->GetHadronNucleonXscMK(dp, G4Proton::Proton());
cross = fHadron->GetInelasticHadronNucleonXsc();
} else {
fHadron->GetHadronNucleonXscNS(dp, G4Proton::Proton());
cross = fHadron->GetInelasticHadronNucleonXsc();
fHadron->GetHadronNucleonXscNS(dp, G4Neutron::Neutron());
cross += fHadron->GetInelasticHadronNucleonXsc();
}
} else if(ekin > fGlauberEnergy) {
cross = theGlauberFac[iz]*fGlauber->GetInelasticGlauberGribov(dp, Z, A);
} else {
cross = fPion->GetInelasticCrossSection(dp, Z, A);
cross = fPion->GetIsoZACrossSection(dp, Z, A);
}
if(verboseLevel > 1)
@@ -111,8 +126,16 @@ G4double G4BGGPionInelasticXS::GetIsoZACrossSection(const G4DynamicParticle* dp,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4BGGPionInelasticXS::BuildPhysicsTable(const G4ParticleDefinition&)
void G4BGGPionInelasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
{
if(&p == G4PionPlus::PionPlus() || &p == G4PionMinus::PionMinus()) {
particle = &p;
Initialise();
} else {
G4cout << "### G4BGGPionInelasticXS WARNING: is not applicable to "
<< p.GetParticleName()
<< G4endl;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -126,17 +149,28 @@ void G4BGGPionInelasticXS::DumpPhysicsTable(const G4ParticleDefinition&)
void G4BGGPionInelasticXS::Initialise()
{
if(isInitialized) return;
isInitialized = true;
fPion = new G4UPiNuclearCrossSection();
fGlauber = new G4GlauberGribovCrossSection();
fHadron = new G4HadronNucleonXsc();
fPion->BuildPhysicsTable(*particle);
fGlauber->BuildPhysicsTable(*particle);
if(particle == G4PionPlus::PionPlus()) isPiplus = true;
G4ParticleDefinition* part = const_cast<G4ParticleDefinition*>(particle);
G4ThreeVector mom(0.0,0.0,1.0);
G4DynamicParticle dp(part, mom, thEnergy);
G4DynamicParticle dp(part, mom, fGlauberEnergy);
G4NistManager* nist = G4NistManager::Instance();
G4double A = nist->GetAtomicMassAmu(2);
G4double csup, csdn;
G4double A, csup, csdn;
if(verboseLevel > 0) G4cout << "### G4BGGPionInelasticXS::Initialise for "
<< particle->GetParticleName() << G4endl;
<< particle->GetParticleName()
<< " isPiplus: " << isPiplus
<< G4endl;
for(G4int iz=2; iz<93; iz++) {
@@ -146,12 +180,50 @@ void G4BGGPionInelasticXS::Initialise()
csup = fGlauber->GetInelasticGlauberGribov(&dp, Z, A);
csdn = fPion->GetInelasticCrossSection(&dp, Z, A);
theFac[iz] = csdn/csup;
theGlauberFac[iz] = csdn/csup;
if(verboseLevel > 0) G4cout << "Z= " << Z << " A= " << A
<< " factor= " << theFac[iz] << G4endl;
<< " factor= " << theGlauberFac[iz] << G4endl;
}
dp.SetKineticEnergy(fLowEnergy);
fHadron->GetHadronNucleonXscNS(&dp, G4Proton::Proton());
theCoulombFac[1] = fHadron->GetInelasticHadronNucleonXsc();
if(isPiplus) { theCoulombFac[1] /= CoulombFactor(fLowEnergy,1.0); }
for(G4int iz=2; iz<93; iz++) {
G4double Z = G4double(iz);
A = nist->GetAtomicMassAmu(iz);
theCoulombFac[iz] = fPion->GetIsoZACrossSection(&dp, Z, A);
if(isPiplus) { theCoulombFac[iz] /= CoulombFactor(fLowEnergy,A); }
if(verboseLevel > 0) G4cout << "Z= " << Z << " A= " << A
<< " factor= " << theCoulombFac[iz] << G4endl;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4BGGPionInelasticXS::CoulombFactor(G4double kinEnergy, G4double A)
{
G4double res= 0.0;
if(kinEnergy <= DBL_MIN) return res;
else if(A < 1.5) return kinEnergy*kinEnergy;
G4double elog = std::log10(kinEnergy/GeV);
// from G4ProtonInelasticCrossSection
G4double f1 = 8.0 - 8.0/A - 0.008*A;
G4double f2 = 2.34 - 5.4/A - 0.0028*A;
res = 1.0/(1.0 + std::exp(-f1*(elog + f2)));
f1 = 5.6 - 0.016*A;
f2 = 1.37 + 1.37/A;
res *= ( 1.0 + (0.8 + 18./A - 0.002*A)/(1.0 + std::exp(f1*(elog + f2))));
return res;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -30,6 +30,7 @@
#include "G4StableIsotopes.hh"
#include "G4HadTmpUtil.hh"
#include "Randomize.hh"
#include "G4Nucleus.hh"
G4double
@@ -53,6 +54,28 @@ G4CrossSectionDataStore::GetCrossSection(const G4DynamicParticle* aParticle,
return DBL_MIN;
}
G4VCrossSectionDataSet*
G4CrossSectionDataStore::whichDataSetInCharge(const G4DynamicParticle* aParticle,
const G4Element* anElement)
{
if (NDataSetList == 0)
{
throw G4HadronicException(__FILE__, __LINE__,
"G4CrossSectionDataStore: no data sets registered");
return 0;
}
for (G4int i = NDataSetList-1; i >= 0; i--) {
if (DataSetList[i]->IsApplicable(aParticle, anElement) )
{
return DataSetList[i];
}
}
throw G4HadronicException(__FILE__, __LINE__,
"G4CrossSectionDataStore: no applicable data set found "
"for particle/element");
return 0;
}
G4double
G4CrossSectionDataStore::GetCrossSection(const G4DynamicParticle* aParticle,
@@ -117,6 +140,259 @@ G4CrossSectionDataStore::GetCrossSection(const G4DynamicParticle* aParticle,
}
G4Element* G4CrossSectionDataStore::SampleZandA(const G4DynamicParticle* particle,
const G4Material* aMaterial,
G4Nucleus& target)
{
G4double aTemp = aMaterial->GetTemperature();
const G4int nElements = aMaterial->GetNumberOfElements();
const G4ElementVector* theElementVector = aMaterial->GetElementVector();
G4Element* anElement = (*theElementVector)[0];
G4VCrossSectionDataSet* inCharge;
G4int i;
// compounds
if(1 < nElements) {
G4double* xsec = new G4double [nElements];
const G4double* theAtomsPerVolumeVector = aMaterial->GetVecNbOfAtomsPerVolume();
G4double cross = 0.0;
for(i=0; i<nElements; i++) {
anElement= (*theElementVector)[i];
inCharge = whichDataSetInCharge(particle, anElement);
cross += theAtomsPerVolumeVector[i]*
inCharge->GetCrossSection(particle, anElement, aTemp);
xsec[i] = cross;
}
cross *= G4UniformRand();
for(i=0; i<nElements; i++) {
if( cross <= xsec[i] ) {
anElement = (*theElementVector)[i];
break;
}
}
delete [] xsec;
}
// element have been selected
inCharge = whichDataSetInCharge(particle, anElement);
G4double ZZ = anElement->GetZ();
G4double AA;
// Collect abundance weighted cross sections and A values for each isotope
// in each element
const G4int nIsoPerElement = anElement->GetNumberOfIsotopes();
// user-defined isotope abundances
if (0 < nIsoPerElement) {
G4IsotopeVector* isoVector = anElement->GetIsotopeVector();
AA = G4double((*isoVector)[0]->GetN());
if(1 < nIsoPerElement) {
G4double* xsec = new G4double [nIsoPerElement];
G4double iso_xs = 0.0;
G4double cross = 0.0;
G4double* abundVector = anElement->GetRelativeAbundanceVector();
G4bool elementXS = false;
for (i = 0; i<nIsoPerElement; i++) {
if (inCharge->IsZAApplicable(particle, ZZ, G4double((*isoVector)[i]->GetN()))) {
iso_xs = inCharge->GetIsoCrossSection(particle, (*isoVector)[i], aTemp);
} else if (elementXS == false) {
iso_xs = inCharge->GetCrossSection(particle, anElement, aTemp);
elementXS = true;
}
cross += abundVector[i]*iso_xs;
xsec[i] = cross;
}
cross *= G4UniformRand();
for (i = 0; i<nIsoPerElement; i++) {
if(cross <= xsec[i]) {
AA = G4double((*isoVector)[i]->GetN());
break;
}
}
delete [] xsec;
}
// natural abundances
} else {
G4StableIsotopes theDefaultIsotopes;
G4int Z = G4int(ZZ + 0.5);
const G4int nIso = theDefaultIsotopes.GetNumberOfIsotopes(Z);
G4int index = theDefaultIsotopes.GetFirstIsotope(Z);
AA = G4double(theDefaultIsotopes.GetIsotopeNucleonCount(index));
if(1 < nIso) {
G4double* xsec = new G4double [nIso];
G4double iso_xs = 0.0;
G4double cross = 0.0;
G4bool elementXS= false;
for (i = 0; i<nIso; i++) {
AA = G4double(theDefaultIsotopes.GetIsotopeNucleonCount(index+i));
if (inCharge->IsZAApplicable(particle, ZZ, AA )) {
iso_xs = inCharge->GetIsoZACrossSection(particle, ZZ, AA, aTemp);
} else if (elementXS == false) {
iso_xs = inCharge->GetCrossSection(particle, anElement, aTemp);
elementXS = true;
}
cross += theDefaultIsotopes.GetAbundance(index+i)*iso_xs;
xsec[i] = cross;
}
cross *= G4UniformRand();
for (i = 0; i<nIso; i++) {
if(cross <= xsec[i]) {
AA = G4double(theDefaultIsotopes.GetIsotopeNucleonCount(index+i));
break;
}
}
delete [] xsec;
}
}
//G4cout << "XS: " << particle->GetDefinition()->GetParticleName()
// << " e(GeV)= " << particle->GetKineticEnergy()/GeV
// << " in " << aMaterial->GetName()
// << " ZZ= " << ZZ << " AA= " << AA << " " << anElement->GetName() << G4endl;
target.SetParameters(AA, ZZ);
return anElement;
}
/*
G4Element* G4CrossSectionDataStore::SampleZandA(const G4DynamicParticle* particle,
const G4Material* aMaterial,
G4Nucleus& target)
{
static G4StableIsotopes theDefaultIsotopes; // natural abundances and
// stable isotopes
G4double aTemp = aMaterial->GetTemperature();
G4int nElements = aMaterial->GetNumberOfElements();
const G4ElementVector* theElementVector = aMaterial->GetElementVector();
const G4double* theAtomsPerVolumeVector = aMaterial->GetVecNbOfAtomsPerVolume();
std::vector<std::vector<G4double> > awicsPerElement;
std::vector<std::vector<G4double> > AvaluesPerElement;
G4Element* anElement;
// Collect abundance weighted cross sections and A values for each isotope
// in each element
for (G4int i = 0; i < nElements; i++) {
anElement = (*theElementVector)[i];
G4int nIsoPerElement = anElement->GetNumberOfIsotopes();
std::vector<G4double> isoholder;
std::vector<G4double> aholder;
G4double iso_xs = DBL_MIN;
if (nIsoPerElement) { // user-defined isotope abundances
G4IsotopeVector* isoVector = anElement->GetIsotopeVector();
G4double* abundVector = anElement->GetRelativeAbundanceVector();
G4VCrossSectionDataSet* inCharge = whichDataSetInCharge(particle, anElement);
G4bool elementXS = false;
for (G4int j = 0; j < nIsoPerElement; j++) {
if (inCharge->IsZAApplicable(particle, (*isoVector)[j]->GetZ(),
(*isoVector)[j]->GetN() ) ) {
iso_xs = inCharge->GetIsoCrossSection(particle, (*isoVector)[j], aTemp);
} else if (elementXS == false) {
iso_xs = inCharge->GetCrossSection(particle, anElement, aTemp);
elementXS = true;
}
isoholder.push_back(abundVector[j]*iso_xs);
aholder.push_back(G4double((*isoVector)[j]->GetN()));
}
} else { // natural abundances
G4int ZZ = G4lrint(anElement->GetZ());
nIsoPerElement = theDefaultIsotopes.GetNumberOfIsotopes(ZZ);
G4int index = theDefaultIsotopes.GetFirstIsotope(ZZ);
G4double AA;
G4double abundance;
G4VCrossSectionDataSet* inCharge = whichDataSetInCharge(particle, anElement);
G4bool elementXS = false;
for (G4int j = 0; j < nIsoPerElement; j++) {
AA = G4double(theDefaultIsotopes.GetIsotopeNucleonCount(index+j));
aholder.push_back(AA);
if (inCharge->IsZAApplicable(particle, G4double(ZZ), AA) ) {
iso_xs = inCharge->GetIsoZACrossSection(particle, G4double(ZZ), AA, aTemp);
} else if (elementXS == false) {
iso_xs = inCharge->GetCrossSection(particle, anElement, aTemp);
elementXS = true;
}
abundance = theDefaultIsotopes.GetAbundance(index+j)/100.0;
isoholder.push_back(abundance*iso_xs);
}
}
awicsPerElement.push_back(isoholder);
AvaluesPerElement.push_back(aholder);
}
// Calculate running sums for isotope selection
G4double crossSectionTotal = 0;
G4double xSectionPerElement;
std::vector<G4double> runningSum;
for (G4int i=0; i < nElements; i++) {
xSectionPerElement = 0;
for (G4int j=0; j < G4int(awicsPerElement[i].size()); j++)
xSectionPerElement += awicsPerElement[i][j];
runningSum.push_back(theAtomsPerVolumeVector[i]*xSectionPerElement);
crossSectionTotal += runningSum[i];
}
// Compare random number to running sum over element xc to choose Z
// Initialize Z and A to first element and first isotope in case
// cross section is zero
anElement = (*theElementVector)[0];
G4double ZZ = anElement->GetZ();
G4double AA = AvaluesPerElement[0][0];
if (crossSectionTotal != 0.) {
G4double random = G4UniformRand();
for(G4int i=0; i < nElements; i++) {
if(i!=0) runningSum[i] += runningSum[i-1];
if(random <= runningSum[i]/crossSectionTotal) {
anElement = (*theElementVector)[i];
ZZ = anElement->GetZ();
// Compare random number to running sum over isotope xc to choose A
G4int nIso = awicsPerElement[i].size();
G4double* running = new G4double[nIso];
for (G4int j=0; j < nIso; j++) {
running[j] = awicsPerElement[i][j];
if(j!=0) running[j] += running[j-1];
}
G4double trial = G4UniformRand();
for (G4int j=0; j < nIso; j++) {
AA = AvaluesPerElement[i][j];
if (trial <= running[j]/running[nIso-1]) break;
}
delete [] running;
break;
}
}
}
//G4cout << "XS: " << particle->GetDefinition()->GetParticleName()
// << " e(GeV)= " << particle->GetKineticEnergy()/GeV
// << " in " << aMaterial->GetName()
// << " ZZ= " << ZZ << " AA= " << AA << " " << anElement->GetName() << G4endl;
target.SetParameters(AA, ZZ);
return anElement;
}
*/
std::pair<G4double, G4double>
G4CrossSectionDataStore::SelectRandomIsotope(const G4DynamicParticle* particle,
const G4Material* aMaterial)
@@ -139,13 +415,22 @@ G4CrossSectionDataStore::SelectRandomIsotope(const G4DynamicParticle* particle,
G4int nIsoPerElement = anElement->GetNumberOfIsotopes();
std::vector<G4double> isoholder;
std::vector<G4double> aholder;
G4double iso_xs;
G4double iso_xs = DBL_MIN;
if (nIsoPerElement) { // user-defined isotope abundances
G4IsotopeVector* isoVector = anElement->GetIsotopeVector();
G4double* abundVector = anElement->GetRelativeAbundanceVector();
G4VCrossSectionDataSet* inCharge = whichDataSetInCharge(particle, anElement);
G4bool elementXS = false;
for (G4int j = 0; j < nIsoPerElement; j++) {
iso_xs = GetCrossSection(particle, (*isoVector)[j], aTemp);
if (inCharge->IsZAApplicable(particle, (*isoVector)[j]->GetZ(),
(*isoVector)[j]->GetN() ) ) {
iso_xs = inCharge->GetIsoCrossSection(particle, (*isoVector)[j], aTemp);
} else if (elementXS == false) {
iso_xs = inCharge->GetCrossSection(particle, anElement, aTemp);
elementXS = true;
}
isoholder.push_back(abundVector[j]*iso_xs);
aholder.push_back(G4double((*isoVector)[j]->GetN()));
}
@@ -156,10 +441,19 @@ G4CrossSectionDataStore::SelectRandomIsotope(const G4DynamicParticle* particle,
G4int index = theDefaultIsotopes.GetFirstIsotope(ZZ);
G4double AA;
G4double abundance;
G4VCrossSectionDataSet* inCharge = whichDataSetInCharge(particle, anElement);
G4bool elementXS = false;
for (G4int j = 0; j < nIsoPerElement; j++) {
AA = G4double(theDefaultIsotopes.GetIsotopeNucleonCount(index+j));
aholder.push_back(AA);
iso_xs = GetCrossSection(particle, G4double(ZZ), AA, aTemp);
if (inCharge->IsZAApplicable(particle, G4double(ZZ), AA) ) {
iso_xs = inCharge->GetIsoZACrossSection(particle, G4double(ZZ), AA, aTemp);
} else if (elementXS == false) {
iso_xs = inCharge->GetCrossSection(particle, anElement, aTemp);
elementXS = true;
}
abundance = theDefaultIsotopes.GetAbundance(index+j)/100.0;
isoholder.push_back(abundance*iso_xs);
}
@@ -24,8 +24,8 @@
// ********************************************************************
//
//
// $Id: G4ElectroNuclearCrossSection.cc,v 1.27 2007/06/15 16:36:39 gcosmo Exp $
// GEANT4 tag $Name: geant4-09-01 $
// $Id: G4ElectroNuclearCrossSection.cc,v 1.29 2008/10/24 19:15:17 dennis Exp $
// GEANT4 tag $Name: geant4-09-02 $
//
//
// G4 Physics class: G4ElectroNuclearCrossSection for gamma+A cross sections
@@ -232,6 +232,41 @@ G4ElectroNuclearCrossSection::GetIsoZACrossSection(const G4DynamicParticle* aPar
return lastSig*millibarn;
}
// Gives the threshold energy for different nuclei (min of p- and n-threshold)
G4double G4ElectroNuclearCrossSection::ThresholdEnergy(G4int Z, G4int N)
{
// CHIPS - Direct GEANT
//static const G4double mNeut = G4QPDGCode(2112).GetMass();
//static const G4double mProt = G4QPDGCode(2212).GetMass();
static const G4double mNeut = G4NucleiProperties::GetNuclearMass(1,0);
static const G4double mProt = G4NucleiProperties::GetNuclearMass(1,1);
// ---------
static const G4double infEn = 9.e27;
G4int A=Z+N;
if(A<1) return infEn;
else if(A==1) return 134.9766; // Pi0 threshold for the nucleon
// CHIPS - Direct GEANT
//G4double mT= G4QPDGCode(111).GetNuclMass(Z,N,0);
G4double mT= 0.;
if(G4NucleiProperties::IsInStableTable(A,Z)) mT = G4NucleiProperties::GetNuclearMass(A,Z);
// If it is not in the Table of Stable Nuclei, then the Threshold=inf
else return infEn;
// ---------
G4double mP= infEn;
//if(Z) mP= G4QPDGCode(111).GetNuclMass(Z-1,N,0);
if(Z&&G4NucleiProperties::IsInStableTable(A-1,Z-1)) mP = G4NucleiProperties::GetNuclearMass(A-1,Z-1);
else return infEn;
G4double mN= infEn;
//if(N) mN= G4QPDGCode(111).GetNuclMass(Z,N-1,0);
if(N&&G4NucleiProperties::IsInStableTable(A-1,Z)) mN = G4NucleiProperties::GetNuclearMass(A-1,Z);
else return infEn;
G4double dP= mP+mProt-mT;
G4double dN= mN+mNeut-mT;
if(dP<dN)dN=dP;
return dN;
}
// Correction function for Be,C @@ Move to header // @@@ !!! NOT used !!!
//G4double G4ElectroNuclearCrossSection::LinearFit(G4double X, G4int N, const G4double* XN,
// const G4double* YN)
@@ -0,0 +1,928 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// 24.11.08 V. Grichine - first implementation
//
#include "G4GGNuclNuclCrossSection.hh"
#include "G4ParticleTable.hh"
#include "G4IonTable.hh"
#include "G4ParticleDefinition.hh"
////////////////////////////////////////////////////////////////////////////////
//
//
G4GGNuclNuclCrossSection::G4GGNuclNuclCrossSection()
: fUpperLimit( 100000 * GeV ),
fLowerLimit( 0.1 * GeV ),
fRadiusConst( 1.08*fermi ) // 1.1, 1.3 ?
{
theProton = G4Proton::Proton();
theNeutron = G4Neutron::Neutron();
}
///////////////////////////////////////////////////////////////////////////////////////
//
//
G4GGNuclNuclCrossSection::~G4GGNuclNuclCrossSection()
{
}
////////////////////////////////////////////////////////////////////////////////////////
//
//
G4bool
G4GGNuclNuclCrossSection::IsApplicable(const G4DynamicParticle* aDP,
const G4Element* anElement)
{
return IsZAApplicable(aDP, anElement->GetZ(), anElement->GetN());
}
////////////////////////////////////////////////////////////////////////////////////////
//
//
G4bool
G4GGNuclNuclCrossSection::IsZAApplicable(const G4DynamicParticle* aDP,
G4double Z, G4double)
{
G4bool applicable = false;
// G4int baryonNumber = aDP->GetDefinition()->GetBaryonNumber();
G4double kineticEnergy = aDP->GetKineticEnergy();
// const G4ParticleDefinition* theParticle = aDP->GetDefinition();
if ( kineticEnergy >= fLowerLimit && Z > 1.5 ) applicable = true;
return applicable;
}
////////////////////////////////////////////////////////////////////////////////////////
//
// Calculates total and inelastic Xsc, derives elastic as total - inelastic accordong to
// Glauber model with Gribov correction calculated in the dipole approximation on
// light cone. Gaussian density helps to calculate rest integrals of the model.
// [1] B.Z. Kopeliovich, nucl-th/0306044
G4double G4GGNuclNuclCrossSection::
GetCrossSection(const G4DynamicParticle* aParticle, const G4Element* anElement, G4double T)
{
return GetIsoZACrossSection(aParticle, anElement->GetZ(), anElement->GetN(), T);
}
////////////////////////////////////////////////////////////////////////////////////////
//
// Calculates total and inelastic Xsc, derives elastic as total - inelastic accordong to
// Glauber model with Gribov correction calculated in the dipole approximation on
// light cone. Gaussian density of point-like nucleons helps to calculate rest integrals of the model.
// [1] B.Z. Kopeliovich, nucl-th/0306044 + simplification above
G4double G4GGNuclNuclCrossSection::
GetIsoZACrossSection(const G4DynamicParticle* aParticle, G4double tZ, G4double tA, G4double)
{
G4double xsection, sigma, cofInelastic = 2.4, cofTotal = 2.0, nucleusSquare, ratio;
G4double pZ = aParticle->GetDefinition()->GetPDGCharge();
G4double pA = aParticle->GetDefinition()->GetBaryonNumber();
G4double pTkin = aParticle->GetKineticEnergy();
pTkin /= pA;
G4double pN = pA - pZ;
if( pN < 0. ) pN = 0.;
G4double tN = tA - tZ;
if( tN < 0. ) tN = 0.;
G4double tR = GetNucleusRadius(tA);
G4double pR = GetNucleusRadius(pA);
sigma = (pZ*tZ+pN*tN)*GetHadronNucleonXscNS(theProton, pTkin, theProton) +
(pZ*tN+pN*tZ)*GetHadronNucleonXscNS(theProton, pTkin, theNeutron);
nucleusSquare = cofTotal*pi*( pR*pR + tR*tR ); // basically 2piRR
ratio = sigma/nucleusSquare;
xsection = nucleusSquare*std::log( 1. + ratio );
fTotalXsc = xsection;
fInelasticXsc = nucleusSquare*std::log( 1. + cofInelastic*ratio )/cofInelastic;
fElasticXsc = fTotalXsc - fInelasticXsc;
G4double difratio = ratio/(1.+ratio);
fDiffractionXsc = 0.5*nucleusSquare*( difratio - std::log( 1. + difratio ) );
// production to be checked !!! edit MK xsc
sigma = (pZ*tZ+pN*tN)*GetHadronNucleonXscMK(theProton, pTkin, theProton) +
(pZ*tN+pN*tZ)*GetHadronNucleonXscMK(theProton, pTkin, theNeutron);
ratio = sigma/nucleusSquare;
fProductionXsc = nucleusSquare*std::log( 1. + cofInelastic*ratio )/cofInelastic;
if (fElasticXsc < 0.) fElasticXsc = 0.;
return xsection;
}
//////////////////////////////////////////////////////////////////////////
//
// Return single-diffraction/inelastic cross-section ratio
G4double G4GGNuclNuclCrossSection::
GetRatioSD(const G4DynamicParticle* aParticle, G4double tA, G4double tZ)
{
G4double sigma, cofInelastic = 2.4, cofTotal = 2.0, nucleusSquare, ratio;
G4double pZ = aParticle->GetDefinition()->GetPDGCharge();
G4double pA = aParticle->GetDefinition()->GetBaryonNumber();
G4double pTkin = aParticle->GetKineticEnergy();
pTkin /= pA;
G4double pN = pA - pZ;
if( pN < 0. ) pN = 0.;
G4double tN = tA - tZ;
if( tN < 0. ) tN = 0.;
G4double tR = GetNucleusRadius(tA);
G4double pR = GetNucleusRadius(pA);
sigma = (pZ*tZ+pN*tN)*GetHadronNucleonXscNS(theProton, pTkin, theProton) +
(pZ*tN+pN*tZ)*GetHadronNucleonXscNS(theProton, pTkin, theNeutron);
nucleusSquare = cofTotal*pi*( pR*pR + tR*tR ); // basically 2piRR
ratio = sigma/nucleusSquare;
fInelasticXsc = nucleusSquare*std::log( 1. + cofInelastic*ratio )/cofInelastic;
G4double difratio = ratio/(1.+ratio);
fDiffractionXsc = 0.5*nucleusSquare*( difratio - std::log( 1. + difratio ) );
if (fInelasticXsc > 0.) ratio = fDiffractionXsc/fInelasticXsc;
else ratio = 0.;
return ratio;
}
//////////////////////////////////////////////////////////////////////////
//
// Return suasi-elastic/inelastic cross-section ratio
G4double G4GGNuclNuclCrossSection::
GetRatioQE(const G4DynamicParticle* aParticle, G4double tA, G4double tZ)
{
G4double sigma, cofInelastic = 2.4, cofTotal = 2.0, nucleusSquare, ratio;
G4double pZ = aParticle->GetDefinition()->GetPDGCharge();
G4double pA = aParticle->GetDefinition()->GetBaryonNumber();
G4double pTkin = aParticle->GetKineticEnergy();
pTkin /= pA;
G4double pN = pA - pZ;
if( pN < 0. ) pN = 0.;
G4double tN = tA - tZ;
if( tN < 0. ) tN = 0.;
G4double tR = GetNucleusRadius(tA);
G4double pR = GetNucleusRadius(pA);
sigma = (pZ*tZ+pN*tN)*GetHadronNucleonXscNS(theProton, pTkin, theProton) +
(pZ*tN+pN*tZ)*GetHadronNucleonXscNS(theProton, pTkin, theNeutron);
nucleusSquare = cofTotal*pi*( pR*pR + tR*tR ); // basically 2piRR
ratio = sigma/nucleusSquare;
fInelasticXsc = nucleusSquare*std::log( 1. + cofInelastic*ratio )/cofInelastic;
// sigma = GetHNinelasticXsc(aParticle, tA, tZ);
ratio = sigma/nucleusSquare;
fProductionXsc = nucleusSquare*std::log( 1. + cofInelastic*ratio )/cofInelastic;
if (fInelasticXsc > fProductionXsc) ratio = (fInelasticXsc-fProductionXsc)/fInelasticXsc;
else ratio = 0.;
if ( ratio < 0. ) ratio = 0.;
return ratio;
}
/////////////////////////////////////////////////////////////////////////////////////
//
// 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
G4GGNuclNuclCrossSection::GetHadronNucleonXsc(const G4DynamicParticle* aParticle,
const G4Element* anElement )
{
G4double At = anElement->GetN(); // number of nucleons
G4double Zt = anElement->GetZ(); // 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
G4GGNuclNuclCrossSection::GetHadronNucleonXsc(const G4DynamicParticle* aParticle,
G4double At, G4double Zt )
{
G4double xsection = 0.;
G4double targ_mass = G4ParticleTable::GetParticleTable()->
GetIonTable()->GetIonMass( G4int(Zt+0.5) , G4int(At+0.5) );
targ_mass = 0.939*GeV; // ~mean neutron and proton ???
G4double proj_mass = aParticle->GetMass();
G4double proj_momentum = aParticle->GetMomentum().mag();
G4double sMand = CalcMandelstamS ( proj_mass , targ_mass , proj_momentum );
sMand /= GeV*GeV; // in GeV for parametrisation
proj_momentum /= GeV;
const G4ParticleDefinition* pParticle = aParticle->GetDefinition();
if(pParticle == theNeutron) // as proton ???
{
xsection = At*(21.70*std::pow(sMand,0.0808) + 56.08*std::pow(sMand,-0.4525));
}
else if(pParticle == theProton)
{
xsection = At*(21.70*std::pow(sMand,0.0808) + 56.08*std::pow(sMand,-0.4525));
// xsection = At*( 49.51*std::pow(sMand,-0.097) + 0.314*std::log(sMand)*std::log(sMand) );
// xsection = At*( 38.4 + 0.85*std::abs(std::pow(log(sMand),1.47)) );
}
xsection *= millibarn;
return xsection;
}
/////////////////////////////////////////////////////////////////////////////////////
//
// Returns hadron-nucleon Xsc according to PDG parametrisation (2005):
// http://pdg.lbl.gov/2006/reviews/hadronicrpp.pdf
G4double
G4GGNuclNuclCrossSection::GetHadronNucleonXscPDG(const G4DynamicParticle* aParticle,
const G4Element* anElement )
{
G4double At = anElement->GetN(); // number of nucleons
G4double Zt = anElement->GetZ(); // number of protons
return GetHadronNucleonXscPDG( 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
G4GGNuclNuclCrossSection::GetHadronNucleonXscPDG(const G4DynamicParticle* aParticle,
G4double At, G4double Zt )
{
G4double xsection = 0.;
G4double Nt = At-Zt; // number of neutrons
if (Nt < 0.) Nt = 0.;
G4double targ_mass = G4ParticleTable::GetParticleTable()->
GetIonTable()->GetIonMass( G4int(Zt+0.5) , G4int(At+0.5) );
targ_mass = 0.939*GeV; // ~mean neutron and proton ???
G4double proj_mass = aParticle->GetMass();
G4double proj_momentum = aParticle->GetMomentum().mag();
G4double sMand = CalcMandelstamS ( proj_mass , targ_mass , proj_momentum );
sMand /= GeV*GeV; // in GeV for parametrisation
// General PDG fit constants
G4double s0 = 5.38*5.38; // in Gev^2
G4double eta1 = 0.458;
G4double eta2 = 0.458;
G4double B = 0.308;
const G4ParticleDefinition* pParticle = aParticle->GetDefinition();
if(pParticle == theNeutron) // proton-neutron fit
{
xsection = Zt*( 35.80 + B*std::pow(std::log(sMand/s0),2.)
+ 40.15*std::pow(sMand,-eta1) - 30.*std::pow(sMand,-eta2));
xsection += Nt*( 35.45 + B*std::pow(std::log(sMand/s0),2.)
+ 42.53*std::pow(sMand,-eta1) - 33.34*std::pow(sMand,-eta2)); // pp for nn
}
else if(pParticle == theProton)
{
xsection = Zt*( 35.45 + B*std::pow(std::log(sMand/s0),2.)
+ 42.53*std::pow(sMand,-eta1) - 33.34*std::pow(sMand,-eta2));
xsection += Nt*( 35.80 + B*std::pow(std::log(sMand/s0),2.)
+ 40.15*std::pow(sMand,-eta1) - 30.*std::pow(sMand,-eta2));
}
xsection *= millibarn; // parametrised in mb
return xsection;
}
/////////////////////////////////////////////////////////////////////////////////////
//
// Returns 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
G4GGNuclNuclCrossSection::GetHadronNucleonXscNS( G4ParticleDefinition* pParticle,
G4double pTkin,
G4ParticleDefinition* tParticle)
{
G4double xsection(0), Delta, A0, B0;
G4double hpXsc(0);
G4double hnXsc(0);
G4double targ_mass = tParticle->GetPDGMass();
G4double proj_mass = pParticle->GetPDGMass();
G4double proj_energy = proj_mass + pTkin;
G4double proj_momentum = std::sqrt(pTkin*(pTkin+2*proj_mass));
G4double sMand = CalcMandelstamS ( proj_mass , targ_mass , proj_momentum );
sMand /= GeV*GeV; // in GeV for parametrisation
proj_momentum /= GeV;
proj_energy /= GeV;
proj_mass /= GeV;
// General PDG fit constants
// G4double s0 = 5.38*5.38; // in Gev^2
// G4double eta1 = 0.458;
// G4double eta2 = 0.458;
// G4double B = 0.308;
if( proj_momentum >= 10. ) // high energy: pp = nn = np
// if( proj_momentum >= 2.)
{
Delta = 1.;
if( proj_energy < 40. ) Delta = 0.916+0.0021*proj_energy;
if( proj_momentum >= 10.)
{
B0 = 7.5;
A0 = 100. - B0*std::log(3.0e7);
xsection = A0 + B0*std::log(proj_energy) - 11
+ 103*std::pow(2*0.93827*proj_energy + proj_mass*proj_mass+
0.93827*0.93827,-0.165); // mb
}
}
else // low energy pp = nn != np
{
if(pParticle == tParticle) // pp or nn // nn to be pp
{
if( proj_momentum < 0.73 )
{
hnXsc = 23 + 50*( std::pow( std::log(0.73/proj_momentum), 3.5 ) );
}
else if( proj_momentum < 1.05 )
{
hnXsc = 23 + 40*(std::log(proj_momentum/0.73))*
(std::log(proj_momentum/0.73));
}
else // if( proj_momentum < 10. )
{
hnXsc = 39.0 +
75*(proj_momentum - 1.2)/(std::pow(proj_momentum,3.0) + 0.15);
}
xsection = hnXsc;
}
else // pn to be np
{
if( proj_momentum < 0.8 )
{
hpXsc = 33+30*std::pow(std::log(proj_momentum/1.3),4.0);
}
else if( proj_momentum < 1.4 )
{
hpXsc = 33+30*std::pow(std::log(proj_momentum/0.95),2.0);
}
else // if( proj_momentum < 10. )
{
hpXsc = 33.3+
20.8*(std::pow(proj_momentum,2.0)-1.35)/
(std::pow(proj_momentum,2.50)+0.95);
}
xsection = hpXsc;
}
}
xsection *= millibarn; // parametrised in mb
return xsection;
}
/*
/////////////////////////////////////////////////////////////////////////////////////
//
// Returns hadron-nucleon inelastic cross-section based on proper parametrisation
G4double
G4GGNuclNuclCrossSection::GetHNinelasticXsc(const G4DynamicParticle* aParticle,
const G4Element* anElement )
{
G4double At = anElement->GetN(); // number of nucleons
G4double Zt = anElement->GetZ(); // number of protons
return GetHNinelasticXsc( aParticle, At, Zt );
}
/////////////////////////////////////////////////////////////////////////////////////
//
// Returns hadron-nucleon inelastic cross-section based on FTF-parametrisation
G4double
G4GGNuclNuclCrossSection::GetHNinelasticXsc(const G4DynamicParticle* aParticle,
G4double At, G4double Zt )
{
// G4ParticleDefinition* hadron = aParticle->GetDefinition();
G4double sumInelastic, Nt = At - Zt;
if(Nt < 0.) Nt = 0.;
sumInelastic = Zt*GetHadronNucleonXscMK(aParticle, theProton);
sumInelastic += Nt*GetHadronNucleonXscMK(aParticle, theNeutron);
return sumInelastic;
}
*/
/////////////////////////////////////////////////////////////////////////////////////
//
// Returns hadron-nucleon inelastic cross-section based on FTF-parametrisation
G4double
G4GGNuclNuclCrossSection::GetHNinelasticXscVU(const G4DynamicParticle* aParticle,
G4double At, G4double Zt )
{
G4int PDGcode = aParticle->GetDefinition()->GetPDGEncoding();
G4int absPDGcode = std::abs(PDGcode);
G4double Elab = aParticle->GetTotalEnergy();
// (s - 2*0.88*GeV*GeV)/(2*0.939*GeV)/GeV;
G4double Plab = aParticle->GetMomentum().mag();
// std::sqrt(Elab * Elab - 0.88);
Elab /= GeV;
Plab /= GeV;
G4double LogPlab = std::log( Plab );
G4double sqrLogPlab = LogPlab * LogPlab;
//G4cout<<"Plab = "<<Plab<<G4endl;
G4double NumberOfTargetProtons = Zt;
G4double NumberOfTargetNucleons = At;
G4double NumberOfTargetNeutrons = NumberOfTargetNucleons - NumberOfTargetProtons;
if(NumberOfTargetNeutrons < 0.) NumberOfTargetNeutrons = 0.;
G4double Xtotal = 0., Xelastic = 0., Xinelastic =0.;
if( absPDGcode > 1000 ) //------Projectile is baryon --------
{
G4double XtotPP = 48.0 + 0. *std::pow(Plab, 0. ) +
0.522*sqrLogPlab - 4.51*LogPlab;
G4double XtotPN = 47.3 + 0. *std::pow(Plab, 0. ) +
0.513*sqrLogPlab - 4.27*LogPlab;
G4double XelPP = 11.9 + 26.9*std::pow(Plab,-1.21) +
0.169*sqrLogPlab - 1.85*LogPlab;
G4double XelPN = 11.9 + 26.9*std::pow(Plab,-1.21) +
0.169*sqrLogPlab - 1.85*LogPlab;
Xtotal = ( NumberOfTargetProtons * XtotPP +
NumberOfTargetNeutrons * XtotPN );
Xelastic = ( NumberOfTargetProtons * XelPP +
NumberOfTargetNeutrons * XelPN );
}
Xinelastic = Xtotal - Xelastic;
if(Xinelastic < 0.) Xinelastic = 0.;
return Xinelastic*= millibarn;
}
/////////////////////////////////////////////////////////////////////////////////////
//
// Returns hadron-nucleon cross-section based on Mikhail Kossov CHIPS parametrisation of
// data from G4QuasiFreeRatios class
G4double
G4GGNuclNuclCrossSection::GetHadronNucleonXscMK(G4ParticleDefinition* pParticle, G4double pTkin,
G4ParticleDefinition* nucleon )
{
G4int I = -1;
G4int PDG = pParticle->GetPDGEncoding();
G4double totalXsc = 0;
G4double elasticXsc = 0;
G4double inelasticXsc;
// G4int absPDG = std::abs(PDG);
G4double pM = pParticle->GetPDGMass();
G4double p = std::sqrt(pTkin*(pTkin+2*pM))/GeV;
G4bool F = false;
if(nucleon == theProton) F = true;
else if(nucleon == theNeutron) F = false;
else
{
G4cout << "nucleon is not proton or neutron, return xsc for proton" << G4endl;
F = true;
}
G4bool kfl = true; // Flag of K0/aK0 oscillation
G4bool kf = false;
if( PDG == 130 || PDG == 310 )
{
kf = true;
if( G4UniformRand() > .5 ) kfl = false;
}
if ( (PDG == 2212 && F) || (PDG == 2112 && !F) ) I = 0; // pp/nn
else if( (PDG == 2112 && F) || (PDG == 2212 && !F) ) I = 1; // np/pn
else
{
G4cout<<"MK PDG = "<<PDG
<<", while it is defined only for p,n,hyperons,anti-baryons,pi,K/antiK"<<G4endl;
G4Exception("G4QuasiFreeRatio::FetchElTot:","22",FatalException,"CHIPScrash");
}
// Each parameter set can have not more than nPoints = 128 parameters
static const G4double lmi = 3.5; // min of (lnP-lmi)^2 parabola
static const G4double pbe = .0557; // elastic (lnP-lmi)^2 parabola coefficient
static const G4double pbt = .3; // total (lnP-lmi)^2 parabola coefficient
static const G4double pmi = .1; // Below that fast LE calculation is made
static const G4double pma = 1000.; // Above that fast HE calculation is made
if( p <= 0.)
{
G4cout<<" p = "<<p<<" is zero or negative"<<G4endl;
elasticXsc = 0.;
inelasticXsc = 0.;
totalXsc = 0.;
return totalXsc;
}
if (!I) // pp/nn
{
if( p < pmi )
{
G4double p2 = p*p;
elasticXsc = 1./(.00012 + p2*.2);
totalXsc = elasticXsc;
}
else if(p>pma)
{
G4double lp = std::log(p)-lmi;
G4double lp2 = lp*lp;
elasticXsc = pbe*lp2 + 6.72;
totalXsc = pbt*lp2 + 38.2;
}
else
{
G4double p2 = p*p;
G4double LE = 1./( .00012 + p2*.2);
G4double lp = std::log(p) - lmi;
G4double lp2 = lp*lp;
G4double rp2 = 1./p2;
elasticXsc = LE + ( pbe*lp2 + 6.72+32.6/p)/( 1. + rp2/p);
totalXsc = LE + ( pbt*lp2 + 38.2+52.7*rp2)/( 1. + 2.72*rp2*rp2);
}
}
else if( I==1 ) // np/pn
{
if( p < pmi )
{
G4double p2 = p*p;
elasticXsc = 1./( .00012 + p2*( .051 + .1*p2));
totalXsc = elasticXsc;
}
else if( p > pma )
{
G4double lp = std::log(p) - lmi;
G4double lp2 = lp*lp;
elasticXsc = pbe*lp2 + 6.72;
totalXsc = pbt*lp2 + 38.2;
}
else
{
G4double p2 = p*p;
G4double LE = 1./( .00012 + p2*( .051 + .1*p2 ) );
G4double lp = std::log(p) - lmi;
G4double lp2 = lp*lp;
G4double rp2 = 1./p2;
elasticXsc = LE + (pbe*lp2 + 6.72 + 30./p)/( 1. + .49*rp2/p);
totalXsc = LE + (pbt*lp2 + 38.2)/( 1. + .54*rp2*rp2);
}
}
else
{
G4cout<<"PDG incoding = "<<I<<" is not defined (0-1)"<<G4endl;
}
if( elasticXsc > totalXsc ) elasticXsc = totalXsc;
totalXsc *= millibarn;
elasticXsc *= millibarn;
inelasticXsc = totalXsc - elasticXsc;
if (inelasticXsc < 0.) inelasticXsc = 0.;
return inelasticXsc;
}
////////////////////////////////////////////////////////////////////////////////////
//
//
G4double
G4GGNuclNuclCrossSection::GetNucleusRadius( const G4DynamicParticle* ,
const G4Element* anElement)
{
G4double At = anElement->GetN();
G4double oneThird = 1.0/3.0;
G4double cubicrAt = std::pow (At, oneThird);
G4double R; // = fRadiusConst*cubicrAt;
/*
G4double tmp = std::pow( cubicrAt-1., 3.);
tmp += At;
tmp *= 0.5;
if (At > 20.) // 20.
{
R = fRadiusConst*std::pow (tmp, oneThird);
}
else
{
R = fRadiusConst*cubicrAt;
}
*/
R = fRadiusConst*cubicrAt;
// return R; // !!!!
G4double meanA = 21.;
G4double tauA1 = 40.;
G4double tauA2 = 10.;
G4double tauA3 = 5.;
G4double a1 = 0.85;
G4double b1 = 1. - a1;
G4double b2 = 0.3;
G4double b3 = 4.;
if (At > 20.) // 20.
{
R *= ( a1 + b1*std::exp( -(At - meanA)/tauA1) );
}
else if (At > 3.5)
{
R *= ( 1.0 + b2*( 1. - std::exp( (At - meanA)/tauA2) ) );
}
else
{
R *= ( 1.0 + b3*( 1. - std::exp( (At - meanA)/tauA3) ) );
}
return R;
}
////////////////////////////////////////////////////////////////////////////////////
//
//
G4double
G4GGNuclNuclCrossSection::GetNucleusRadius(G4double At)
{
G4double R;
// R = GetNucleusRadiusGG(At);
R = GetNucleusRadiusDE(At);
return R;
}
///////////////////////////////////////////////////////////////////
G4double
G4GGNuclNuclCrossSection::GetNucleusRadiusGG(G4double At)
{
G4double oneThird = 1.0/3.0;
G4double cubicrAt = std::pow (At, oneThird);
G4double R; // = fRadiusConst*cubicrAt;
/*
G4double tmp = std::pow( cubicrAt-1., 3.);
tmp += At;
tmp *= 0.5;
if (At > 20.)
{
R = fRadiusConst*std::pow (tmp, oneThird);
}
else
{
R = fRadiusConst*cubicrAt;
}
*/
R = fRadiusConst*cubicrAt;
G4double meanA = 20.;
G4double tauA = 20.;
if ( At > 20.) // 20.
{
R *= ( 0.8 + 0.2*std::exp( -(At - meanA)/tauA) );
}
else
{
R *= ( 1.0 + 0.1*( 1. - std::exp( (At - meanA)/tauA) ) );
}
return R;
}
G4double
G4GGNuclNuclCrossSection::GetNucleusRadiusDE(G4double A)
{
// algorithm from diffuse-elastic
G4double R, r0, a11, a12, a13, a2, a3;
a11 = 1.26; // 1.08, 1.16
a12 = 1.; // 1.08, 1.16
a13 = 1.12; // 1.08, 1.16
a2 = 1.1;
a3 = 1.;
if( A < 50. )
{
if( 10 < A && A <= 15. ) r0 = a11*( 1 - std::pow(A, -2./3.) )*fermi; // 1.08*fermi;
else if( 15 < A && A <= 20 ) r0 = a12*( 1 - std::pow(A, -2./3.) )*fermi;
else if( 20 < A && A <= 30 ) r0 = a13*( 1 - std::pow(A, -2./3.) )*fermi;
else r0 = a2*fermi;
R = r0*std::pow( A, 1./3. );
}
else
{
r0 = a3*fermi;
R = r0*std::pow(A, 0.27);
}
return R;
}
////////////////////////////////////////////////////////////////////////////////////
//
//
G4double G4GGNuclNuclCrossSection::CalculateEcmValue( const G4double mp ,
const G4double mt ,
const G4double Plab )
{
G4double Elab = std::sqrt ( mp * mp + Plab * Plab );
G4double Ecm = std::sqrt ( mp * mp + mt * mt + 2 * Elab * mt );
// G4double Pcm = Plab * mt / Ecm;
// G4double KEcm = std::sqrt ( Pcm * Pcm + mp * mp ) - mp;
return Ecm ; // KEcm;
}
////////////////////////////////////////////////////////////////////////////////////
//
//
G4double G4GGNuclNuclCrossSection::CalcMandelstamS( const G4double mp ,
const G4double mt ,
const G4double Plab )
{
G4double Elab = std::sqrt ( mp * mp + Plab * Plab );
G4double sMand = mp*mp + mt*mt + 2*Elab*mt ;
return sMand;
}
//
//
///////////////////////////////////////////////////////////////////////////////////////
@@ -39,9 +39,191 @@
//
//
const G4double G4GlauberGribovCrossSection::fNeutronBarCorrectionTot[93] = {
1.0, 1.0, 1.118517e+00, 1.082002e+00, 1.116171e+00, 1.078747e+00, 1.061315e+00,
1.058205e+00, 1.082663e+00, 1.068500e+00, 1.076912e+00, 1.083475e+00, 1.079117e+00,
1.071856e+00, 1.071990e+00, 1.073774e+00, 1.079356e+00, 1.081314e+00, 1.082056e+00,
1.090772e+00, 1.096776e+00, 1.095828e+00, 1.097678e+00, 1.099157e+00, 1.103677e+00,
1.105132e+00, 1.109806e+00, 1.110816e+00, 1.117378e+00, 1.115165e+00, 1.115710e+00,
1.111855e+00, 1.110482e+00, 1.110112e+00, 1.106676e+00, 1.108706e+00, 1.105549e+00,
1.106318e+00, 1.106242e+00, 1.107672e+00, 1.107342e+00, 1.108119e+00, 1.106655e+00,
1.102588e+00, 1.096657e+00, 1.092920e+00, 1.086629e+00, 1.083592e+00, 1.076030e+00,
1.083777e+00, 1.089460e+00, 1.086545e+00, 1.079924e+00, 1.082218e+00, 1.077798e+00,
1.077062e+00, 1.072825e+00, 1.072241e+00, 1.072104e+00, 1.072490e+00, 1.069829e+00,
1.070398e+00, 1.065458e+00, 1.064968e+00, 1.060524e+00, 1.060048e+00, 1.057620e+00,
1.056428e+00, 1.055366e+00, 1.055017e+00, 1.052304e+00, 1.051767e+00, 1.049728e+00,
1.048745e+00, 1.047399e+00, 1.045876e+00, 1.042972e+00, 1.041824e+00, 1.039993e+00,
1.039021e+00, 1.036627e+00, 1.034176e+00, 1.032526e+00, 1.033633e+00, 1.036107e+00,
1.037803e+00, 1.031266e+00, 1.032991e+00, 1.033284e+00, 1.035015e+00, 1.033945e+00,
1.037075e+00, 1.034721e+00
};
const G4double G4GlauberGribovCrossSection::fNeutronBarCorrectionIn[93] = {
1.0, 1.0, 1.167421e+00, 1.156250e+00, 1.205364e+00, 1.154225e+00, 1.120391e+00,
1.124632e+00, 1.129460e+00, 1.107863e+00, 1.102152e+00, 1.104593e+00, 1.100285e+00,
1.098450e+00, 1.092677e+00, 1.101124e+00, 1.106461e+00, 1.115049e+00, 1.123903e+00,
1.126661e+00, 1.131259e+00, 1.133949e+00, 1.134185e+00, 1.133767e+00, 1.132813e+00,
1.131515e+00, 1.130338e+00, 1.134171e+00, 1.139206e+00, 1.141474e+00, 1.142189e+00,
1.140725e+00, 1.140100e+00, 1.139848e+00, 1.137674e+00, 1.138645e+00, 1.136339e+00,
1.136439e+00, 1.135946e+00, 1.136431e+00, 1.135702e+00, 1.135703e+00, 1.134113e+00,
1.131935e+00, 1.128381e+00, 1.126373e+00, 1.122453e+00, 1.120908e+00, 1.115953e+00,
1.115947e+00, 1.114426e+00, 1.111749e+00, 1.106207e+00, 1.107494e+00, 1.103622e+00,
1.102576e+00, 1.098816e+00, 1.097889e+00, 1.097306e+00, 1.097130e+00, 1.094578e+00,
1.094552e+00, 1.090222e+00, 1.089358e+00, 1.085409e+00, 1.084560e+00, 1.082182e+00,
1.080773e+00, 1.079464e+00, 1.078724e+00, 1.076121e+00, 1.075235e+00, 1.073159e+00,
1.071920e+00, 1.070395e+00, 1.069503e+00, 1.067525e+00, 1.066919e+00, 1.065779e+00,
1.065319e+00, 1.063730e+00, 1.062092e+00, 1.061085e+00, 1.059908e+00, 1.059815e+00,
1.059109e+00, 1.051920e+00, 1.051258e+00, 1.049473e+00, 1.048823e+00, 1.045984e+00,
1.046435e+00, 1.042614e+00
};
const G4double G4GlauberGribovCrossSection::fProtonBarCorrectionTot[93] = {
1.0, 1.0,
1.118515e+00, 1.082000e+00, 1.116169e+00, 1.078745e+00, 1.061313e+00, 1.058203e+00,
1.082661e+00, 1.068498e+00, 1.076910e+00, 1.083474e+00, 1.079115e+00, 1.071854e+00,
1.071988e+00, 1.073772e+00, 1.079355e+00, 1.081312e+00, 1.082054e+00, 1.090770e+00,
1.096774e+00, 1.095827e+00, 1.097677e+00, 1.099156e+00, 1.103676e+00, 1.105130e+00,
1.109805e+00, 1.110814e+00, 1.117377e+00, 1.115163e+00, 1.115708e+00, 1.111853e+00,
1.110480e+00, 1.110111e+00, 1.106674e+00, 1.108705e+00, 1.105548e+00, 1.106317e+00,
1.106241e+00, 1.107671e+00, 1.107341e+00, 1.108118e+00, 1.106654e+00, 1.102586e+00,
1.096655e+00, 1.092918e+00, 1.086628e+00, 1.083590e+00, 1.076028e+00, 1.083776e+00,
1.089458e+00, 1.086543e+00, 1.079923e+00, 1.082216e+00, 1.077797e+00, 1.077061e+00,
1.072824e+00, 1.072239e+00, 1.072103e+00, 1.072488e+00, 1.069828e+00, 1.070396e+00,
1.065456e+00, 1.064966e+00, 1.060523e+00, 1.060047e+00, 1.057618e+00, 1.056427e+00,
1.055365e+00, 1.055016e+00, 1.052303e+00, 1.051766e+00, 1.049727e+00, 1.048743e+00,
1.047397e+00, 1.045875e+00, 1.042971e+00, 1.041823e+00, 1.039992e+00, 1.039019e+00,
1.036626e+00, 1.034175e+00, 1.032525e+00, 1.033632e+00, 1.036106e+00, 1.037802e+00,
1.031265e+00, 1.032990e+00, 1.033283e+00, 1.035014e+00, 1.033944e+00, 1.037074e+00,
1.034720e+00
};
const G4double G4GlauberGribovCrossSection::fProtonBarCorrectionIn[93] = {
1.0, 1.0,
1.167419e+00, 1.156248e+00, 1.205362e+00, 1.154224e+00, 1.120390e+00, 1.124630e+00,
1.129459e+00, 1.107861e+00, 1.102151e+00, 1.104591e+00, 1.100284e+00, 1.098449e+00,
1.092675e+00, 1.101122e+00, 1.106460e+00, 1.115048e+00, 1.123902e+00, 1.126659e+00,
1.131258e+00, 1.133948e+00, 1.134183e+00, 1.133766e+00, 1.132812e+00, 1.131514e+00,
1.130337e+00, 1.134170e+00, 1.139205e+00, 1.141472e+00, 1.142188e+00, 1.140724e+00,
1.140099e+00, 1.139847e+00, 1.137672e+00, 1.138644e+00, 1.136338e+00, 1.136438e+00,
1.135945e+00, 1.136429e+00, 1.135701e+00, 1.135702e+00, 1.134112e+00, 1.131934e+00,
1.128380e+00, 1.126371e+00, 1.122452e+00, 1.120907e+00, 1.115952e+00, 1.115946e+00,
1.114425e+00, 1.111748e+00, 1.106205e+00, 1.107493e+00, 1.103621e+00, 1.102575e+00,
1.098815e+00, 1.097888e+00, 1.097305e+00, 1.097129e+00, 1.094577e+00, 1.094551e+00,
1.090221e+00, 1.089357e+00, 1.085408e+00, 1.084559e+00, 1.082181e+00, 1.080772e+00,
1.079463e+00, 1.078723e+00, 1.076120e+00, 1.075234e+00, 1.073158e+00, 1.071919e+00,
1.070394e+00, 1.069502e+00, 1.067524e+00, 1.066918e+00, 1.065778e+00, 1.065318e+00,
1.063729e+00, 1.062091e+00, 1.061084e+00, 1.059907e+00, 1.059814e+00, 1.059108e+00,
1.051919e+00, 1.051257e+00, 1.049472e+00, 1.048822e+00, 1.045983e+00, 1.046434e+00,
1.042613e+00
};
const G4double G4GlauberGribovCrossSection::fPionPlusBarCorrectionTot[93] = {
1.0, 1.0,
1.075927e+00, 1.074407e+00, 1.126098e+00, 1.100127e+00, 1.089742e+00, 1.083536e+00,
1.089988e+00, 1.103566e+00, 1.096922e+00, 1.126573e+00, 1.132734e+00, 1.136512e+00,
1.136629e+00, 1.133086e+00, 1.132428e+00, 1.129299e+00, 1.125622e+00, 1.126992e+00,
1.127840e+00, 1.162670e+00, 1.160392e+00, 1.157864e+00, 1.157227e+00, 1.154627e+00,
1.192555e+00, 1.197243e+00, 1.197911e+00, 1.200326e+00, 1.220053e+00, 1.215019e+00,
1.211703e+00, 1.209080e+00, 1.204248e+00, 1.203328e+00, 1.198671e+00, 1.196840e+00,
1.194392e+00, 1.193037e+00, 1.190408e+00, 1.188583e+00, 1.206127e+00, 1.210028e+00,
1.206434e+00, 1.204456e+00, 1.200547e+00, 1.199058e+00, 1.200174e+00, 1.200276e+00,
1.198912e+00, 1.213048e+00, 1.207160e+00, 1.208020e+00, 1.203814e+00, 1.202380e+00,
1.198306e+00, 1.197002e+00, 1.196027e+00, 1.195449e+00, 1.192563e+00, 1.192135e+00,
1.187556e+00, 1.186308e+00, 1.182124e+00, 1.180900e+00, 1.178224e+00, 1.176471e+00,
1.174811e+00, 1.173702e+00, 1.170827e+00, 1.169581e+00, 1.167205e+00, 1.165626e+00,
1.180244e+00, 1.177626e+00, 1.175121e+00, 1.173903e+00, 1.172192e+00, 1.171128e+00,
1.168997e+00, 1.166826e+00, 1.164130e+00, 1.165412e+00, 1.165504e+00, 1.165020e+00,
1.158462e+00, 1.158014e+00, 1.156519e+00, 1.156081e+00, 1.153602e+00, 1.154190e+00,
1.152974e+00
};
const G4double G4GlauberGribovCrossSection::fPionPlusBarCorrectionIn[93] = {
1.0, 1.0,
1.140246e+00, 1.097872e+00, 1.104301e+00, 1.068722e+00, 1.044495e+00, 1.062622e+00,
1.047987e+00, 1.037032e+00, 1.035686e+00, 1.042870e+00, 1.052222e+00, 1.065100e+00,
1.070480e+00, 1.078286e+00, 1.081488e+00, 1.089713e+00, 1.099105e+00, 1.098003e+00,
1.102175e+00, 1.117707e+00, 1.121734e+00, 1.125229e+00, 1.126457e+00, 1.128905e+00,
1.137312e+00, 1.126263e+00, 1.126459e+00, 1.115191e+00, 1.116986e+00, 1.117184e+00,
1.117037e+00, 1.116777e+00, 1.115858e+00, 1.115745e+00, 1.114489e+00, 1.113993e+00,
1.113226e+00, 1.112818e+00, 1.111890e+00, 1.111238e+00, 1.111209e+00, 1.111775e+00,
1.110256e+00, 1.109414e+00, 1.107647e+00, 1.106980e+00, 1.106096e+00, 1.107331e+00,
1.107849e+00, 1.106407e+00, 1.103426e+00, 1.103896e+00, 1.101756e+00, 1.101031e+00,
1.098915e+00, 1.098260e+00, 1.097768e+00, 1.097487e+00, 1.095964e+00, 1.095773e+00,
1.093348e+00, 1.092687e+00, 1.090465e+00, 1.089821e+00, 1.088394e+00, 1.087462e+00,
1.086571e+00, 1.085997e+00, 1.084451e+00, 1.083798e+00, 1.082513e+00, 1.081670e+00,
1.080735e+00, 1.075659e+00, 1.074341e+00, 1.073689e+00, 1.072787e+00, 1.072237e+00,
1.071107e+00, 1.069955e+00, 1.064856e+00, 1.065873e+00, 1.065938e+00, 1.065694e+00,
1.062192e+00, 1.061967e+00, 1.061180e+00, 1.060960e+00, 1.059646e+00, 1.059975e+00,
1.059658e+00
};
const G4double G4GlauberGribovCrossSection::fPionMinusBarCorrectionTot[93] = {
1.0, 1.0,
1.075927e+00, 1.077959e+00, 1.129145e+00, 1.102088e+00, 1.089765e+00, 1.083542e+00,
1.089995e+00, 1.104895e+00, 1.097154e+00, 1.127663e+00, 1.133063e+00, 1.137425e+00,
1.136724e+00, 1.133859e+00, 1.132498e+00, 1.130276e+00, 1.127896e+00, 1.127656e+00,
1.127905e+00, 1.164210e+00, 1.162259e+00, 1.160075e+00, 1.158978e+00, 1.156649e+00,
1.194157e+00, 1.199177e+00, 1.198983e+00, 1.202325e+00, 1.221967e+00, 1.217548e+00,
1.214389e+00, 1.211760e+00, 1.207335e+00, 1.206081e+00, 1.201766e+00, 1.199779e+00,
1.197283e+00, 1.195706e+00, 1.193071e+00, 1.191115e+00, 1.208838e+00, 1.212681e+00,
1.209235e+00, 1.207163e+00, 1.203451e+00, 1.201807e+00, 1.203283e+00, 1.203388e+00,
1.202244e+00, 1.216509e+00, 1.211066e+00, 1.211504e+00, 1.207539e+00, 1.205991e+00,
1.202143e+00, 1.200724e+00, 1.199595e+00, 1.198815e+00, 1.196025e+00, 1.195390e+00,
1.191137e+00, 1.189791e+00, 1.185888e+00, 1.184575e+00, 1.181996e+00, 1.180229e+00,
1.178545e+00, 1.177355e+00, 1.174616e+00, 1.173312e+00, 1.171016e+00, 1.169424e+00,
1.184120e+00, 1.181478e+00, 1.179085e+00, 1.177817e+00, 1.176124e+00, 1.175003e+00,
1.172947e+00, 1.170858e+00, 1.168170e+00, 1.169397e+00, 1.169304e+00, 1.168706e+00,
1.162774e+00, 1.162217e+00, 1.160740e+00, 1.160196e+00, 1.157857e+00, 1.158220e+00,
1.157267e+00
};
const G4double G4GlauberGribovCrossSection::fPionMinusBarCorrectionIn[93] = {
1.0, 1.0,
1.140246e+00, 1.100898e+00, 1.106773e+00, 1.070289e+00, 1.044514e+00, 1.062628e+00,
1.047992e+00, 1.038041e+00, 1.035862e+00, 1.043679e+00, 1.052466e+00, 1.065780e+00,
1.070551e+00, 1.078869e+00, 1.081541e+00, 1.090455e+00, 1.100847e+00, 1.098511e+00,
1.102226e+00, 1.118865e+00, 1.123143e+00, 1.126904e+00, 1.127785e+00, 1.130444e+00,
1.138502e+00, 1.127678e+00, 1.127244e+00, 1.116634e+00, 1.118347e+00, 1.118988e+00,
1.118957e+00, 1.118696e+00, 1.118074e+00, 1.117722e+00, 1.116717e+00, 1.116111e+00,
1.115311e+00, 1.114745e+00, 1.113814e+00, 1.113069e+00, 1.113141e+00, 1.113660e+00,
1.112249e+00, 1.111343e+00, 1.109718e+00, 1.108942e+00, 1.108310e+00, 1.109549e+00,
1.110227e+00, 1.108846e+00, 1.106183e+00, 1.106354e+00, 1.104388e+00, 1.103583e+00,
1.101632e+00, 1.100896e+00, 1.100296e+00, 1.099873e+00, 1.098420e+00, 1.098082e+00,
1.095892e+00, 1.095162e+00, 1.093144e+00, 1.092438e+00, 1.091083e+00, 1.090142e+00,
1.089236e+00, 1.088604e+00, 1.087159e+00, 1.086465e+00, 1.085239e+00, 1.084388e+00,
1.083473e+00, 1.078373e+00, 1.077136e+00, 1.076450e+00, 1.075561e+00, 1.074973e+00,
1.073898e+00, 1.072806e+00, 1.067706e+00, 1.068684e+00, 1.068618e+00, 1.068294e+00,
1.065241e+00, 1.064939e+00, 1.064166e+00, 1.063872e+00, 1.062659e+00, 1.062828e+00,
1.062699e+00
};
////////////////////////////////////////////////////////////////////////////////
//
//
G4GlauberGribovCrossSection::G4GlauberGribovCrossSection()
: fUpperLimit( 10000 * GeV ),
: fUpperLimit( 100000 * GeV ),
fLowerLimit( 3 * GeV ),
fRadiusConst( 1.08*fermi ) // 1.1, 1.3 ?
{
@@ -120,7 +302,7 @@ G4GlauberGribovCrossSection::IsZAApplicable(const G4DynamicParticle* aDP,
theParticle == theKMinus ||
theParticle == theSMinus) ) ||
( kineticEnergy >= 0.1*fLowerLimit &&
( kineticEnergy >= fLowerLimit &&
Z > 1.5 && // >= He
( theParticle == theProton ||
theParticle == theNeutron ||
@@ -184,12 +366,16 @@ GetIsoZACrossSection(const G4DynamicParticle* aParticle, G4double Z, G4double A,
xsection = nucleusSquare*std::log( 1. + ratio );
xsection *= GetParticleBarCorTot(theParticle, Z);
fTotalXsc = xsection;
fInelasticXsc = nucleusSquare*std::log( 1. + cofInelastic*ratio )/cofInelastic;
fInelasticXsc *= GetParticleBarCorIn(theParticle, Z);
fElasticXsc = fTotalXsc - fInelasticXsc;
@@ -1137,11 +1323,11 @@ G4GlauberGribovCrossSection::GetHadronNucleonXscMK(const G4DynamicParticle* aPar
kf = true;
if( G4UniformRand() > .5 ) kfl = false;
}
if ( PDG == 2212 && F || PDG == 2112 && !F ) I = 0; // pp/nn
else if( PDG == 2112 && F || PDG == 2212 && !F ) I = 1; // np/pn
if ( (PDG == 2212 && F) || (PDG == 2112 && !F) ) I = 0; // pp/nn
else if( (PDG == 2112 && F) || (PDG == 2212 && !F) ) I = 1; // np/pn
else if( PDG == -211 && F || PDG == 211 && !F ) I = 2; // pimp/pipn
else if( PDG == 211 && F || PDG ==-211 && !F ) I = 3; // pipp/pimn
else if( (PDG == -211 && F) || (PDG == 211 && !F) ) I = 2; // pimp/pipn
else if( (PDG == 211 && F) || (PDG ==-211 && !F) ) I = 3; // pipp/pimn
else if( PDG == -321 || PDG == -311 || ( kf && !kfl ) ) I = 4; // KmN/K0N
else if( PDG == 321 || PDG == 311 || ( kf && kfl ) ) I = 5; // KpN/aK0N
@@ -25,7 +25,7 @@
//
//
// $Id: G4HadronCaptureDataSet.cc,v 1.8 2006/06/29 19:57:35 gunter Exp $
// GEANT4 tag $Name: geant4-09-01 $
// GEANT4 tag $Name: geant4-09-02 $
//
//
// G4 Physics class: HadronCaptureDataSet for cross sections
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// GEANT4 tag $Name: geant4-09-01 $
// GEANT4 tag $Name: geant4-09-02 $
//
//
// G4 Hadron Physics class G4HadronCrossSections
@@ -25,7 +25,7 @@
//
//
// $Id: G4HadronElasticDataSet.cc,v 1.8 2006/06/29 19:57:39 gunter Exp $
// GEANT4 tag $Name: geant4-09-01 $
// GEANT4 tag $Name: geant4-09-02 $
//
//
// G4 Physics class: HadronElasticDataSet for cross sections
@@ -25,7 +25,7 @@
//
//
// $Id: G4HadronFissionDataSet.cc,v 1.8 2006/06/29 19:57:41 gunter Exp $
// GEANT4 tag $Name: geant4-09-01 $
// GEANT4 tag $Name: geant4-09-02 $
//
//
// G4 Physics class: HadronFissionDataSet for cross sections
@@ -25,7 +25,7 @@
//
//
// $Id: G4HadronInelasticDataSet.cc,v 1.8 2006/06/29 19:57:43 gunter Exp $
// GEANT4 tag $Name: geant4-09-01 $
// GEANT4 tag $Name: geant4-09-02 $
//
//
// G4 Physics class: HadronInelasticDataSet for cross sections
@@ -915,11 +915,11 @@ G4HadronNucleonXsc::GetHadronNucleonXscMK(const G4DynamicParticle* aParticle,
kf = true;
if( G4UniformRand() > .5 ) kfl = false;
}
if ( PDG == 2212 && F || PDG == 2112 && !F ) I = 0; // pp/nn
else if( PDG == 2112 && F || PDG == 2212 && !F ) I = 1; // np/pn
if ( (PDG == 2212 && F) || (PDG == 2112 && !F) ) I = 0; // pp/nn
else if( (PDG == 2112 && F) || (PDG == 2212 && !F) ) I = 1; // np/pn
else if( PDG == -211 && F || PDG == 211 && !F ) I = 2; // pimp/pipn
else if( PDG == 211 && F || PDG ==-211 && !F ) I = 3; // pipp/pimn
else if( (PDG == -211 && F) || (PDG == 211 && !F) ) I = 2; // pimp/pipn
else if( (PDG == 211 && F) || (PDG ==-211 && !F) ) I = 3; // pipp/pimn
else if( PDG == -321 || PDG == -311 || ( kf && !kfl ) ) I = 4; // KmN/K0N
else if( PDG == 321 || PDG == 311 || ( kf && kfl ) ) I = 5; // KpN/aK0N
@@ -73,8 +73,10 @@ GetCrossSection(G4double anEnergy, G4double atomicNumber, G4double nOfProtons)
const G4double p5=1.64-1.8/atomicNumber-0.0005*atomicNumber;
const G4double p6=1.+200./atomicNumber+0.02*atomicNumber;
const G4double p7=(atomicNumber-70.)*(atomicNumber-200.)/11000.;
G4double part1 = pi*(p1*p1)*std::log(nOfNeutrons);
G4double logN = 1.0;
if (nOfNeutrons > 1.5) logN = std::log(nOfNeutrons);
G4double part1 = pi*(p1*p1)*logN;
G4double part2 = 1.+ std::pow(atomicNumber, 1./3.)
- p2*(1.-1./std::pow(atomicNumber, 1./3.));
@@ -25,7 +25,7 @@
//
//
// The lust update: M.V. Kossov, CERN/ITEP(Moscow) 17-June-02
// GEANT4 tag $Name: geant4-09-01 $
// GEANT4 tag $Name: geant4-09-02 $
//
//
// G4 Physics class: G4PhotoNuclearCrossSection for gamma+A cross sections
@@ -266,6 +266,64 @@ G4PhotoNuclearCrossSection::GetIsoZACrossSection(const G4DynamicParticle* aPart,
return sigma*millibarn;
}
// Gives the threshold energy for different nuclei (min of p- and n-threshold)
G4double G4PhotoNuclearCrossSection::ThresholdEnergy(G4int Z, G4int N)
{
// CHIPS - Direct GEANT
//static const G4double mNeut = G4QPDGCode(2112).GetMass();
//static const G4double mProt = G4QPDGCode(2212).GetMass();
static const G4double mNeut = G4NucleiProperties::GetNuclearMass(1,0);
static const G4double mProt = G4NucleiProperties::GetNuclearMass(1,1);
// ---------
static const G4double infEn = 9.e27;
G4int A=Z+N;
if(A<1) return infEn;
else if(A==1) return 134.9766; // Pi0 threshold for the nucleon
// CHIPS - Direct GEANT
//G4double mT= G4QPDGCode(111).GetNuclMass(Z,N,0);
G4double mT= 0.;
if(G4NucleiProperties::IsInStableTable(A,Z))
mT=G4NucleiProperties::GetNuclearMass(A,Z);
else
{
//G4cerr<<"G4PhotoNucCrossSect.hh::ThreshEn:Z="<<Z<<",A="<<A
// <<" element isn't in G4NucPr"<<G4endl;
// If it is not in the Table of Stable Nuclei, then the Threshold=inf
return infEn;
}
// ---------
G4double mP= infEn;
//if(Z) mP= G4QPDGCode(111).GetNuclMass(Z-1,N,0);
if(Z && G4NucleiProperties::IsInStableTable(A-1,Z-1))
{
mP = G4NucleiProperties::GetNuclearMass(A-1,Z-1);
}
/*
else
{
G4cerr << "G4PhotoNuclearCrossSection::ThrEn:Z=" << Z-1 << ",A="
<< A-1 << " element isn't in G4NucP" << G4endl;
}
*/
G4double mN= infEn;
//if(N) mN= G4QPDGCode(111).GetNuclMass(Z,N-1,0);
if(N&&G4NucleiProperties::IsInStableTable(A-1,Z))
mN=G4NucleiProperties::GetNuclearMass(A-1,Z);
/*
else
{
G4cerr<<"G4PhotoNuclearCrossSection::ThreshEn:Z="<<Z<<",A="<<A-1
<<" element isn't in G4NuP"<<G4endl;
}
*/
G4double dP= mP+mProt-mT;
G4double dN= mN+mNeut-mT;
if(dP<dN)dN=dP;
return dN;
}
//
// Linear fit for XN[N],YN[N] tabulated function
// to X point // @@ !!! Not used !!!
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// GEANT4 tag $Name: geant4-09-01 $
// GEANT4 tag $Name: geant4-09-02 $
//
// --------------------------------------------------------------------
// by J.P Wellisch, Sun Sep 15 2002.
@@ -26,7 +26,7 @@
#include "G4PiNuclearCrossSection.hh"
#include "G4HadronicException.hh"
#include "G4HadTmpUtil.hh"
#include "G4ping.hh"
// #include "G4ping.hh"
// by J.P Wellisch, Sun Sep 15 2002.
// corrected G.Folger 17-8-2006: inel. Ca pim was missing two number,
@@ -349,7 +349,7 @@ GetIsoZACrossSection(const G4DynamicParticle* particle, G4double ZZ,
G4double /*AA*/, G4double /*temperature*/)
{
// precondition
G4ping debug("debug_PiNuclearCrossSection");
// G4ping debug("debug_PiNuclearCrossSection");
using namespace std;
G4bool ok = false;
if(particle->GetDefinition() == G4PionMinus::PionMinus()) ok=true;
@@ -367,13 +367,13 @@ GetIsoZACrossSection(const G4DynamicParticle* particle, G4double ZZ,
G4double result = 0;
G4int Z=G4lrint(ZZ);
debug.push_back(Z);
// debug.push_back(Z);
size_t it = 0;
while(it<theZ.size() && Z>theZ[it]) it++;
debug.push_back(theZ[it]);
debug.push_back(kineticEnergy);
// debug.push_back(theZ[it]);
// debug.push_back(kineticEnergy);
if(Z > theZ[it])
{
@@ -389,9 +389,9 @@ GetIsoZACrossSection(const G4DynamicParticle* particle, G4double ZZ,
result = thePimData[it]->ReactionXSection(kineticEnergy);
fTotalXsc = thePimData[it]->TotalXSection(kineticEnergy);
debug.push_back("D1 ");
debug.push_back(result);
debug.push_back(fTotalXsc);
// debug.push_back("D1 ");
// debug.push_back(result);
// debug.push_back(fTotalXsc);
}
else
{
@@ -405,15 +405,15 @@ GetIsoZACrossSection(const G4DynamicParticle* particle, G4double ZZ,
result = Interpolate(Z1, Z2, Z, x1, x2);
fTotalXsc = Interpolate(Z1, Z2, Z, xt1, xt2);
debug.push_back("D2 ");
debug.push_back(x1);
debug.push_back(x2);
debug.push_back(xt1);
debug.push_back(xt2);
debug.push_back(Z1);
debug.push_back(Z2);
debug.push_back(result);
debug.push_back(fTotalXsc);
// debug.push_back("D2 ");
// debug.push_back(x1);
// debug.push_back(x2);
// debug.push_back(xt1);
// debug.push_back(xt2);
// debug.push_back(Z1);
// debug.push_back(Z2);
// debug.push_back(result);
// debug.push_back(fTotalXsc);
}
}
else
@@ -429,9 +429,9 @@ GetIsoZACrossSection(const G4DynamicParticle* particle, G4double ZZ,
result = theData->operator[](it)->ReactionXSection(kineticEnergy);
fTotalXsc = theData->operator[](it)->TotalXSection(kineticEnergy);
debug.push_back("D3 ");
debug.push_back(result);
debug.push_back(fTotalXsc);
// debug.push_back("D3 ");
// debug.push_back(result);
// debug.push_back(fTotalXsc);
}
else
{
@@ -455,18 +455,18 @@ GetIsoZACrossSection(const G4DynamicParticle* particle, G4double ZZ,
result = Interpolate(Z1, Z2, Z, x1, x2);
fTotalXsc = Interpolate(Z1, Z2, Z, xt1, xt2);
debug.push_back("D4 ");
debug.push_back(x1);
debug.push_back(xt1);
debug.push_back(x2);
debug.push_back(xt2);
debug.push_back(Z1);
debug.push_back(Z2);
debug.push_back(result);
debug.push_back(fTotalXsc);
// debug.push_back("D4 ");
// debug.push_back(x1);
// debug.push_back(xt1);
// debug.push_back(x2);
// debug.push_back(xt2);
// debug.push_back(Z1);
// debug.push_back(Z2);
// debug.push_back(result);
// debug.push_back(fTotalXsc);
}
}
debug.dump();
// debug.dump();
fElasticXsc = fTotalXsc - result;
if( fElasticXsc < 0.) fElasticXsc = 0.;
@@ -100,7 +100,7 @@ G4TripathiLightCrossSection::~G4TripathiLightCrossSection ()
G4bool G4TripathiLightCrossSection::IsApplicable
(const G4DynamicParticle* theProjectile, const G4Element* theTarget)
{
return IsZAApplicable(theProjectile, theTarget->GetZ(), theTarget->GetA());
return IsZAApplicable(theProjectile, theTarget->GetZ(), theTarget->GetN());
}
@@ -49,20 +49,15 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4UElasticCrossSection::G4UElasticCrossSection(const G4ParticleDefinition* p)
G4UElasticCrossSection::G4UElasticCrossSection(const G4ParticleDefinition*)
{
verboseLevel = 0;
hasGlauber = false;
thEnergy = 100.*GeV;
thEnergy = 90.*GeV;
fGlauber = new G4GlauberGribovCrossSection();
fGheisha = G4HadronCrossSections::Instance();
fNucleon = 0;
fUPi = 0;
if(p == G4Proton::Proton() || p == G4Neutron::Neutron())
fNucleon = new G4NucleonNuclearCrossSection();
else if(p == G4PionPlus::PionPlus() || p == G4PionMinus::PionMinus())
fUPi = new G4UPiNuclearCrossSection();
verboseLevel = 0;
Initialise(p);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -116,7 +111,7 @@ G4double G4UElasticCrossSection::GetIsoZACrossSection(const G4DynamicParticle* d
{
G4double cross = 0.0;
G4double ekin = dp->GetKineticEnergy();
G4int iz = G4int(Z + 0.5);
G4int iz = G4int(Z);
if(iz > 92) iz = 92;
// proton and neutron
@@ -159,8 +154,14 @@ G4double G4UElasticCrossSection::GetIsoZACrossSection(const G4DynamicParticle* d
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4UElasticCrossSection::BuildPhysicsTable(const G4ParticleDefinition&)
void G4UElasticCrossSection::BuildPhysicsTable(const G4ParticleDefinition& p)
{
if(&p == G4Proton::Proton() || &p == G4Neutron::Neutron()) {
fNucleon = new G4NucleonNuclearCrossSection();
} else if(&p == G4PionPlus::PionPlus() || &p == G4PionMinus::PionMinus()) {
fUPi = new G4UPiNuclearCrossSection();
}
Initialise(&p);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -49,20 +49,15 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4UInelasticCrossSection::G4UInelasticCrossSection(const G4ParticleDefinition* p)
G4UInelasticCrossSection::G4UInelasticCrossSection(const G4ParticleDefinition*)
{
verboseLevel = 0;
hasGlauber = false;
thEnergy = 100.*GeV;
thEnergy = 90.*GeV;
fGlauber = new G4GlauberGribovCrossSection();
fGheisha = G4HadronCrossSections::Instance();
fNucleon = 0;
fUPi = 0;
if(p == G4Proton::Proton() || p == G4Neutron::Neutron())
fNucleon = new G4NucleonNuclearCrossSection();
else if(p == G4PionPlus::PionPlus() || p == G4PionMinus::PionMinus())
fUPi = new G4UPiNuclearCrossSection();
verboseLevel = 0;
Initialise(p);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -116,7 +111,7 @@ G4double G4UInelasticCrossSection::GetIsoZACrossSection(const G4DynamicParticle*
{
G4double cross = 0.0;
G4double ekin = dp->GetKineticEnergy();
G4int iz = G4int(Z + 0.5);
G4int iz = G4int(Z);
if(iz > 92) iz = 92;
// proton and neutron
@@ -159,8 +154,14 @@ G4double G4UInelasticCrossSection::GetIsoZACrossSection(const G4DynamicParticle*
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4UInelasticCrossSection::BuildPhysicsTable(const G4ParticleDefinition&)
void G4UInelasticCrossSection::BuildPhysicsTable(const G4ParticleDefinition& p)
{
if(&p == G4Proton::Proton() || &p == G4Neutron::Neutron()) {
fNucleon = new G4NucleonNuclearCrossSection();
} else if(&p == G4PionPlus::PionPlus() || &p == G4PionMinus::PionMinus()) {
fUPi = new G4UPiNuclearCrossSection();
}
Initialise(&p);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -97,42 +97,31 @@ G4double G4UPiNuclearCrossSection::GetInelasticCrossSection(
G4double G4UPiNuclearCrossSection::Interpolate(
G4double Z, G4double A, G4double ekin, G4PhysicsTable* table)
{
G4double res = 0.0;
G4bool b;
G4int idx;
G4int iz = G4int(Z + 0.5);
for(idx=0; idx<NZ-1; idx++) {if(theZ[idx] >= iz) break;}
if(iz > 92) iz = 92;
for(idx=0; idx<NZ; idx++) {if(theZ[idx] >= iz) break;}
if(idx >= NZ) idx = NZ - 1;
G4int iz2 = theZ[idx];
G4double x = (((*table)[idx])->GetValue(ekin, b));
G4double x2 = (((*table)[idx])->GetValue(ekin, b))*APower[iz]/APower[iz2];
// one of elements in the table
if(iz >= theZ[idx]) {
G4double A1 = theA[idx];
x *= std::pow(A/A1,aPower);
// use only one Z
if(iz >= theZ[idx] || idx == 0) {
res = x2;
// Interpolation between Z
} else {
G4double x2 = x;
G4double x1 = x;
if(idx == 0) {
idx++;
x2 = (((*table)[idx])->GetValue(ekin, b));
} else {
x1 = (((*table)[idx-1])->GetValue(ekin, b));
}
G4double A1 = theA[idx-1];
G4double A2 = theA[idx];
G4double w1 = A - A1;
G4double w2 = A2 - A;
G4double y1 = x1*std::pow(A/A1,aPower);
if(w1 <= 0.0) x = y1;
else {
G4double y2 = x2*std::pow(A/A2,aPower);
if(w2 <= 0.0) x = y2;
else x = (w2*y1 + w1*y2)/(w1 + w2);
}
G4int iz1 = theZ[idx-1];
G4double x1 = (((*table)[idx-1])->GetValue(ekin, b))*APower[iz]/APower[iz1];
G4double w1 = A - theA[idx-1];
G4double w2 = theA[idx] - A;
res = (w1*x1 + w2*x2)/(w1 + w2);
}
return x;
return res;
}
void G4UPiNuclearCrossSection::AddDataSet(const G4String& p,
@@ -142,7 +131,9 @@ void G4UPiNuclearCrossSection::AddDataSet(const G4String& p,
G4int n)
{
G4LPhysicsFreeVector* pvin = new G4LPhysicsFreeVector(n,e[0]*GeV,e[n-1]*GeV);
//pvin->SetSpline(true);
G4LPhysicsFreeVector* pvel = new G4LPhysicsFreeVector(n,e[0]*GeV,e[n-1]*GeV);
//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));
@@ -187,10 +178,14 @@ void G4UPiNuclearCrossSection::Initialise()
NZ = n;
G4NistManager* nist = G4NistManager::Instance();
for(G4int i=0; i<n; i++) {
G4int i;
for(i=0; i<n; i++) {
theZ.push_back(iz[i]);
theA.push_back(nist->GetAtomicMassAmu(iz[i]));
}
for(i=1; i<92; i++) {
APower[i] = std::pow(nist->GetAtomicMassAmu(i),aPower);
}
piPlusElastic = new G4PhysicsTable();
piPlusInelastic = new G4PhysicsTable();