61 nDataSetList(0), verboseLevel(0),fastPathFlags(),fastPathParams(),
62 counters(),fastPathCache()
65 currentMaterial = elmMaterial =
nullptr;
66 currentElement =
nullptr;
67 matParticle = elmParticle =
nullptr;
68 matKinEnergy = elmKinEnergy = matCrossSection = elmCrossSection = 0.0;
134 requiresSlowPath=
true;
153 if(mat == currentMaterial && part->
GetDefinition() == matParticle
156 G4FastPathHadronicCrossSection::logInvocationTriedOneLine(entry);
160 return matCrossSection;
168 G4FastPathHadronicCrossSection::logInvocationOneLine(entry);
170 return matCrossSection;
174 requiresSlowPath =
true;
185 G4FastPathHadronicCrossSection::logHit(entry);
186 if ( !requiresSlowPath ) {
191 currentMaterial = mat;
198 if ( entry !=
nullptr && ! requiresSlowPath ) {
207 assert(requiresSlowPath==
false);
208 requiresSlowPath =
true;
212 if ( !requiresSlowPath && fast_entry !=
nullptr ) {
226 if(
G4int(xsecelm.size()) < nElements) { xsecelm.resize(nElements); }
228 for(
G4int i=0; i<nElements; ++i) {
229 matCrossSection += nAtomsPerVolume[i] *
231 xsecelm[i] = matCrossSection;
237 if ( entry !=
nullptr ) {
242 G4FastPathHadronicCrossSection::logTiming(entry,fast_entry,timing);
243 return matCrossSection;
252 if ( entry !=
nullptr ) {
256 os<<
"#Cache entry for {"<<(pd!=
nullptr?pd->
GetParticleName():
"UNDEFINED")<<
",";
257 os<<(mat!=
nullptr?mat->
GetName():
"UNDEFINED")<<
"} found, but no fast path defined";
260 os<<
"#Cache entry for {"<<(pd!=
nullptr?pd->
GetParticleName():
"UNDEFINED")<<
",";
261 os<<(mat!=
nullptr?mat->
GetName():
"UNDEFINED")<<
"} not found.";
271 if(mat == currentMaterial && part->
GetDefinition() == matParticle
273 return matCrossSection;
275 currentMaterial = mat;
278 matCrossSection = 0.0;
283 if(xsecelm.size() < nElements) { xsecelm.resize(nElements); }
285 for(
size_t i=0; i<nElements; ++i) {
286 matCrossSection += nAtomsPerVolume[i] *
288 xsecelm[i] = matCrossSection;
290 return matCrossSection;
300 if(mat == elmMaterial && elm == currentElement &&
303 {
return elmCrossSection; }
306 currentElement = elm;
309 elmCrossSection = 0.0;
311 G4int i = nDataSetList-1;
314 dataSetList[i]->IsElementApplicable(part, Z, mat)) {
317 elmCrossSection = dataSetList[i]->GetElementCrossSection(part, Z, mat);
332 for (
size_t j=0; j<nIso; ++j) {
333 if(abundVector[j] > 0.0) {
335 elmCrossSection += abundVector[j]*
336 GetIsoCrossSection(part, Z, iso->
GetN(), iso, elm, mat, i);
346 return elmCrossSection;
363 if(dataSetList[idx]->IsIsoApplicable(part, Z, A, elm, mat) ) {
364 return dataSetList[idx]->GetIsoCrossSection(part, Z, A, iso, elm, mat);
368 for (
G4int j = nDataSetList-1; j >= 0; --j) {
369 if (dataSetList[j]->IsElementApplicable(part, Z, mat)) {
370 return dataSetList[j]->GetElementCrossSection(part, Z, mat);
371 }
else if (dataSetList[j]->IsIsoApplicable(part, Z, A, elm, mat)) {
372 return dataSetList[j]->GetIsoCrossSection(part, Z, A, iso, elm, mat);
377 ed <<
"No isotope cross section found for "
379 <<
" off Element " << elm->
GetName()
380 <<
" in " << mat->
GetName() <<
" Z= " << Z <<
" A= " <<
A
382 G4Exception(
"G4CrossSectionDataStore::GetIsoCrossSection",
"had001",
396 for (
G4int i = nDataSetList-1; i >= 0; --i) {
397 if (dataSetList[i]->IsIsoApplicable(part, Z,
A, elm, mat) ) {
398 return dataSetList[i]->GetIsoCrossSection(part, Z,
A, iso, elm, mat);
402 ed <<
"No isotope cross section found for "
404 <<
" off Element " << elm->
GetName()
405 <<
" in " << mat->
GetName() <<
" Z= " << Z <<
" A= " <<
A
407 G4Exception(
"G4CrossSectionDataStore::GetCrossSection",
"had001",
425 for(
size_t i=0; i<nElements; ++i) {
426 if(cross <= xsecelm[i]) {
436 G4int i = nDataSetList-1;
437 if (dataSetList[i]->IsElementApplicable(part, Z, mat)) {
448 iso = dataSetList[i]->SelectIsotope(anElement,
464 if(xseciso.size() < nIso) { xseciso.resize(nIso); }
468 for (j = 0; j<nIso; ++j) {
470 if(abundVector[j] > 0.0) {
472 xsec = abundVector[j]*
473 GetIsoCrossSection(part, Z, iso->
GetN(), iso, anElement, mat, i);
479 for (j = 0; j<nIso; ++j) {
480 if(cross <= xseciso[j]) {
496 if (nDataSetList == 0) {
498 ed <<
"No cross section is registered for "
500 G4Exception(
"G4CrossSectionDataStore::BuildPhysicsTable",
"had001",
504 for (
G4int i=0; i<nDataSetList; ++i) {
505 dataSetList[i]->BuildPhysicsTable(aParticleType);
511 using my_value_type=G4FastPathHadronicCrossSection::G4CrossSectionDataStore_Requests::value_type;
513 std::for_each( requests.begin() , requests.end() ,
514 [&aParticleType,
this](
const my_value_type& req) {
515 if ( aParticleType == *req.part_mat.first ) {
516 G4FastPathHadronicCrossSection::cycleCountEntry* entry =
517 new G4FastPathHadronicCrossSection::cycleCountEntry(aParticleType.GetParticleName(),req.part_mat.second);
519 new G4FastPathHadronicCrossSection::fastPathEntry(&aParticleType,req.part_mat.second,req.min_cutoff);
520 entry->fastPath->Initialize(this);
521 fastPathCache[req.part_mat] = entry;
534 assert(pdef!=
nullptr&&mat!=
nullptr);
536 if ( requests.insert( { key , min_cutoff } ).second ) {
538 ed <<
"Attempting to request FastPath for couple: <"
540 <<
"> but combination already exists" <<
G4endl;
541 G4Exception(
"G4CrossSectionDataStore::ActivateFastPath",
"had001",
554 if (nDataSetList == 0) {
555 G4cout <<
"WARNING - G4CrossSectionDataStore::DumpPhysicsTable: "
556 <<
" no data sets registered" <<
G4endl;
560 for (
G4int i = nDataSetList-1; i >= 0; --i) {
561 G4double e1 = dataSetList[i]->GetMinKinEnergy();
562 G4double e2 = dataSetList[i]->GetMaxKinEnergy();
564 <<
" Cr_sctns: " << std::setw(25) << dataSetList[i]->GetName() <<
": "
568 if (dataSetList[i]->GetName() ==
"G4CrossSectionPairGG") {
569 dataSetList[i]->DumpPhysicsTable(aParticleType);
577 std::ofstream& outFile)
const
584 G4String physListName(std::getenv(
"G4PhysListName"));
585 for (
G4int i = nDataSetList-1; i > 0; i--) {
586 elo = dataSetList[i]->GetMinKinEnergy()/GeV;
587 ehi = dataSetList[i]->GetMaxKinEnergy()/GeV;
588 outFile <<
" <li><b><a href=\"" << physListName <<
"_"
589 << dataSetList[i]->GetName() <<
".html\"> "
590 << dataSetList[i]->GetName() <<
"</a> from "
591 << elo <<
" GeV to " << ehi <<
" GeV </b></li>\n";
597 G4double defaultHi = dataSetList[0]->GetMaxKinEnergy()/GeV;
598 if (ehi < defaultHi) {
599 outFile <<
" <li><b><a href=\"" << dataSetList[0]->GetName() <<
".html\"> "
600 << dataSetList[0]->GetName() <<
"</a> from "
601 << ehi <<
" GeV to " << defaultHi <<
" GeV </b></li>\n";
610 G4String dirName(std::getenv(
"G4PhysListDocDir"));
611 G4String physListName(std::getenv(
"G4PhysListName"));
613 G4String pathName = dirName +
"/" + physListName +
"_" + HtmlFileName(cs->
GetName());
615 outCS.open(pathName);
618 outCS <<
"<title>Description of " << cs->
GetName()
620 outCS <<
"</head>\n";
625 outCS <<
"</body>\n";
626 outCS <<
"</html>\n";
635 std::transform(str.begin(), str.end(), str.begin(), [](
char ch) {
636 return ch ==
' ' ?
'_' : ch;
650 dataSetList.push_back(p);
662 dataSetList.push_back(p);
665 if ( i > dataSetList.size() ) i = dataSetList.size();
666 std::vector< G4VCrossSectionDataSet* >::iterator it = dataSetList.end() - i;
667 dataSetList.insert(it , p);
double A(double temperature)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
G4GLOB_DLL std::ostream G4cout
void DumpHtml(const G4ParticleDefinition &, std::ofstream &) const
void BuildPhysicsTable(const G4ParticleDefinition &)
void AddDataSet(G4VCrossSectionDataSet *)
void PrintCrossSectionHtml(const G4VCrossSectionDataSet *cs) const
void DumpPhysicsTable(const G4ParticleDefinition &)
~G4CrossSectionDataStore()
G4double ComputeCrossSection(const G4DynamicParticle *, const G4Material *)
void DumpFastPath(const G4ParticleDefinition *, const G4Material *, std::ostream &os)
void ActivateFastPath(const G4ParticleDefinition *, const G4Material *, G4double)
G4double GetCrossSection(const G4DynamicParticle *, const G4Material *)
G4CrossSectionDataStore()
const G4Element * SampleZandA(const G4DynamicParticle *, const G4Material *, G4Nucleus &target)
G4double GetLogKineticEnergy() const
const G4ParticleDefinition * GetParticleDefinition() const
G4ParticleDefinition * GetDefinition() const
G4double GetKineticEnergy() const
G4double * GetRelativeAbundanceVector() const
G4bool GetNaturalAbundanceFlag() const
const G4Isotope * GetIsotope(G4int iso) const
size_t GetNumberOfIsotopes() const
const G4String & GetName() const
const G4ElementVector * GetElementVector() const
const G4Element * GetElement(G4int iel) const
size_t GetNumberOfElements() const
const G4double * GetVecNbOfAtomsPerVolume() const
const G4String & GetName() const
static G4NistManager * Instance()
void SetIsotope(const G4Isotope *iso)
const G4String & GetParticleName() const
bool ForAllAtomsAndEnergies() const
const G4String & GetName() const
virtual void CrossSectionDescription(std::ostream &) const
void logStopCountCycles(timing &)
std::pair< const G4ParticleDefinition *, const G4Material * > G4CrossSectionDataStore_Key
void logStartCountCycles(timing &)
G4bool prevCalcUsedFastPath
G4bool useFastPathIfAvailable
G4bool initializationPhase
G4double GetCrossSection(G4double ene) const
const G4double min_cutoff