Import Geant4 10.5.0.beta source tree

This commit is contained in:
Gabriele Cosmo
2018-06-29 10:58:11 +02:00
parent fe81a77428
commit 6aa23be517
1581 changed files with 124288 additions and 83758 deletions
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4BGGNucleonElasticXS.cc 93682 2015-10-28 10:09:49Z gcosmo $
// $Id: G4BGGNucleonElasticXS.cc 110543 2018-05-29 13:38:54Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -80,6 +80,7 @@ G4BGGNucleonElasticXS::G4BGGNucleonElasticXS(const G4ParticleDefinition* p)
theProton= G4Proton::Proton();
isProton = false;
isInitialized = false;
SetForAllAtomsAndEnergies(true);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4BGGNucleonInelasticXS.cc 93682 2015-10-28 10:09:49Z gcosmo $
// $Id: G4BGGNucleonInelasticXS.cc 110543 2018-05-29 13:38:54Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -85,6 +85,7 @@ G4BGGNucleonInelasticXS::G4BGGNucleonInelasticXS(const G4ParticleDefinition* p)
theProton= G4Proton::Proton();
isProton = false;
isInitialized = false;
SetForAllAtomsAndEnergies(true);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4BGGPionElasticXS.cc 93682 2015-10-28 10:09:49Z gcosmo $
// $Id: G4BGGPionElasticXS.cc 110543 2018-05-29 13:38:54Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -76,6 +76,7 @@ G4BGGPionElasticXS::G4BGGPionElasticXS(const G4ParticleDefinition*)
theProton= G4Proton::Proton();
isPiplus = false;
isInitialized = false;
SetForAllAtomsAndEnergies(true);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4BGGPionInelasticXS.cc 93682 2015-10-28 10:09:49Z gcosmo $
// $Id: G4BGGPionInelasticXS.cc 110543 2018-05-29 13:38:54Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -79,8 +79,10 @@ G4BGGPionInelasticXS::G4BGGPionInelasticXS(const G4ParticleDefinition* p)
theProton= G4Proton::Proton();
isPiplus = false;
isInitialized = false;
SetForAllAtomsAndEnergies(true);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4BGGPionInelasticXS::~G4BGGPionInelasticXS()
{
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4ChipsAntiBaryonElasticXS.cc 93260 2015-10-14 08:37:04Z gcosmo $
// $Id: G4ChipsAntiBaryonElasticXS.cc 109482 2018-04-24 14:47:28Z gcosmo $
//
//
// G4 Physics class: G4ChipsAntiBaryonElasticXS for pA elastic cross sections
@@ -783,7 +783,10 @@ G4double G4ChipsAntiBaryonElasticXS::GetTabValues(G4double lp, G4int PDG, G4int
G4int tgN)
{
if(PDG<-3334 || PDG>-1111) G4cout<<"*Warning*G4QAntiBaryElCS::GetTabV:PDG="<<PDG<<G4endl;
if(tgZ<0 || tgZ>92)
//AR-24Apr2018 Switch to allow transuranic elements
const G4bool isHeavyElementAllowed = true;
if(tgZ<0 || ( !isHeavyElementAllowed && tgZ>92))
{
G4cout<<"*Warning*G4QAntiBaryonElCS::GetTabValue:(1-92) NoIsotopesFor Z="<<tgZ<<G4endl;
return 0.;
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4ChipsHyperonElasticXS.cc 93260 2015-10-14 08:37:04Z gcosmo $
// $Id: G4ChipsHyperonElasticXS.cc 109482 2018-04-24 14:47:28Z gcosmo $
//
//
// G4 Physics class: G4ChipsHyperonElasticXS for pA elastic cross sections
@@ -751,7 +751,11 @@ G4double G4ChipsHyperonElasticXS::GetTabValues(G4double lp, G4int PDG, G4int tgZ
{
//AR-04Jun2014 if(PDG==3222 || PDG<3000 || PDG>3334) G4cout<<"*Warning*G4QHypElCS::GTV:P="<<PDG<<G4endl;
if(PDG<3000 || PDG>3334) G4cout<<"*Warning*G4QHypElCS::GTV:P="<<PDG<<G4endl;
if(tgZ<0 || tgZ>92)
//AR-24Apr2018 Switch to allow transuranic elements
const G4bool isHeavyElementAllowed = true;
if(tgZ<0 || ( !isHeavyElementAllowed && tgZ>92))
{
G4cout<<"*Warning*G4QHyperonElastCS::GetTabValue:(1-92) NoIsotopesFor Z="<<tgZ<<G4endl;
return 0.;
@@ -306,6 +306,10 @@ G4double G4ChipsHyperonInelasticXS::CrossSectionFormula(G4int tZ, G4int tN,
G4double P, G4double lP)
{
G4double sigma=0.;
//AR-24Apr2018 Switch to allow transuranic elements
const G4bool isHeavyElementAllowed = true;
if(tZ==1 && !tN) // Hyperon-P interaction from G4QuasiElastRatios
{
G4double ld=lP-3.5;
@@ -317,7 +321,7 @@ G4double G4ChipsHyperonInelasticXS::CrossSectionFormula(G4int tZ, G4int tN,
G4double To=(.3*ld2+38.2+900./sp)/(1.+27./sp+3./p4);
sigma=To-El;
}
else if(tZ<97 && tN<152) // General solution
else if((tZ<97 && tN<152) || isHeavyElementAllowed) // General solution
{
G4double d=lP-4.2;
G4double p2=P*P;
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4ChipsKaonMinusElasticXS.cc 93203 2015-10-12 07:42:34Z gcosmo $
// $Id: G4ChipsKaonMinusElasticXS.cc 109482 2018-04-24 14:47:28Z gcosmo $
//
//
// G4 Physics class: G4ChipsKaonMinusElasticXS for pA elastic cross sections
@@ -748,7 +748,10 @@ G4double G4ChipsKaonMinusElasticXS::GetTabValues(G4double lp, G4int PDG, G4int t
G4int tgN)
{
if(PDG!=-321)G4cout<<"*Warning*G4ChipsKaonMinusElasticXS::GetTV:PDG="<<PDG<<G4endl;
if(tgZ<0 || tgZ>92)
//AR-24Apr2018 Switch to allow transuranic elements
const G4bool isHeavyElementAllowed = true;
if(tgZ<0 || ( !isHeavyElementAllowed && tgZ>92))
{
G4cout<<"*Warning*G4QKaonMinusElasticCS::GetTabV:(1-92)NoIsotopes for Z="<<tgZ<<G4endl;
return 0.;
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4ChipsKaonPlusElasticXS.cc 93260 2015-10-14 08:37:04Z gcosmo $
// $Id: G4ChipsKaonPlusElasticXS.cc 109482 2018-04-24 14:47:28Z gcosmo $
//
//
// G4 Physics class: G4ChipsKaonPlusElasticXS for pA elastic cross sections
@@ -746,7 +746,10 @@ G4double G4ChipsKaonPlusElasticXS::GetTabValues(G4double lp, G4int PDG, G4int tg
G4int tgN)
{
if(PDG!=321)G4cout<<"*Warning*G4ChipsKaonPlusElasticXS::GetTaV:PDG="<<PDG<<G4endl;
if(tgZ<0 || tgZ>92)
//AR-24Apr2018 Switch to allow transuranic elements
const G4bool isHeavyElementAllowed = true;
if(tgZ<0 || ( !isHeavyElementAllowed && tgZ>92))
{
G4cout<<"*Warning*G4QKaonPlusElasticCS::GetTabV:(1-92)NoIsotopes for Z="<<tgZ<<G4endl;
return 0.;
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4ChipsNeutronElasticXS.cc 93080 2015-10-02 14:45:31Z gcosmo $
// $Id: G4ChipsNeutronElasticXS.cc 109482 2018-04-24 14:47:28Z gcosmo $
//
//
// G4 Physics class: G4ChipsNeutronElasticXS for nA elastic cross sections
@@ -1669,8 +1669,13 @@ G4double G4ChipsNeutronElasticXS::GetPTables(G4double LP, G4double ILP, G4int PD
}
if(nfound)
{
G4cout<<"-Warning-G4ChipsNeutronElasticXS::CalcCS: Z="<<tgZ<<", N="<<tgN
<<" isotope is not implemented in CHIPS"<<G4endl; // Put default values:
//AR-24Apr2018 Switch to allow transuranic elements (in this case to avoid a harmless warning)
const G4bool isHeavyElementAllowed = true;
if ( ! isHeavyElementAllowed ) {
G4cout<<"-Warning-G4ChipsNeutronElasticXS::CalcCS: Z="<<tgZ<<", N="<<tgN
<<" isotope is not implemented in CHIPS"<<G4endl;
}
// Put default values:
lastPAR[ 4]=5.2E-7; // p4
lastPAR[ 7]=22.; // p7
lastPAR[ 8]=.00026; // p8
@@ -1994,7 +1999,10 @@ G4double G4ChipsNeutronElasticXS::GetTabValues(G4double lp, G4int PDG, G4int tgZ
G4int tgN)
{
if(PDG!=2112) G4cout<<"*Warning*G4ChipsNeutronElasticXS::GetTaV:PDG="<<PDG<<G4endl;
if(tgZ<0 || tgZ>92)
//AR-24Apr2018 Switch to allow transuranic elements
const G4bool isHeavyElementAllowed = true;
if(tgZ<0 || ( !isHeavyElementAllowed && tgZ>92))
{
G4cout<<"*Warning*G4QNElasticCrS::GetTabValue: (1-92) No isotopes for Z="<<tgZ<<G4endl;
return 0.;
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4ChipsPionMinusElasticXS.cc 93260 2015-10-14 08:37:04Z gcosmo $
// $Id: G4ChipsPionMinusElasticXS.cc 109482 2018-04-24 14:47:28Z gcosmo $
//
//
// G4 Physics class: G4ChipsPionMinusElasticXS for pA elastic cross sections
@@ -742,7 +742,10 @@ G4double G4ChipsPionMinusElasticXS::GetTabValues(G4double lp, G4int PDG, G4int t
G4int tgN)
{
if(PDG!=-211)G4cout<<"*Warn*G4ChipsPionMinusElasticXS::GetTabV: PDG="<<PDG<<G4endl;
if(tgZ<0 || tgZ>92)
//AR-24Apr2018 Switch to allow transuranic elements
const G4bool isHeavyElementAllowed = true;
if(tgZ<0 || ( !isHeavyElementAllowed && tgZ>92))
{
G4cout<<"*Warning*G4QPionPlusElCS::GetTabValue:(1-92) No isotopes for Z="<<tgZ<<G4endl;
return 0.;
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4ChipsPionPlusElasticXS.cc 93260 2015-10-14 08:37:04Z gcosmo $
// $Id: G4ChipsPionPlusElasticXS.cc 109482 2018-04-24 14:47:28Z gcosmo $
//
//
// G4 Physics class: G4ChipsPionPlusElasticXS for pA elastic cross sections
@@ -740,7 +740,10 @@ G4double G4ChipsPionPlusElasticXS::GetTabValues(G4double lp, G4int PDG, G4int tg
G4int tgN)
{
if(PDG!= 211)G4cout<<"Warning*G4ChipsPionPlusElasticXS::GetTabV:PDG="<<PDG<<G4endl;
if(tgZ<0 || tgZ>92)
//AR-24Apr2018 Switch to allow transuranic elements
const G4bool isHeavyElementAllowed = true;
if(tgZ<0 || ( !isHeavyElementAllowed && tgZ>92))
{
G4cout<<"*Warning*G4QPionPlusElCS::GetTabValue:(1-92) No isotopes for Z="<<tgZ<<G4endl;
return 0.;
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4ChipsProtonElasticXS.cc 93080 2015-10-02 14:45:31Z gcosmo $
// $Id: G4ChipsProtonElasticXS.cc 109482 2018-04-24 14:47:28Z gcosmo $
//
//
// G4 Physics class: G4ChipsProtonElasticXS for pA elastic cross sections
@@ -760,7 +760,10 @@ G4double G4ChipsProtonElasticXS::GetTabValues(G4double lp, G4int PDG, G4int tgZ,
G4int tgN)
{
if(PDG!=2212) G4cout<<"*Warning*G4ChipsProtonElasticXS::GetTabV:PDG="<<PDG<<G4endl;
if(tgZ<0 || tgZ>92)
//AR-24Apr2018 Switch to allow transuranic elements
const G4bool isHeavyElementAllowed = true;
if(tgZ<0 || ( !isHeavyElementAllowed && tgZ>92))
{
G4cout<<"*Warning*G4QProtonElCS::GetTabValue: (1-92) No isotopes for Z="<<tgZ<<G4endl;
return 0.;
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4CrossSectionDataStore.cc 107119 2017-11-02 15:12:35Z gcosmo $
// $Id: G4CrossSectionDataStore.cc 110654 2018-06-05 11:51:50Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -65,9 +65,9 @@ G4CrossSectionDataStore::G4CrossSectionDataStore() :
counters(),fastPathCache()
{
nist = G4NistManager::Instance();
currentMaterial = elmMaterial = 0;
currentElement = 0; //ALB 14-Aug-2012 Coverity fix.
matParticle = elmParticle = 0;
currentMaterial = elmMaterial = nullptr;
currentElement = nullptr; //ALB 14-Aug-2012 Coverity fix.
matParticle = elmParticle = nullptr;
matKinEnergy = elmKinEnergy = matCrossSection = elmCrossSection = 0.0;
}
@@ -123,11 +123,10 @@ G4CrossSectionDataStore::GetCrossSection(const G4DynamicParticle* part,
// cache is created during the run initialization via calls to this method.
//
//fastPathFlags contains control flags for the fast-path algorithm:
// .prevCalcUsedFastPath == true => Previous call to GetCrossSection used the fast-path
// it is used in the decision to assess if xsecelem is
// correctly set-up
// .useFastPathIfAvailable == true => User requested the use of fast-path algorithm
// .initializationPhase == true => If true we are in Geant4 Init phase before the event-loop
// .prevCalcUsedFastPath == true => Previous call to GetCrossSection used the fast-path
// it is used in the decision to assess if xsecelem is correctly set-up
// .useFastPathIfAvailable == true => User requested the use of fast-path algorithm
// .initializationPhase == true => If true we are in Geant4 Init phase before the event-loop
//Check user-request, does he want fast-path? if not
// OR
@@ -268,6 +267,34 @@ G4CrossSectionDataStore::DumpFastPath(const G4ParticleDefinition* pd, const G4Ma
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4double
G4CrossSectionDataStore::ComputeCrossSection(const G4DynamicParticle* part,
const G4Material* mat)
{
if(mat == currentMaterial && part->GetDefinition() == matParticle
&& part->GetKineticEnergy() == matKinEnergy) {
return matCrossSection;
}
currentMaterial = mat;
matParticle = part->GetDefinition();
matKinEnergy = part->GetKineticEnergy();
matCrossSection = 0.0;
size_t nElements = mat->GetNumberOfElements();
const G4double* nAtomsPerVolume = mat->GetVecNbOfAtomsPerVolume();
if(xsecelm.size() < nElements) { xsecelm.resize(nElements); }
for(size_t i=0; i<nElements; ++i) {
matCrossSection += nAtomsPerVolume[i] *
GetCrossSection(part, mat->GetElement(i), mat);
xsecelm[i] = matCrossSection;
}
return matCrossSection;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4double
G4CrossSectionDataStore::GetCrossSection(const G4DynamicParticle* part,
const G4Element* elm,
@@ -285,7 +312,7 @@ G4CrossSectionDataStore::GetCrossSection(const G4DynamicParticle* part,
elmCrossSection = 0.0;
G4int i = nDataSetList-1;
G4int Z = G4lrint(elm->GetZ());
G4int Z = elm->GetZasInt();
if (elm->GetNaturalAbundanceFlag() &&
dataSetList[i]->IsElementApplicable(part, Z, mat)) {
@@ -300,16 +327,14 @@ G4CrossSectionDataStore::GetCrossSection(const G4DynamicParticle* part,
} else {
// isotope wise cross section
G4int nIso = elm->GetNumberOfIsotopes();
G4Isotope* iso = 0;
size_t nIso = elm->GetNumberOfIsotopes();
// user-defined isotope abundances
G4IsotopeVector* isoVector = elm->GetIsotopeVector();
G4double* abundVector = elm->GetRelativeAbundanceVector();
const G4double* abundVector = elm->GetRelativeAbundanceVector();
for (G4int j = 0; j<nIso; ++j) {
for (size_t j=0; j<nIso; ++j) {
if(abundVector[j] > 0.0) {
iso = (*isoVector)[j];
const G4Isotope* iso = elm->GetIsotope(j);
elmCrossSection += abundVector[j]*
GetIsoCrossSection(part, Z, iso->GetN(), iso, elm, mat, i);
//G4cout << "Isotope wise " << elmParticle->GetParticleName()
@@ -391,50 +416,37 @@ G4CrossSectionDataStore::GetCrossSection(const G4DynamicParticle* part,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4Element*
const G4Element*
G4CrossSectionDataStore::SampleZandA(const G4DynamicParticle* part,
const G4Material* mat,
G4Nucleus& target)
{
counters.SampleZandA();
size_t nElements = mat->GetNumberOfElements();
const G4Element* anElement = mat->GetElement(0);
G4int nElements = mat->GetNumberOfElements();
const G4ElementVector* theElementVector = mat->GetElementVector();
G4Element* anElement = (*theElementVector)[0];
G4double cross = GetCrossSection(part, mat , true);
// select element from a compound
if(1 < nElements) {
cross *= G4UniformRand();
for(G4int i=0; i<nElements; ++i) {
G4double cross = matCrossSection*G4UniformRand();
for(size_t i=0; i<nElements; ++i) {
if(cross <= xsecelm[i]) {
anElement = (*theElementVector)[i];
anElement = mat->GetElement(i);
break;
}
}
}
G4int Z = G4lrint(anElement->GetZ());
G4Isotope* iso = 0;
G4int Z = anElement->GetZasInt();
const G4Isotope* iso = nullptr;
G4int i = nDataSetList-1;
G4int i = nDataSetList-1;
if (dataSetList[i]->IsElementApplicable(part, Z, mat)) {
//----------------------------------------------------------------
// element-wise cross section
// isotope cross section is not computed
//----------------------------------------------------------------
G4int nIso = anElement->GetNumberOfIsotopes();
if (0 >= nIso) {
G4cout << " Element " << anElement->GetName() << " Z= " << Z
<< " has no isotopes " << G4endl;
throw G4HadronicException(__FILE__, __LINE__,
" Isotope vector is not defined");
return anElement;
}
// isotope abundances
G4IsotopeVector* isoVector = anElement->GetIsotopeVector();
iso = (*isoVector)[0];
size_t nIso = anElement->GetNumberOfIsotopes();
iso = anElement->GetIsotope(0);
// more than 1 isotope
if(1 < nIso) {
@@ -447,30 +459,20 @@ G4CrossSectionDataStore::SampleZandA(const G4DynamicParticle* part,
// isotope-wise cross section
// isotope cross section is computed
//----------------------------------------------------------------
G4int nIso = anElement->GetNumberOfIsotopes();
cross = 0.0;
if (0 >= nIso) {
G4cout << " Element " << anElement->GetName() << " Z= " << Z
<< " has no isotopes " << G4endl;
throw G4HadronicException(__FILE__, __LINE__,
" Isotope vector is not defined");
return anElement;
}
// user-defined isotope abundances
G4IsotopeVector* isoVector = anElement->GetIsotopeVector();
iso = (*isoVector)[0];
size_t nIso = anElement->GetNumberOfIsotopes();
iso = anElement->GetIsotope(0);
// more than 1 isotope
if(1 < nIso) {
G4double* abundVector = anElement->GetRelativeAbundanceVector();
if(G4int(xseciso.size()) < nIso) { xseciso.resize(nIso); }
const G4double* abundVector = anElement->GetRelativeAbundanceVector();
if(xseciso.size() < nIso) { xseciso.resize(nIso); }
for (G4int j = 0; j<nIso; ++j) {
G4double cross = 0.0;
size_t j;
for (j = 0; j<nIso; ++j) {
G4double xsec = 0.0;
if(abundVector[j] > 0.0) {
iso = (*isoVector)[j];
iso = anElement->GetIsotope(j);
xsec = abundVector[j]*
GetIsoCrossSection(part, Z, iso->GetN(), iso, anElement, mat, i);
}
@@ -478,9 +480,9 @@ G4CrossSectionDataStore::SampleZandA(const G4DynamicParticle* part,
xseciso[j] = cross;
}
cross *= G4UniformRand();
for (G4int j = 0; j<nIso; ++j) {
for (j = 0; j<nIso; ++j) {
if(cross <= xseciso[j]) {
iso = (*isoVector)[j];
iso = anElement->GetIsotope(j);
break;
}
}
@@ -628,27 +630,41 @@ void G4CrossSectionDataStore::PrintCrossSectionHtml(const G4VCrossSectionDataSet
G4String G4CrossSectionDataStore::HtmlFileName(const G4String & in) const
{
G4String str(in);
// replace blanks by _ C++11 version:
#ifdef G4USE_STD11
std::transform(str.begin(), str.end(), str.begin(), [](char ch) {
return ch == ' ' ? '_' : ch;
// replace blanks by _ C++11 version:
std::transform(str.begin(), str.end(), str.begin(), [](char ch) {
return ch == ' ' ? '_' : ch;
});
#else
// and now in ancient language
for(std::string::iterator it = str.begin(); it != str.end(); ++it) {
if(*it == ' ') *it = '_';
}
#endif
str=str + ".html";
return str;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4CrossSectionDataStore::AddDataSet( G4VCrossSectionDataSet* aDataSet , size_t i )
void G4CrossSectionDataStore::AddDataSet(G4VCrossSectionDataSet* p)
{
if ( i > dataSetList.size() ) i = dataSetList.size();
std::vector< G4VCrossSectionDataSet* >::iterator it = dataSetList.end() - i;
dataSetList.insert( it , aDataSet );
++nDataSetList;
if(p->ForAllAtomsAndEnergies()) {
dataSetList.clear();
nDataSetList = 0;
}
dataSetList.push_back(p);
++nDataSetList;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4CrossSectionDataStore::AddDataSet(G4VCrossSectionDataSet* p, size_t i )
{
if(p->ForAllAtomsAndEnergies()) {
dataSetList.clear();
dataSetList.push_back(p);
nDataSetList = 1;
} else {
if ( i > dataSetList.size() ) i = dataSetList.size();
std::vector< G4VCrossSectionDataSet* >::iterator it = dataSetList.end() - i;
dataSetList.insert(it , p);
++nDataSetList;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
@@ -32,21 +32,21 @@
#include "G4AutoLock.hh"
#include "globals.hh"
namespace {
//This is used to lock on shared resource
G4Mutex xsFactoryRegisterMutex = G4MUTEX_INITIALIZER;
}
//This is used to lock on shared resource
// G4TypeMutex<G4CrossSectionFactoryRegistry>()
G4CrossSectionFactoryRegistry* G4CrossSectionFactoryRegistry::instance = 0;
G4CrossSectionFactoryRegistry* G4CrossSectionFactoryRegistry::Instance()
{
G4AutoLock l(&xsFactoryRegisterMutex);
if ( !instance ) instance = new G4CrossSectionFactoryRegistry();
return instance;
G4AutoLock l(G4TypeMutex<G4CrossSectionFactoryRegistry>());
if (!instance)
new G4CrossSectionFactoryRegistry();
return instance;
}
G4CrossSectionFactoryRegistry::G4CrossSectionFactoryRegistry()
{
instance = this;
}
G4CrossSectionFactoryRegistry::G4CrossSectionFactoryRegistry(const G4CrossSectionFactoryRegistry&)
@@ -63,7 +63,7 @@ G4CrossSectionFactoryRegistry& G4CrossSectionFactoryRegistry::operator=(const G4
void G4CrossSectionFactoryRegistry::Register( const G4String& name, G4VBaseXSFactory* factory )
{
G4AutoLock l(&xsFactoryRegisterMutex);
G4AutoLock l(G4TypeMutex<G4CrossSectionFactoryRegistry>());
if ( factories.find(name) != factories.end() )
{
G4ExceptionDescription msg;
@@ -77,7 +77,7 @@ void G4CrossSectionFactoryRegistry::Register( const G4String& name, G4VBaseXSFac
G4VBaseXSFactory* G4CrossSectionFactoryRegistry::GetFactory( const G4String& name, G4bool abortIfNotFound ) const
{
G4AutoLock l(&xsFactoryRegisterMutex);
G4AutoLock l(G4TypeMutex<G4CrossSectionFactoryRegistry>());
std::map<G4String,G4VBaseXSFactory*>::const_iterator it = factories.find(name);
if ( it != factories.end() ) return it->second;
else
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4ElectroNuclearCrossSection.cc 107592 2017-11-24 12:04:25Z gcosmo $
// $Id: G4ElectroNuclearCrossSection.cc 109482 2018-04-24 14:47:28Z gcosmo $
//
// G4 Physics class: G4ElectroNuclearCrossSection for gamma+A cross sections
// Created: M.V. Kossov, CERN/ITEP(Moscow), 10-OCT-01
@@ -2381,7 +2381,10 @@ G4int G4ElectroNuclearCrossSection::GetFunctions(G4double a, G4double* xx, G4dou
{
// --------------------------------
G4int r=-1; // Low channel for J-functions
if(a<=.9999 || a>238.49) // Plutonium 244 is forbidden
//AR-24Apr2018 Switch to allow transuranic elements
const G4bool isHeavyElementAllowed = true;
if(a<=.9999 || ( !isHeavyElementAllowed && a>238.49))
{
G4cout<<"***G4ElectroNuclearCrossSection::GetFunctions: A="<<a<<"(?). No CS returned!"<<G4endl;
return r;
@@ -0,0 +1,163 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// $Id: G4HadronXSDataTable.cc 96794 2016-05-09 10:09:30Z gcosmo $
//
//---------------------------------------------------------------------------
//
// GEANT4 Class file
//
// Description: Data structure for cross sections per materials
//
// Author: V.Ivanchenko 31.05.2018
//
// Modifications:
//
//----------------------------------------------------------------------------
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "G4HadronXSDataTable.hh"
#include "G4PhysicsLogVector.hh"
#include "G4Material.hh"
#include "G4MaterialTable.hh"
#include "G4DynamicParticle.hh"
#include "G4CrossSectionDataStore.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4HadElementSelector::G4HadElementSelector(G4DynamicParticle* dp,
G4CrossSectionDataStore* xs,
const G4Material* mat,
G4int bins, G4double emin,
G4double emax, G4bool spline)
{
G4int n = mat->GetNumberOfElements();
nElmMinusOne = n - 1;
theElementVector = mat->GetElementVector();
if(nElmMinusOne > 0) {
G4PhysicsVector* first = nullptr;
xSections.resize(n, first);
first = new G4PhysicsLogVector(emin,emax,bins);
first->SetSpline(spline);
xSections[0] = first;
for(G4int i=1; i<n; ++i) {
xSections[i] = new G4PhysicsVector(*first);
}
std::vector<double> temp;
temp.resize(n, 0.0);
for(G4int j=0; j<=bins; ++j) {
G4double cross = 0.0;
G4double e = first->Energy(j);
dp->SetKineticEnergy(e);
for(G4int i=0; i<n; ++i) {
cross += xs->GetCrossSection(dp, (*theElementVector)[i], mat);
temp[i] = cross;
}
G4double fact = (cross > 0.0) ? 1.0/cross : 0.0;
for(G4int i=0; i<n; ++i) {
G4double y = (i<n-1) ? temp[i]*fact : 1.0;
xSections[i]->PutValue(j, y);
}
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4HadElementSelector::~G4HadElementSelector()
{
if(nElmMinusOne > 0) {
for(G4int i=0; i<=nElmMinusOne; ++i) { delete xSections[i]; }
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4HadElementSelector::Dump()
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4HadronXSDataTable::G4HadronXSDataTable() : nMaterials(0)
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4HadronXSDataTable::Initialise(G4DynamicParticle* dp,
G4CrossSectionDataStore* xs,
G4int bins, G4double emin, G4double emax,
G4bool spline)
{
size_t nn = G4Material::GetNumberOfMaterials();
if(nn > nMaterials) {
G4PhysicsLogVector* first = nullptr;
G4int sbins = std::max(10, bins/5);
const G4MaterialTable* mtable = G4Material::GetMaterialTable();
for(size_t i=nMaterials; i<nn; ++i) {
const G4Material* mat = (*mtable)[i];
G4PhysicsVector* v = nullptr;
G4HadElementSelector* es = nullptr;
// create real vector only for complex materials
if(mat->GetNumberOfElements() > 1) {
if(!first) {
first = new G4PhysicsLogVector(emin, emax, bins);
first->SetSpline(spline);
v = first;
} else {
v = new G4PhysicsVector(*first);
}
for(G4int j=0; j<=bins; ++j) {
G4double e = first->Energy(j);
dp->SetKineticEnergy(e);
G4double cros = xs->ComputeCrossSection(dp, mat);
v->PutValue(j, cros);
}
elmSelectors[i] = new G4HadElementSelector(dp, xs, mat, sbins, emin, emax, spline);
}
xsData.push_back(v);
elmSelectors.push_back(es);
}
nMaterials = nn;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4HadronXSDataTable::~G4HadronXSDataTable()
{
for(size_t i=0; i<nMaterials; ++i) {
delete xsData[i];
delete elmSelectors[i];
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4HadronXSDataTable::Dump()
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -116,6 +116,10 @@ void G4KokoulinMuonNuclearXS::BuildCrossSectionTable()
for (G4int j = 0; j < nEl; j++) {
Z = G4lrint((*theElementTable)[j]->GetZ());
//AR-24Apr2018 Switch to treat transuranic elements as uranium
const G4bool isHeavyElementAllowed = true; if ( isHeavyElementAllowed && Z>92 ) Z=92;
A = nistManager->GetAtomicMassAmu(Z);
if(Z < MAXZMUN && !theCrossSection[Z]) {
theCrossSection[Z] = new G4PhysicsLogVector(LowestKineticEnergy,
@@ -218,6 +222,9 @@ G4double G4KokoulinMuonNuclearXS::
GetElementCrossSection(const G4DynamicParticle* aPart,
G4int Z, const G4Material*)
{
//AR-24Apr2018 Switch to treat transuranic elements as uranium
const G4bool isHeavyElementAllowed = true; if ( isHeavyElementAllowed && Z>92 ) Z=92;
return theCrossSection[Z]->Value(aPart->GetKineticEnergy());
}
@@ -0,0 +1,106 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#include "G4NeutrinoElectronTotXsc.hh"
#include "G4NeutrinoElectronCcXsc.hh"
#include "G4NeutrinoElectronNcXsc.hh"
#include "G4PhysicalConstants.hh"
#include "G4SystemOfUnits.hh"
#include "G4DynamicParticle.hh"
#include "G4ParticleTable.hh"
#include "G4IonTable.hh"
#include "G4HadTmpUtil.hh"
#include "G4NistManager.hh"
using namespace std;
using namespace CLHEP;
G4NeutrinoElectronTotXsc::G4NeutrinoElectronTotXsc()
: G4VCrossSectionDataSet("NuElectronTotXsc")
{
fCcXsc = new G4NeutrinoElectronCcXsc();
fNcXsc = new G4NeutrinoElectronNcXsc();
fCutEnergy = 0.; // default value
fBiasingFactor = 1.; // default as physics
fCcRatio = 0.5;
}
G4NeutrinoElectronTotXsc::~G4NeutrinoElectronTotXsc()
{}
//////////////////////////////////////////////////////
G4bool
G4NeutrinoElectronTotXsc::IsElementApplicable( const G4DynamicParticle* aPart, G4int i, const G4Material* mat)
{
G4bool result = false;
G4bool apCc = fCcXsc->IsElementApplicable( aPart,i, mat);
G4bool apNc = fNcXsc->IsElementApplicable( aPart, i, mat);
if( apCc || apNc) result = true;
return result;
}
////////////////////////////////////////////////////
G4double G4NeutrinoElectronTotXsc::
GetElementCrossSection(const G4DynamicParticle* aPart, G4int ZZ,
const G4Material* mat)
{
G4double result = 0.;
G4double ccXsc = fCcXsc->GetElementCrossSection( aPart, ZZ, mat);
G4double ncXsc = fNcXsc->GetElementCrossSection( aPart, ZZ, mat);
result = ccXsc + ncXsc;
if (result > 0.) fCcRatio = ccXsc/result;
else fCcRatio = 0.;
return result;
}
////////////////////////////////////////////////////
void G4NeutrinoElectronTotXsc::SetBiasingFactor(G4double bf)
{
fBiasingFactor = bf;
fCcXsc->SetBiasingFactor(bf);
fNcXsc->SetBiasingFactor(bf);
}
////////////////////////////////////////////////////
//
// For separate testing Cc and Nc currents
void G4NeutrinoElectronTotXsc::SetBiasingFactors(G4double bfCc, G4double bfNc)
{
fCcXsc->SetBiasingFactor(bfCc);
fNcXsc->SetBiasingFactor(bfNc);
}
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4NeutronCaptureXS.cc 91903 2015-08-10 12:10:36Z gcosmo $
// $Id: G4NeutronCaptureXS.cc 110787 2018-06-14 06:43:31Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -58,34 +58,38 @@ using namespace std;
const G4int G4NeutronCaptureXS::amin[] = {
0,
0, 0, 6, 0,10,12,14,16, 0, 0, //1-10
0, 0, 0,28, 0, 0, 0,36, 0,40, //11-20
0, 0, 0, 0, 0,54, 0,58,63,64, //21-30
0,70, 0, 0, 0, 0, 0, 0, 0,90, //31-40
0, 0, 0, 0, 0, 0,107,106, 0,112, //41-50
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //51-60
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //61-70
0, 0, 0,180, 0, 0, 0, 0, 0, 0, //71-80
0,204, 0, 0, 0, 0, 0, 0, 0, 0, //81-90
0,235};
1, 4, 6, 9, 10, 12, 14, 16, 19, 20, //1-10
23, 24, 27, 28, 31, 32, 35, 36, 39, 40, //11-20
45, 46, 50, 50, 55, 54, 59, 58, 63, 64, //21-30
69, 70, 75, 0, 0, 0, 0, 0, 0, 90, //31-40
0, 92, 0, 0, 0, 102, 107, 106, 113, 112, //41-50
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //51-60
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //61-70
0, 0, 181, 180, 0, 0, 0, 192, 197, 0, //71-80
0, 204, 209, 0, 0, 0, 0, 0, 0, 0, //81-90
0, 235};
const G4int G4NeutronCaptureXS::amax[] = {
0,
0, 0, 7, 0,11,13,15,18, 0, 0, //1-10
0, 0, 0,30, 0, 0, 0,40, 0,48, //11-20
0, 0, 0, 0, 0,58, 0,64,65,70, //21-30
0,76, 0, 0, 0, 0, 0, 0, 0,96, //31-40
0, 0, 0, 0, 0, 0,109,116, 0,124, //41-50
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //51-60
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //61-70
0, 0, 0,186, 0, 0, 0, 0, 0, 0, //71-80
0,208, 0, 0, 0, 0, 0, 0, 0, 0, //81-90
0,238};
1, 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
0, 100, 0, 0, 0, 110, 109, 116, 115, 124, //41-50
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //51-60
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //61-70
0, 0, 181, 186, 0, 0, 0, 198, 197, 0, //71-80
0, 208, 209, 0, 0, 0, 0, 0, 0, 0, //81-90
0, 238};
G4ElementData* G4NeutronCaptureXS::data = 0;
G4ElementData* G4NeutronCaptureXS::data = nullptr;
#ifdef G4MULTITHREADED
G4Mutex G4NeutronCaptureXS::neutronCaptureXSMutex = G4MUTEX_INITIALIZER;
#endif
G4NeutronCaptureXS::G4NeutronCaptureXS()
: G4VCrossSectionDataSet(Default_Name()),
emax(20*MeV),elimit(1.0e-10*eV)
emax(20*CLHEP::MeV),elimit(1.0e-10*CLHEP::eV)
{
// verboseLevel = 0;
if(verboseLevel > 0){
@@ -97,7 +101,7 @@ G4NeutronCaptureXS::G4NeutronCaptureXS()
G4NeutronCaptureXS::~G4NeutronCaptureXS()
{
if(isMaster) { delete data; data = 0; }
if(isMaster) { delete data; data = nullptr; }
}
void G4NeutronCaptureXS::CrossSectionDescription(std::ostream& outFile) const
@@ -105,8 +109,8 @@ void G4NeutronCaptureXS::CrossSectionDescription(std::ostream& outFile) const
outFile << "G4NeutronCaptureXS calculates the neutron capture cross sections\n"
<< "on nuclei using data from the high precision neutron database.\n"
<< "These data are simplified and smoothed over the resonance region\n"
<< "in order to reduce CPU time. G4NeutronCaptureXS is valid up to\n"
<< "20 MeV for all targets through U.\n";
<< "in order to reduce CPU time. G4NeutronCaptureXS is set to zero\n"
<< "above 20 MeV for all targets. Cross section is zero also for Z>92.\n";
}
G4bool
@@ -118,7 +122,7 @@ G4NeutronCaptureXS::IsElementApplicable(const G4DynamicParticle*,
G4bool
G4NeutronCaptureXS::IsIsoApplicable(const G4DynamicParticle*,
G4int /*ZZ*/, G4int /*AA*/,
G4int, G4int,
const G4Element*, const G4Material*)
{
return true;
@@ -135,11 +139,7 @@ G4NeutronCaptureXS::GetElementCrossSection(const G4DynamicParticle* aParticle,
// element was not initialised
G4PhysicsVector* pv = data->GetElementData(Z);
if(!pv) {
Initialise(Z);
pv = data->GetElementData(Z);
if(!pv) { return xs; }
}
if(!pv) { return xs; }
G4double e1 = pv->Energy(0);
if(ekin < e1) { xs = (*pv)[0]*std::sqrt(e1/ekin); }
@@ -157,56 +157,54 @@ G4NeutronCaptureXS::GetIsoCrossSection(const G4DynamicParticle* aParticle,
const G4Isotope*, const G4Element*,
const G4Material*)
{
G4double xs = 0.0;
G4double ekin = aParticle->GetKineticEnergy();
if(ekin <= emax && Z > 0 && Z < MAXZCAPTURE) {
xs = IsoCrossSection(ekin, Z, A);
}
return xs;
return IsoCrossSection(aParticle->GetKineticEnergy(), Z, A);
}
G4double G4NeutronCaptureXS::IsoCrossSection(G4double ekin, G4int Z, G4int A)
{
G4double xs = 0.0;
if(ekin > emax || Z < 1 || Z >= MAXZCAPTURE) { return xs; }
if(ekin < elimit) { ekin = elimit; }
// element was not initialised
G4PhysicsVector* pv = data->GetElementData(Z);
if(!pv) {
Initialise(Z);
pv = data->GetElementData(Z);
}
// isotope cross section exist
if(pv && amin[Z] > 0 && A >= amin[Z] && A <= amax[Z]) {
pv = data->GetComponentDataByID(Z, A - amin[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); }
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;
}
if(verboseLevel > 0) {
G4cout << "G4NeutronCaptureXS::IsoCrossSection: Ekin(MeV)= " << ekin/MeV
<< " xs(b)= " << xs/barn
<< " Z= " << Z << " A= " << A << G4endl;
// 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;
}
}
return xs;
}
G4Isotope* G4NeutronCaptureXS::SelectIsotope(const G4Element* anElement,
G4double kinEnergy)
const G4Isotope*
G4NeutronCaptureXS::SelectIsotope(const G4Element* anElement,
G4double kinEnergy)
{
size_t nIso = anElement->GetNumberOfIsotopes();
G4IsotopeVector* isoVector = anElement->GetIsotopeVector();
G4Isotope* iso = (*isoVector)[0];
const G4Isotope* iso = anElement->GetIsotope(0);
// more than 1 isotope
if(1 < nIso) {
G4int Z = G4lrint(anElement->GetZ());
G4int Z = anElement->GetZasInt();
G4double* abundVector = anElement->GetRelativeAbundanceVector();
const G4double* abundVector = anElement->GetRelativeAbundanceVector();
G4double q = G4UniformRand();
G4double sum = 0.0;
@@ -216,26 +214,23 @@ G4Isotope* G4NeutronCaptureXS::SelectIsotope(const G4Element* anElement,
for (j = 0; j<nIso; ++j) {
sum += abundVector[j];
if(q <= sum) {
iso = (*isoVector)[j];
iso = anElement->GetIsotope(j);
break;
}
}
} else {
// element may be not initialised in unit test
if(!data->GetElementData(Z)) { Initialise(Z); }
size_t nn = temp.size();
if(nn < nIso) { temp.resize(nIso, 0.); }
for (j=0; j<nIso; ++j) {
sum += abundVector[j]*IsoCrossSection(kinEnergy, Z,
(*isoVector)[j]->GetN());
anElement->GetIsotope(j)->GetN());
temp[j] = sum;
}
sum *= q;
for (j = 0; j<nIso; ++j) {
if(temp[j] >= sum) {
iso = (*isoVector)[j];
iso = anElement->GetIsotope(j);
break;
}
}
@@ -261,10 +256,18 @@ G4NeutronCaptureXS::BuildPhysicsTable(const G4ParticleDefinition& p)
}
if(!data) {
isMaster = true;
data = new G4ElementData();
data->SetName("NeutronCapture");
temp.resize(13,0.0);
#ifdef G4MULTITHREADED
G4MUTEXLOCK(&neutronCaptureXSMutex);
if(!data) {
#endif
isMaster = true;
data = new G4ElementData();
data->SetName("NeutronCapture");
temp.resize(13,0.0);
#ifdef G4MULTITHREADED
}
G4MUTEXUNLOCK(&neutronCaptureXSMutex);
#endif
}
// it is possible re-initialisation for the second run
@@ -277,15 +280,12 @@ G4NeutronCaptureXS::BuildPhysicsTable(const G4ParticleDefinition& p)
// Access to elements
const G4ElementTable* theElmTable = G4Element::GetElementTable();
size_t numOfElm = G4Element::GetNumberOfElements();
if(numOfElm > 0) {
for(size_t i=0; i<numOfElm; ++i) {
G4int Z = G4int(((*theElmTable)[i])->GetZ());
if(Z < 1) { Z = 1; }
else if(Z >= MAXZCAPTURE) { Z = MAXZCAPTURE-1; }
//G4cout << "Z= " << Z << G4endl;
// Initialisation
if(!data->GetElementData(Z)) { Initialise(Z, path); }
}
for(size_t i=0; i<numOfElm; ++i) {
G4int Z = ((*theElmTable)[i])->GetZasInt();
if(Z >= MAXZCAPTURE) { Z = MAXZCAPTURE-1; }
//G4cout << "Z= " << Z << G4endl;
// Initialisation
if(!data->GetElementData(Z)) { Initialise(Z, path); }
}
}
}
@@ -308,7 +308,7 @@ G4NeutronCaptureXS::Initialise(G4int Z, const char* p)
// upload element data
std::ostringstream ost;
ost << path << "/cap" << Z ;
ost << path << "/neutron/cap" << Z ;
G4PhysicsVector* v = RetrieveVector(ost, true);
data->InitialiseForElement(Z, v);
@@ -319,7 +319,7 @@ G4NeutronCaptureXS::Initialise(G4int Z, const char* p)
for(G4int A=amin[Z]; A<=amax[Z]; ++A) {
std::ostringstream ost1;
ost1 << path << "/cap" << Z << "_" << A;
ost1 << path << "/neutron/cap" << Z << "_" << A;
v = RetrieveVector(ost1, false);
data->AddComponent(Z, A, v);
}
@@ -329,7 +329,7 @@ G4NeutronCaptureXS::Initialise(G4int Z, const char* p)
G4PhysicsVector*
G4NeutronCaptureXS::RetrieveVector(std::ostringstream& ost, G4bool warn)
{
G4PhysicsLogVector* v = 0;
G4PhysicsLogVector* v = nullptr;
std::ifstream filein(ost.str().c_str());
if (!(filein)) {
if(warn) {
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4NeutronElasticXS.cc 93682 2015-10-28 10:09:49Z gcosmo $
// $Id: G4NeutronElasticXS.cc 110744 2018-06-12 06:35:40Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -60,8 +60,12 @@ G4_DECLARE_XS_FACTORY(G4NeutronElasticXS);
using namespace std;
std::vector<G4PhysicsVector*>* G4NeutronElasticXS::data = 0;
G4double G4NeutronElasticXS::coeff[] = {0.0};
G4PhysicsVector* G4NeutronElasticXS::data[] = {nullptr};
G4double G4NeutronElasticXS::coeff[] = {1.0};
#ifdef G4MULTITHREADED
G4Mutex G4NeutronElasticXS::neutronElasticXSMutex = G4MUTEX_INITIALIZER;
#endif
G4NeutronElasticXS::G4NeutronElasticXS()
: G4VCrossSectionDataSet(Default_Name()),
@@ -83,11 +87,9 @@ G4NeutronElasticXS::~G4NeutronElasticXS()
delete ggXsection;
if(isMaster) {
for(G4int i=0; i<MAXZEL; ++i) {
delete (*data)[i];
(*data)[i] = 0;
delete data[i];
data[i] = nullptr;
}
delete data;
data = 0;
}
}
@@ -97,8 +99,7 @@ void G4NeutronElasticXS::CrossSectionDescription(std::ostream& outFile) const
<< "cross section on nuclei using data from the high precision\n"
<< "neutron database. These data are simplified and smoothed over\n"
<< "the resonance region in order to reduce CPU time.\n"
<< "G4NeutronElasticXS is valid for energies up to 20 MeV, for all\n"
<< "targets through U.\n";
<< "For high energies Glauber-Gribiv cross section is used.\n";
}
G4bool
@@ -110,43 +111,38 @@ G4NeutronElasticXS::IsElementApplicable(const G4DynamicParticle*,
G4double
G4NeutronElasticXS::GetElementCrossSection(const G4DynamicParticle* aParticle,
G4int Z, const G4Material*)
G4int ZZ, const G4Material*)
{
G4double xs = 0.0;
G4double ekin = aParticle->GetKineticEnergy();
if(Z < 1 || Z >=MAXZEL) { return xs; }
G4int Z = (ZZ >= MAXZEL) ? MAXZEL - 1 : ZZ;
G4int Amean = G4lrint(G4NistManager::Instance()->GetAtomicMassAmu(Z));
G4PhysicsVector* pv = (*data)[Z];
G4PhysicsVector* pv = data[Z];
// G4cout << "G4NeutronElasticXS::GetCrossSection e= " << ekin
// << " Z= " << Z << G4endl;
// element was not initialised
if(!pv) {
Initialise(Z);
pv = (*data)[Z];
if(!pv) { return xs; }
}
if(!pv) { return xs; }
G4double e1 = pv->Energy(0);
if(ekin <= e1) { return (*pv)[0]; }
if(ekin <= pv->Energy(0)) { return (*pv)[0]; }
G4int n = pv->GetVectorLength() - 1;
G4double e2 = pv->Energy(n);
if(ekin <= e2) {
if(ekin <= pv->GetMaxEnergy()) {
xs = pv->Value(ekin);
} else if(1 == Z) {
fNucleon->GetHadronNucleonXscPDG(aParticle, proton);
xs = coeff[1]*fNucleon->GetElasticHadronNucleonXsc();
} else {
G4int Amean =
G4lrint(G4NistManager::Instance()->GetAtomicMassAmu(Z));
ggXsection->GetIsoCrossSection(aParticle, Z, Amean);
xs = coeff[Z]*ggXsection->GetElasticGlauberGribovXsc();
}
if(verboseLevel > 0){
G4cout << "ekin= " << ekin << ", XSinel= " << xs << G4endl;
G4cout << "Z= " << Z << " Ekin(MeV)= " << ekin/CLHEP::MeV
<< ", nElmXSel(bn)= " << xs/CLHEP::barn
<< G4endl;
}
return xs;
}
@@ -167,11 +163,16 @@ G4NeutronElasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
return;
}
if(0 == coeff[0]) {
isMaster = true;
for(G4int i=0; i<MAXZEL; ++i) { coeff[i] = 1.0; }
data = new std::vector<G4PhysicsVector*>;
data->resize(MAXZEL, 0);
if(!data[1]) {
#ifdef G4MULTITHREADED
G4MUTEXLOCK(&neutronElasticXSMutex);
if(!data[1]) {
#endif
isMaster = true;
#ifdef G4MULTITHREADED
}
G4MUTEXUNLOCK(&neutronElasticXSMutex);
#endif
}
// it is possible re-initialisation for the second run
@@ -187,15 +188,12 @@ G4NeutronElasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
// Access to elements
const G4ElementTable* theElmTable = G4Element::GetElementTable();
size_t numOfElm = G4Element::GetNumberOfElements();
if(numOfElm > 0) {
for(size_t i=0; i<numOfElm; ++i) {
G4int Z = G4int(((*theElmTable)[i])->GetZ());
if(Z < 1) { Z = 1; }
else if(Z >= MAXZEL) { Z = MAXZEL-1; }
//G4cout << "Z= " << Z << G4endl;
// Initialisation
if(!(*data)[Z]) { Initialise(Z, dynParticle, path); }
}
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); }
}
delete dynParticle;
}
@@ -205,7 +203,7 @@ void
G4NeutronElasticXS::Initialise(G4int Z, G4DynamicParticle* dp,
const char* p)
{
if((*data)[Z]) { return; }
if(data[Z]) { return; }
const char* path = p;
if(!p) {
// check environment variable
@@ -218,19 +216,12 @@ G4NeutronElasticXS::Initialise(G4int Z, G4DynamicParticle* dp,
return;
}
}
G4DynamicParticle* dynParticle = dp;
if(!dp) {
dynParticle =
new G4DynamicParticle(G4Neutron::Neutron(),G4ThreeVector(1,0,0),1);
}
G4int Amean = G4lrint(G4NistManager::Instance()->GetAtomicMassAmu(Z));
// upload data from file
(*data)[Z] = new G4PhysicsLogVector();
data[Z] = new G4PhysicsLogVector();
std::ostringstream ost;
ost << path << "/elast" << Z ;
ost << path << "/neutron/el" << Z ;
std::ifstream filein(ost.str().c_str());
if (!(filein)) {
G4ExceptionDescription ed;
@@ -246,7 +237,7 @@ G4NeutronElasticXS::Initialise(G4int Z, G4DynamicParticle* dp,
}
// retrieve data from DB
if(!((*data)[Z]->Retrieve(filein, true))) {
if(!data[Z]->Retrieve(filein, true)) {
G4ExceptionDescription ed;
ed << "Data file <" << ost.str().c_str()
<< "> is not retrieved!";
@@ -256,19 +247,18 @@ G4NeutronElasticXS::Initialise(G4int Z, G4DynamicParticle* dp,
}
// smooth transition
size_t n = (*data)[Z]->GetVectorLength() - 1;
G4double emax = (*data)[Z]->Energy(n);
G4double sig1 = (*(*data)[Z])[n];
dynParticle->SetKineticEnergy(emax);
G4double sig1 = (*(data[Z]))[data[Z]->GetVectorLength()-1];
dp->SetKineticEnergy(data[Z]->GetMaxEnergy());
G4double sig2 = 0.0;
if(1 == Z) {
fNucleon->GetHadronNucleonXscPDG(dynParticle, proton);
fNucleon->GetHadronNucleonXscPDG(dp, proton);
sig2 = fNucleon->GetElasticHadronNucleonXsc();
} else {
ggXsection->GetIsoCrossSection(dynParticle, Z, Amean);
G4int Amean =
G4lrint(G4NistManager::Instance()->GetAtomicMassAmu(Z));
ggXsection->GetIsoCrossSection(dp, Z, Amean);
sig2 = ggXsection->GetElasticGlauberGribovXsc();
}
if(sig2 > 0.) { coeff[Z] = sig1/sig2; }
}
if(!dp) { delete dynParticle; }
}
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4NeutronInelasticXS.cc 93682 2015-10-28 10:09:49Z gcosmo $
// $Id: G4NeutronInelasticXS.cc 110787 2018-06-14 06:43:31Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -63,36 +63,40 @@ using namespace std;
const G4int G4NeutronInelasticXS::amin[] = {
0,
0, 0, 6, 0,10,12,14,16, 0, 0, //1-10
0, 0, 0,28, 0, 0, 0,36, 0,40, //11-20
0, 0, 0, 0, 0,54, 0,58,63,64, //21-30
0,70, 0, 0, 0, 0, 0, 0, 0,90, //31-40
0, 0, 0, 0, 0, 0,107,106, 0,112, //41-50
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //51-60
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //61-70
0, 0, 0,180, 0, 0, 0, 0, 0, 0, //71-80
0,204, 0, 0, 0, 0, 0, 0, 0, 0, //81-90
0,235};
1, 4, 6, 9, 10, 12, 14, 16, 19, 20, //1-10
23, 24, 27, 28, 31, 32, 35, 36, 39, 40, //11-20
45, 46, 50, 50, 55, 54, 59, 58, 63, 64, //21-30
69, 70, 75, 0, 0, 0, 0, 0, 0, 90, //31-40
0, 92, 0, 0, 0, 102, 107, 106, 113, 112, //41-50
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //51-60
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //61-70
0, 0, 181, 180, 0, 0, 0, 192, 197, 0, //71-80
0, 204, 209, 0, 0, 0, 0, 0, 0, 0, //81-90
0, 235};
const G4int G4NeutronInelasticXS::amax[] = {
0,
0, 0, 7, 0,11,13,15,18, 0, 0, //1-10
0, 0, 0,30, 0, 0, 0,40, 0,48, //11-20
0, 0, 0, 0, 0,58, 0,64,65,70, //21-30
0,76, 0, 0, 0, 0, 0, 0, 0,96, //31-40
0, 0, 0, 0, 0, 0,109,116, 0,124, //41-50
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //51-60
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //61-70
0, 0, 0,186, 0, 0, 0, 0, 0, 0, //71-80
0,208, 0, 0, 0, 0, 0, 0, 0, 0, //81-90
0,238};
1, 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
0, 100, 0, 0, 0, 110, 109, 116, 115, 124, //41-50
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //51-60
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //61-70
0, 0, 181, 186, 0, 0, 0, 198, 197, 0, //71-80
0, 208, 209, 0, 0, 0, 0, 0, 0, 0, //81-90
0, 238};
G4double G4NeutronInelasticXS::coeff[] = {1.0};
G4ElementData* G4NeutronInelasticXS::data = 0;
G4ElementData* G4NeutronInelasticXS::data = nullptr;
#ifdef G4MULTITHREADED
G4Mutex G4NeutronInelasticXS::neutronInelasticXSMutex = G4MUTEX_INITIALIZER;
#endif
G4NeutronInelasticXS::G4NeutronInelasticXS()
: G4VCrossSectionDataSet(Default_Name()),
proton(G4Proton::Proton())
proton(G4Proton::Proton()), emax(20*CLHEP::MeV)
{
// verboseLevel = 0;
if(verboseLevel > 0){
@@ -110,7 +114,7 @@ G4NeutronInelasticXS::~G4NeutronInelasticXS()
// << " isMaster= " << isMaster << " data: " << data << G4endl;
delete fNucleon;
delete ggXsection;
if(isMaster) { delete data; data = 0; }
if(isMaster) { delete data; data = nullptr; }
}
void G4NeutronInelasticXS::CrossSectionDescription(std::ostream& outFile) const
@@ -119,8 +123,7 @@ void G4NeutronInelasticXS::CrossSectionDescription(std::ostream& outFile) const
<< "cross section on nuclei using data from the high precision\n"
<< "neutron database. These data are simplified and smoothed over\n"
<< "the resonance region in order to reduce CPU time.\n"
<< "G4NeutronInelasticXS is valid for energies up to 20 MeV, for\n"
<< "nuclei through U.\n";
<< "For high energy Glauber-Gribov cross section model is used\n";
}
G4bool
@@ -132,7 +135,7 @@ G4NeutronInelasticXS::IsElementApplicable(const G4DynamicParticle*,
G4bool
G4NeutronInelasticXS::IsIsoApplicable(const G4DynamicParticle*,
G4int /*ZZ*/, G4int /*AA*/,
G4int, G4int,
const G4Element*, const G4Material*)
{
return true;
@@ -140,44 +143,36 @@ G4NeutronInelasticXS::IsIsoApplicable(const G4DynamicParticle*,
G4double G4NeutronInelasticXS::GetElementCrossSection(
const G4DynamicParticle* aParticle,
G4int Z, const G4Material*)
G4int ZZ, const G4Material*)
{
G4double xs = 0.0;
G4double ekin = aParticle->GetKineticEnergy();
if(Z >= MAXZINEL) { Z = MAXZINEL - 1; }
else if(Z < 1) { Z = 1; }
G4int Amean = G4lrint(G4NistManager::Instance()->GetAtomicMassAmu(Z));
G4int Z = (ZZ >= MAXZINEL) ? MAXZINEL - 1 : ZZ;
G4PhysicsVector* pv = data->GetElementData(Z);
// G4cout << "G4NeutronInelasticXS::GetCrossSection e= " << ekin
// << " Z= " << Z << G4endl;
// element was not initialised
if(!pv) {
Initialise(Z);
pv = data->GetElementData(Z);
if(!pv) { return xs; }
}
if(!pv || ekin <= pv->Energy(0)) { return xs; }
G4double e1 = pv->Energy(0);
if(ekin <= e1) { return xs; }
G4double e2 = pv->GetMaxEnergy();
if(ekin <= e2) {
if(ekin <= pv->GetMaxEnergy()) {
xs = pv->Value(ekin);
} else if(1 == Z) {
fNucleon->GetHadronNucleonXscPDG(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();
}
if(verboseLevel > 0) {
G4cout << "ekin= " << ekin << ", XSinel= " << xs << G4endl;
G4cout << "Z= " << Z << " Ekin(MeV)= " << ekin/CLHEP::MeV
<< ", nElmXSinel(bn)= " << xs/CLHEP::barn
<< G4endl;
}
return xs;
}
@@ -188,88 +183,90 @@ G4double G4NeutronInelasticXS::GetIsoCrossSection(
const G4Isotope*, const G4Element*,
const G4Material*)
{
if(Z >= MAXZINEL) { Z = MAXZINEL - 1; }
else if(Z < 1) { Z = 1; }
return IsoCrossSection(aParticle->GetKineticEnergy(), Z, A);
}
G4double
G4NeutronInelasticXS::IsoCrossSection(G4double ekin, G4int Z, G4int A)
G4NeutronInelasticXS::IsoCrossSection(G4double ekin, G4int ZZ, G4int A)
{
G4double xs = 0.0;
G4int Z = (ZZ >= MAXZINEL) ? MAXZINEL - 1 : ZZ;
/*
G4cout << "IsoCrossSection Z= " << Z << " A= " << A
<< " Amin= " << amin[Z] << " Amax= " << amax[Z]
<< " E(MeV)= " << ekin << G4endl;
*/
// element was not initialised
// 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;
}
}
// isotope data are not available or applicable
G4PhysicsVector* pv = data->GetElementData(Z);
if(!pv) {
Initialise(Z);
pv = data->GetElementData(Z);
}
// isotope cross section exist
if(pv && amin[Z] > 0 && A >= amin[Z] && A <= amax[Z]) {
pv = data->GetComponentDataByIndex(Z, A - amin[Z]);
if(pv && ekin > pv->Energy(0)) { xs = pv->Value(ekin); }
}
if(verboseLevel > 0){
G4cout << "ekin= " << ekin << ", xs= " << xs << G4endl;
if(pv) { xs = pv->Value(ekin); }
if(verboseLevel > 0) {
G4cout << "IsoXS: Z= " << Z << " A= " << A
<< " Ekin(MeV)= " << ekin/CLHEP::MeV
<< ", nElmXSinel(bn)= " << xs/CLHEP::barn << G4endl;
}
return xs;
}
G4Isotope* G4NeutronInelasticXS::SelectIsotope(
const G4Isotope* G4NeutronInelasticXS::SelectIsotope(
const G4Element* anElement, G4double kinEnergy)
{
size_t nIso = anElement->GetNumberOfIsotopes();
G4IsotopeVector* isoVector = anElement->GetIsotopeVector();
G4Isotope* iso = (*isoVector)[0];
const G4Isotope* iso = anElement->GetIsotope(0);
//G4cout << "SelectIsotope NIso= " << nIso << G4endl;
if(1 == nIso) { return iso; }
// more than 1 isotope
if(1 < nIso) {
G4int Z = G4lrint(anElement->GetZ());
//G4cout << "SelectIsotope Z= " << Z << G4endl;
G4int Z = anElement->GetZasInt();
//G4cout << "SelectIsotope Z= " << Z << G4endl;
G4double* abundVector = anElement->GetRelativeAbundanceVector();
G4double q = G4UniformRand();
G4double sum = 0.0;
const G4double* abundVector = anElement->GetRelativeAbundanceVector();
G4double q = G4UniformRand();
G4double sum = 0.0;
// is there isotope wise cross section?
size_t j;
if(0 == amin[Z] || Z >= MAXZINEL) {
for (j = 0; j<nIso; ++j) {
sum += abundVector[j];
if(q <= sum) {
iso = (*isoVector)[j];
break;
}
// isotope wise cross section not available
size_t j;
if(kinEnergy > emax || 0 >= amin[Z] || Z >= MAXZINEL) {
for (j = 0; j<nIso; ++j) {
sum += abundVector[j];
if(q <= sum) {
iso = anElement->GetIsotope(j);
break;
}
} else {
}
return iso;
}
// element may be not initialised in unit test
if(!data->GetElementData(Z)) { Initialise(Z); }
size_t nn = temp.size();
if(nn < nIso) { temp.resize(nIso, 0.); }
// use isotope cross sections
size_t nn = temp.size();
if(nn < nIso) { temp.resize(nIso, 0.); }
for (j=0; j<nIso; ++j) {
//G4cout << j << "-th isotope " << (*isoVector)[j]->GetN()
// << " abund= " << abundVector[j] << G4endl;
sum += abundVector[j]*IsoCrossSection(kinEnergy, Z,
(*isoVector)[j]->GetN());
temp[j] = sum;
}
sum *= q;
for (j = 0; j<nIso; ++j) {
if(temp[j] >= sum) {
iso = (*isoVector)[j];
break;
}
}
for (j=0; j<nIso; ++j) {
//G4cout << j << "-th isotope " << (*isoVector)[j]->GetN()
// << " abund= " << abundVector[j] << G4endl;
sum += abundVector[j]*IsoCrossSection(kinEnergy, Z,
anElement->GetIsotope(j)->GetN());
temp[j] = sum;
}
sum *= q;
for (j = 0; j<nIso; ++j) {
if(temp[j] >= sum) {
iso = anElement->GetIsotope(j);
break;
}
}
return iso;
@@ -292,10 +289,18 @@ G4NeutronInelasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
}
if(!data) {
isMaster = true;
data = new G4ElementData();
data->SetName("NeutronInelastic");
temp.resize(13,0.0);
#ifdef G4MULTITHREADED
G4MUTEXLOCK(&neutronInelasticXSMutex);
if(!data) {
#endif
isMaster = true;
data = new G4ElementData();
data->SetName("NeutronInelastic");
temp.resize(13,0.0);
#ifdef G4MULTITHREADED
}
G4MUTEXUNLOCK(&neutronInelasticXSMutex);
#endif
}
// it is possible re-initialisation for the new run
@@ -311,16 +316,13 @@ G4NeutronInelasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
// Access to elements
const G4ElementTable* theElmTable = G4Element::GetElementTable();
size_t numOfElm = G4Element::GetNumberOfElements();
if(numOfElm > 0) {
for(size_t i=0; i<numOfElm; ++i) {
G4int Z = G4lrint(((*theElmTable)[i])->GetZ());
if(Z < 1) { Z = 1; }
else if(Z >= MAXZINEL) { Z = MAXZINEL-1; }
//G4cout << "Z= " << Z << G4endl;
// Initialisation
if(!(data->GetElementData(Z))) {
Initialise(Z, dynParticle, path);
}
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);
}
}
delete dynParticle;
@@ -344,17 +346,9 @@ G4NeutronInelasticXS::Initialise(G4int Z, G4DynamicParticle* dp,
return;
}
}
G4DynamicParticle* dynParticle = dp;
if(!dp) {
dynParticle =
new G4DynamicParticle(G4Neutron::Neutron(),G4ThreeVector(1,0,0),1);
}
G4int Amean = G4lrint(G4NistManager::Instance()->GetAtomicMassAmu(Z));
// upload element data
std::ostringstream ost;
ost << path << "/inelast" << Z ;
ost << path << "/neutron/inel" << Z ;
G4PhysicsVector* v = RetrieveVector(ost, true);
data->InitialiseForElement(Z, v);
/*
@@ -369,32 +363,32 @@ G4NeutronInelasticXS::Initialise(G4int Z, G4DynamicParticle* dp,
for(G4int A=amin[Z]; A<=amax[Z]; ++A) {
std::ostringstream ost1;
ost1 << path << "/inelast" << Z << "_" << A;
ost1 << path << "/neutron/inel" << Z << "_" << A;
G4PhysicsVector* v1 = RetrieveVector(ost1, false);
data->AddComponent(Z, A, v1);
}
}
// smooth transition
G4double emax = v->GetMaxEnergy();
G4double sig1 = (*v)[v->GetVectorLength() - 1];
dynParticle->SetKineticEnergy(emax);
G4double sig1 = (*v)[v->GetVectorLength()-1];
dp->SetKineticEnergy(v->GetMaxEnergy());
G4double sig2 = 0.0;
if(1 == Z) {
fNucleon->GetHadronNucleonXscPDG(dynParticle, proton);
fNucleon->GetHadronNucleonXscPDG(dp, proton);
sig2 = fNucleon->GetInelasticHadronNucleonXsc();
} else {
ggXsection->GetIsoCrossSection(dynParticle, Z, Amean);
G4int Amean =
G4lrint(G4NistManager::Instance()->GetAtomicMassAmu(Z));
ggXsection->GetIsoCrossSection(dp, Z, Amean);
sig2 = ggXsection->GetInelasticGlauberGribovXsc();
}
if(sig2 > 0.) { coeff[Z] = sig1/sig2; }
if(!dp) { delete dynParticle; }
}
G4PhysicsVector*
G4NeutronInelasticXS::RetrieveVector(std::ostringstream& ost, G4bool warn)
{
G4PhysicsLogVector* v = 0;
G4PhysicsLogVector* v = nullptr;
std::ifstream filein(ost.str().c_str());
if (!(filein)) {
if(warn) {
@@ -0,0 +1,439 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// $Id: G4ParticleInelasticXS.cc 109964 2018-05-11 17:48:23Z vnivanch $
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
//
// File name: G4ParticleInelasticXS
//
// Author Ivantchenko, Geant4, 3-Aug-09
//
// Modifications:
//
#include "G4ParticleInelasticXS.hh"
#include "G4Neutron.hh"
#include "G4DynamicParticle.hh"
#include "G4Element.hh"
#include "G4ElementTable.hh"
#include "G4PhysicsLogVector.hh"
#include "G4PhysicsVector.hh"
#include "G4ComponentGGHadronNucleusXsc.hh"
#include "G4ComponentGGNuclNuclXsc.hh"
#include "G4HadronNucleonXsc.hh"
#include "G4NistManager.hh"
#include "G4Proton.hh"
#include "Randomize.hh"
#include <iostream>
#include <fstream>
#include <sstream>
using namespace std;
const G4int G4ParticleInelasticXS::amin[] = {
0,
1, 4, 6, 9, 10, 12, 14, 16, 19, 20, //1-10
23, 24, 27, 28, 31, 32, 35, 36, 39, 40, //11-20
45, 46, 50, 50, 55, 54, 59, 58, 63, 64, //21-30
69, 70, 75, 0, 0, 0, 0, 0, 0, 90, //31-40
0, 92, 0, 0, 0, 102, 107, 106, 113, 112, //41-50
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //51-60
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //61-70
0, 0, 181, 180, 0, 0, 0, 192, 197, 0, //71-80
0, 204, 209, 0, 0, 0, 0, 0, 0, 0, //81-90
0, 235};
const G4int G4ParticleInelasticXS::amax[] = {
0,
1, 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
0, 100, 0, 0, 0, 110, 109, 116, 115, 124, //41-50
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //51-60
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //61-70
0, 0, 181, 186, 0, 0, 0, 198, 197, 0, //71-80
0, 208, 209, 0, 0, 0, 0, 0, 0, 0, //81-90
0, 238};
G4double G4ParticleInelasticXS::coeff[] = {1.0};
G4ElementData* G4ParticleInelasticXS::data = nullptr;
#ifdef G4MULTITHREADED
G4Mutex G4ParticleInelasticXS::particleInelasticXSMutex = G4MUTEX_INITIALIZER;
#endif
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)
{
if(!part) {
G4Exception("G4ParticleInelasticXS::G4ParticleInelasticXS(..)","had015",
FatalException, "NO particle definition in constructor");
} else {
// verboseLevel = 0;
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);
}
G4ParticleInelasticXS::~G4ParticleInelasticXS()
{
//G4cout << "G4ParticleInelasticXS::~G4ParticleInelasticXS() "
// << " isMaster= " << isMaster << " data: " << data << G4endl;
delete fNucleon;
delete ggXsection;
delete nnXsection;
if(isMaster) { delete data; data = nullptr; }
}
void G4ParticleInelasticXS::CrossSectionDescription(std::ostream& outFile) const
{
outFile << "G4ParticleInelasticXS calculates n, p, d, t, he3, he4 inelastic \n"
<< "cross section on nuclei using data from the high precision\n"
<< "neutron database. These data are simplified and smoothed over\n"
<< "the resonance region in order to reduce CPU time.\n"
<< "For high energy Glauber-Gribov cross section model is used\n";
}
G4bool
G4ParticleInelasticXS::IsElementApplicable(const G4DynamicParticle*,
G4int, const G4Material*)
{
return true;
}
G4bool
G4ParticleInelasticXS::IsIsoApplicable(const G4DynamicParticle*,
G4int, G4int,
const G4Element*, const G4Material*)
{
return true;
}
G4double G4ParticleInelasticXS::GetElementCrossSection(
const G4DynamicParticle* aParticle,
G4int ZZ, const G4Material*)
{
G4double xs = 0.0;
G4double ekin = aParticle->GetKineticEnergy();
G4int Z = (ZZ >= MAXZINELP) ? MAXZINELP - 1 : ZZ;
G4PhysicsVector* pv = data->GetElementData(Z);
// G4cout << "G4ParticleInelasticXS::GetCrossSection e= " << ekin
// << " Z= " << Z << G4endl;
// element was not initialised or below threshold
if(!pv || ekin <= pv->Energy(0)) { return xs; }
if(ekin <= pv->GetMaxEnergy()) {
xs = pv->Value(ekin);
} else if(1 == Z && fNucleon) {
fNucleon->GetHadronNucleonXscPDG(aParticle, proton);
xs = coeff[1]*fNucleon->GetInelasticHadronNucleonXsc();
} else if(ggXsection) {
G4int Amean =
G4lrint(G4NistManager::Instance()->GetAtomicMassAmu(Z));
ggXsection->GetIsoCrossSection(aParticle, Z, Amean);
xs = coeff[Z]*ggXsection->GetInelasticGlauberGribovXsc();
} else if(nnXsection) {
G4int Amean =
G4lrint(G4NistManager::Instance()->GetAtomicMassAmu(Z));
nnXsection->GetZandACrossSection(aParticle, Z, Amean);
xs = coeff[Z]*nnXsection->GetInelasticGlauberGribovXsc();
}
if(verboseLevel > 0) {
G4cout << "ElmXS: Z= " << Z << " Ekin(MeV)= " << ekin/CLHEP::MeV
<< " xs(bn)= " << xs/CLHEP::barn << " element data for "
<< particleName << G4endl;
}
return xs;
}
G4double G4ParticleInelasticXS::GetIsoCrossSection(
const G4DynamicParticle* aParticle,
G4int Z, G4int A,
const G4Isotope*, const G4Element*,
const G4Material*)
{
return IsoCrossSection(aParticle->GetKineticEnergy(), Z, A);
}
G4double
G4ParticleInelasticXS::IsoCrossSection(G4double ekin, G4int ZZ, G4int A)
{
G4double xs = 0.0;
G4int Z = (ZZ >= MAXZINELP) ? MAXZINELP - 1 : ZZ;
/*
G4cout << "IsoCrossSection Z= " << Z << " A= " << 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;
}
}
// 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
<< " Target Z= " << Z << " A= " << A
<< " Ekin(MeV)= " << ekin/CLHEP::MeV
<< " xs(bn)= " << xs/CLHEP::barn << G4endl;
}
return xs;
}
const G4Isotope* G4ParticleInelasticXS::SelectIsotope(
const G4Element* anElement, G4double kinEnergy)
{
size_t nIso = anElement->GetNumberOfIsotopes();
const G4Isotope* iso = anElement->GetIsotope(0);
//G4cout << "SelectIsotope NIso= " << nIso << G4endl;
if(1 == nIso) { return iso; }
// more than 1 isotope
G4int Z = anElement->GetZasInt();
//G4cout << "SelectIsotope Z= " << Z << G4endl;
const G4double* abundVector = anElement->GetRelativeAbundanceVector();
G4double q = G4UniformRand();
G4double sum = 0.0;
// is there isotope wise cross section?
size_t j;
if(kinEnergy > emax || 0 == amin[Z] || Z >= MAXZINELP) {
for (j = 0; j<nIso; ++j) {
sum += abundVector[j];
if(q <= sum) {
iso = anElement->GetIsotope(j);
break;
}
}
return iso;
}
size_t nn = temp.size();
if(nn < nIso) { temp.resize(nIso, 0.); }
for (j=0; j<nIso; ++j) {
//G4cout << j << "-th isotope " << (*isoVector)[j]->GetN()
// << " abund= " << abundVector[j] << G4endl;
sum += abundVector[j]*IsoCrossSection(kinEnergy, Z,
anElement->GetIsotope(j)->GetN());
temp[j] = sum;
}
sum *= q;
for (j = 0; j<nIso; ++j) {
if(temp[j] >= sum) {
iso = anElement->GetIsotope(j);
break;
}
}
return iso;
}
void
G4ParticleInelasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
{
if(verboseLevel > 0){
G4cout << "G4ParticleInelasticXS::BuildPhysicsTable for "
<< p.GetParticleName() << G4endl;
}
if(&p != particle) {
G4ExceptionDescription ed;
ed << p.GetParticleName() << " is a wrong particle type -"
<< particleName << " is expected";
G4Exception("G4ParticleInelasticXS::BuildPhysicsTable(..)","had012",
FatalException, ed, "");
return;
}
if(!data) {
#ifdef G4MULTITHREADED
G4MUTEXLOCK(&particleInelasticXSMutex);
if(!data) {
#endif
isMaster = true;
data = new G4ElementData();
data->SetName(particleName + "Inelastic");
temp.resize(13,0.0);
#ifdef G4MULTITHREADED
}
G4MUTEXUNLOCK(&particleInelasticXSMutex);
#endif
}
// it is possible re-initialisation for the new run
if(isMaster) {
// check environment variable
// Build the complete string identifying the file with the data set
char* path = getenv("G4NEUTRONXSDATA");
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);
}
}
delete dynParticle;
}
}
void G4ParticleInelasticXS::Initialise(G4int Z, G4DynamicParticle* dp,
const char* p)
{
if(data->GetElementData(Z)) { return; }
const char* path = p;
if(!p) {
// check environment variable
// Build the complete string identifying the file with the data set
path = getenv("G4NEUTRONXSDATA");
if (!path) {
G4Exception("G4ParticleInelasticXS::Initialise(..)","had013",
FatalException,
"Environment variable G4NEUTRONXSDATA is not defined");
return;
}
}
// upload element data
std::ostringstream ost;
ost << path << "/" << particleName << "/inel" << Z ;
G4PhysicsVector* v = RetrieveVector(ost, true);
data->InitialiseForElement(Z, v);
/*
G4cout << "G4ParticleInelasticXS::Initialise for Z= " << Z
<< " A= " << Amean << " Amin= " << amin[Z]
<< " Amax= " << amax[Z] << G4endl;
*/
// upload isotope data
if(amin[Z] > 0) {
size_t nmax = (size_t)(amax[Z]-amin[Z]+1);
data->InitialiseForComponent(Z, nmax);
for(G4int A=amin[Z]; A<=amax[Z]; ++A) {
std::ostringstream ost1;
ost1 << path << "/neutron/inel" << Z << "_" << A;
G4PhysicsVector* v1 = RetrieveVector(ost1, false);
data->AddComponent(Z, A, v1);
}
}
// smooth transition
G4double sig1 = (*v)[v->GetVectorLength()-1];
dp->SetKineticEnergy(v->GetMaxEnergy());
G4double sig2 = 0.0;
G4int Amean =
G4lrint(G4NistManager::Instance()->GetAtomicMassAmu(Z));
if(1 == Z && fNucleon) {
fNucleon->GetHadronNucleonXscPDG(dp, proton);
sig2 = fNucleon->GetInelasticHadronNucleonXsc();
} else if(ggXsection) {
ggXsection->GetIsoCrossSection(dp, Z, Amean);
sig2 = ggXsection->GetInelasticGlauberGribovXsc();
} else if(nnXsection) {
nnXsection->GetZandACrossSection(dp, Z, Amean);
sig2 = nnXsection->GetInelasticGlauberGribovXsc();
}
if(sig2 > 0.) { coeff[Z] = sig1/sig2; }
}
G4PhysicsVector*
G4ParticleInelasticXS::RetrieveVector(std::ostringstream& ost, G4bool warn)
{
G4PhysicsLogVector* v = nullptr;
std::ifstream filein(ost.str().c_str());
if (!(filein)) {
if(warn) {
G4ExceptionDescription ed;
ed << "Data file <" << ost.str().c_str()
<< "> is not opened!";
G4Exception("G4ParticleInelasticXS::RetrieveVector(..)","had014",
FatalException, ed, "Check G4NEUTRONXSDATA");
}
} else {
if(verboseLevel > 1) {
G4cout << "File " << ost.str()
<< " is opened by G4ParticleInelasticXS" << G4endl;
}
// retrieve data from DB
v = new G4PhysicsLogVector();
if(!v->Retrieve(filein, true)) {
G4ExceptionDescription ed;
ed << "Data file <" << ost.str().c_str()
<< "> is not retrieved!";
G4Exception("G4ParticleInelasticXS::RetrieveVector(..)","had015",
FatalException, ed, "Check G4NEUTRONXSDATA");
}
}
return v;
}
@@ -48,7 +48,7 @@ G4_DECLARE_XS_FACTORY(G4PiNuclearCrossSection);
// 22 Dec 2006 - D.H. Wright added isotope dependence
//
// 19 Aug 2011, V.Ivanchenko move to new design and make x-section per element
const G4double G4PiNuclearCrossSection::e1[38] = {
.02, .04, .06, .08, .1, .12, .13, .14, .15, .16, .17, .18, .19, .20,
.22, .24, .26, .28, .30, .35, .40, .45, 0.5, 0.55, 0.6, 0.7, 0.8, 0.9,
@@ -492,10 +492,38 @@ G4PiNuclearCrossSection::GetElementCrossSection(const G4DynamicParticle* particl
// debug.push_back(theZ[it]);
// debug.push_back(kineticEnergy);
if(Z > theZ[it])
if( it == theZ.size() )
{
throw G4HadronicException(__FILE__, __LINE__,
"Called G4PiNuclearCrossSection outside parametrization");
//AR-24Apr2018 Switch to treat transuranic elements as uranium
const G4bool isHeavyElementAllowed = true;
if ( isHeavyElementAllowed ) {
it--;
if ( Z > 100 ) Z = 100; // 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
// Notes:
// - The exponent "0.75" is used to be consistent with the method
// G4PiNuclearCrossSection::Interpolate (otherwise I would use 2/3);
// - We use for Uranium 238.02891 and for the transuranic elements
// the values showed below in the comment.
const std::vector<G4double> vecScaling{ 0.996756, // <A>=237.0 for Np (Z=93)
1.018756, // <A>=244.0 for Pu (Z=94)
1.015623, // <A>=243.0 for Am (Z=95)
1.028136, // <A>=247.0 for Cm (Z=96)
1.028136, // <A>=247.0 for Bk (Z=97)
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;
return result;
} else {
throw G4HadronicException(__FILE__, __LINE__,
"Called G4PiNuclearCrossSection outside parametrization");
}
}
G4int Z1, Z2;
G4double x1, x2, xt1, xt2;
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4VCrossSectionDataSet.cc 98738 2016-08-09 12:53:25Z gcosmo $
// $Id: G4VCrossSectionDataSet.cc 110787 2018-06-14 06:43:31Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -52,7 +52,8 @@
#include "Randomize.hh"
G4VCrossSectionDataSet::G4VCrossSectionDataSet(const G4String& nam) :
verboseLevel(0),minKinEnergy(0.0),maxKinEnergy(100*TeV),name(nam)
verboseLevel(0),minKinEnergy(0.0),maxKinEnergy(100*TeV),
isForAllAtomsAndEnergies(false),name(nam)
{
registry = G4CrossSectionDataSetRegistry::Instance();
registry->Register(this);
@@ -85,7 +86,7 @@ G4VCrossSectionDataSet::ComputeCrossSection(const G4DynamicParticle* part,
const G4Element* elm,
const G4Material* mat)
{
G4int Z = G4lrint(elm->GetZ());
G4int Z = elm->GetZasInt();
if (IsElementApplicable(part, Z, mat)) {
return GetElementCrossSection(part, Z, mat);
@@ -97,35 +98,18 @@ G4VCrossSectionDataSet::ComputeCrossSection(const G4DynamicParticle* part,
G4int nIso = elm->GetNumberOfIsotopes();
G4double fact = 0.0;
G4double xsec = 0.0;
G4Isotope* iso = 0;
const G4Isotope* iso = nullptr;
if (0 < nIso) {
// user-defined isotope abundances
const G4IsotopeVector* isoVector = elm->GetIsotopeVector();
const G4double* abundVector = elm->GetRelativeAbundanceVector();
// user-defined isotope abundances
G4IsotopeVector* isoVector = elm->GetIsotopeVector();
G4double* abundVector = elm->GetRelativeAbundanceVector();
for (G4int 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);
}
}
} else {
// natural isotope abundances
G4NistManager* nist = G4NistManager::Instance();
G4int n0 = nist->GetNistFirstIsotopeN(Z);
G4int nn = nist->GetNumberOfNistIsotopes(Z);
for (G4int A = n0; A < n0+nn; ++A) {
G4double abund = nist->GetIsotopeAbundance(Z, A);
if(abund > 0.0 && IsIsoApplicable(part, Z, A, elm, mat)) {
fact += abund;
xsec += abund*GetIsoCrossSection(part, Z, A, iso, elm, mat);
}
for (G4int 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; }
@@ -165,22 +149,21 @@ G4VCrossSectionDataSet::GetIsoCrossSection(const G4DynamicParticle* dynPart,
"G4VCrossSectionDataSet::GetIsoCrossSection is absent");
}
G4Isotope*
const G4Isotope*
G4VCrossSectionDataSet::SelectIsotope(const G4Element* anElement, G4double)
{
G4int nIso = anElement->GetNumberOfIsotopes();
G4IsotopeVector* isoVector = anElement->GetIsotopeVector();
G4Isotope* iso = (*isoVector)[0];
const G4Isotope* iso = anElement->GetIsotope(0);
// more than 1 isotope
if(1 < nIso) {
G4double* abundVector = anElement->GetRelativeAbundanceVector();
const G4double* abundVector = anElement->GetRelativeAbundanceVector();
G4double sum = 0.0;
G4double q = G4UniformRand();
for (G4int j = 0; j<nIso; ++j) {
sum += abundVector[j];
if(q <= sum) {
iso = (*isoVector)[j];
iso = anElement->GetIsotope(j);
break;
}
}