Import Geant4 11.2.1 source tree

This commit is contained in:
Gabriele Cosmo
2024-02-16 14:58:45 +01:00
parent 860a2b92bf
commit dda54bbdcf
331 changed files with 48457 additions and 50699 deletions
+8
View File
@@ -6,6 +6,14 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2023-12-22 Evgueni Tcherniaev (geom-csg-V11-01-02)
- Use GetThetaCosPhi() and GetThetaSinPhi() in wrapper method G4UTrap::GetVertices(),
this fixes the problem with trapezoid arised in CMSSW after migration to VecGeom 1.2.6
## 2023-12-18 Gabriele Cosmo
- Fixed typo in wrapper method G4UTrap::SetAllParameters(), setter used in
parameterisation of shape dimensions.
## 2023-05-10 Gabriele Cosmo (geom-csg-V11-01-01)
- Applied clang-tidy fixes (readability, modernization, performance, ...).
+4 -6
View File
@@ -25,7 +25,7 @@
//
// Implementation for G4UTrap wrapper class
//
// 13.09.13 G.Cosmo, CERN/PH
// 13.09.13 G.Cosmo, CERN
// --------------------------------------------------------------------
#include "G4Trap.hh"
@@ -268,7 +268,7 @@ void G4UTrap::SetAllParameters(G4double pDz, G4double pTheta, G4double pPhi,
SetDx3(pDx3);
SetDx4(pDx4);
SetTanAlpha1(std::tan(pAlp1));
SetTanAlpha1(std::tan(pAlp2));
SetTanAlpha2(std::tan(pAlp2));
// last two will also reset cached variables
SetTheta(pTheta);
SetPhi(pPhi);
@@ -336,13 +336,11 @@ void G4UTrap::GetVertices(G4ThreeVector pt[8]) const
G4double fDy2 = GetYHalfLength2();
G4double fDx3 = GetXHalfLength3();
G4double fDx4 = GetXHalfLength4();
G4double phi = GetPhi();
G4double theta = GetTheta();
G4double fTalpha1 = GetTanAlpha1();
G4double fTalpha2 = GetTanAlpha2();
G4double DzTthetaCphi = fDz*std::tan(theta)*std::cos(phi);
G4double DzTthetaSphi = fDz*std::tan(theta)*std::sin(phi);
G4double DzTthetaCphi = fDz*GetTanThetaCosPhi();
G4double DzTthetaSphi = fDz*GetTanThetaSinPhi();
G4double Dy1Talpha1 = fDy1*fTalpha1;
G4double Dy2Talpha2 = fDy2*fTalpha2;
+3
View File
@@ -6,6 +6,9 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2023-12-21 Yoshihide Sato (global-V11-01-27)
- G4PhysicsModelCatalog.cc: added the ID for the Light-Ion QMD model.
## 2023-11-23 Gabriele Cosmo (global-V11-01-26)
- Updated tag IDs for geant4-11-02-ref-00.
@@ -43,7 +43,7 @@
/// |--> patch number (single digit)
///
#ifndef G4VERSION_NUMBER
#define G4VERSION_NUMBER 1120
#define G4VERSION_NUMBER 1121
#endif
/// @def G4VERSION_REFERENCE_TAG
@@ -59,7 +59,7 @@
#endif
#ifndef G4VERSION_TAG
#define G4VERSION_TAG "$Name: geant4-11-02 $"
#define G4VERSION_TAG "$Name: geant4-11-02-patch-01 $"
#endif
// as variables
@@ -68,10 +68,10 @@
#include "G4Types.hh"
#ifdef G4MULTITHREADED
static const G4String G4Version = "$Name: geant4-11-02 [MT]$";
static const G4String G4Version = "$Name: geant4-11-02-patch-01 [MT]$";
#else
static const G4String G4Version = "$Name: geant4-11-02 $";
static const G4String G4Version = "$Name: geant4-11-02-patch-01 $";
#endif
static const G4String G4Date = "(8-December-2023)";
static const G4String G4Date = "(16-February-2024)";
#endif
@@ -596,6 +596,9 @@ void G4PhysicsModelCatalog::Initialize() {
InsertModel( 26041, "model_hINCLXXCaptureAtRest_NuclearCapture" );
InsertModel( 26042, "model_hINCLXXCaptureAtRest_DIO" );
// Class: G4LightIonQMDReaction
InsertModel( 23310, "model_LightIonQMDModel" );
// ...
SanityCheck();
@@ -6,6 +6,15 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2024-02-07 Vladimir Ivanchenko (phys-ctor-em-V11-01-14)
- G4EmStandardPhysics_option3 - return back step limit type to
fUseDistanceToBoundary and the default RangeFactor 0.04 from 0.03,
which will allow to restore more accurate distributions for several
tests for medical benchmark
## 2024-02-04 Vladimir Ivanchenko
- G4GammaGeneralProcess - fixed sampling of muon pair production - problem 2543
## 2023-11-09 Hoang Tran (phys-ctor-em-V11-01-13)
- Correct subtype process of G4LowECapture in G4EmDNABuilder .
@@ -115,8 +115,7 @@ G4EmStandardPhysics_option3::G4EmStandardPhysics_option3(G4int ver,
param->SetStepFunctionMuHad(0.2, 50*CLHEP::um);
param->SetStepFunctionLightIons(0.1, 20*CLHEP::um);
param->SetStepFunctionIons(0.1, 1*CLHEP::um);
param->SetMscStepLimitType(fUseSafetyPlus);
param->SetMscRangeFactor(0.03);
param->SetMscStepLimitType(fUseDistanceToBoundary);
param->SetMuHadLateralDisplacement(true);
param->SetLateralDisplacementAlg96(true);
param->SetUseICRU90Data(true);
@@ -433,7 +433,7 @@ void G4GammaGeneralProcess::BuildPhysicsTable(const G4ParticleDefinition& part)
val = (sigN + sigM)/sum;
(*(tables[13]))[idx]->PutValue(j, val);
val = sigN/sum;
val = sigM/sum;
(*(tables[14]))[idx]->PutValue(j, val);
}
for(std::size_t k=0; k<nTables; ++k) {
@@ -6,6 +6,9 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2024-02-13 Vladimir Ivanchenko (phys-ctor-glnuclear-V11-01-05)
- G4NeutrinoPhysics - fixed neutrino physics instantiation (problem #2594)
## 2023-11-10 Vladimir Ivanchenko (phys-ctor-glnuclear-V11-01-04)
- G4EmMessenger, G4NeutrinoPhysicsMessenger - fixed typos
@@ -239,7 +239,7 @@ void G4NeutrinoPhysics::ConstructProcess()
theNuTauNucleusProcess->RegisterMe(anutaunuclnc);
for (G4int i=4; i<=5; ++i) {
p[i]->GetProcessManager()->AddDiscreteProcess(theNuMuNucleusProcess);
p[i]->GetProcessManager()->AddDiscreteProcess(theNuTauNucleusProcess);
}
// nu_e nucleus interactions
@@ -6,6 +6,11 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2023-12-11 V. Ivanchenko (emlowen-V11-01-12)
- G4MicroElecInelasticModel_new - fixed Coverity report on memory leak at exit,
minimal code clean-up.
- G4MicroElecLOPhononModel - minor clean-up
# 2023-11-06 Ben Morgan (emlowen-V11-01-11)
- Use G4FindDataDir to access data libraries in place of raw `getenv`.
@@ -127,9 +127,6 @@ public:
G4MicroElecInelasticModel_new & operator=(const G4MicroElecInelasticModel_new &right) = delete;
G4MicroElecInelasticModel_new(const G4MicroElecInelasticModel_new&) = delete;
protected:
G4ParticleChangeForGamma* fParticleChangeForGamma = nullptr;
private:
//
@@ -157,6 +154,8 @@ private:
//
// private elements
//
G4ParticleChangeForGamma* fParticleChangeForGamma = nullptr;
//deexcitation manager to produce fluo photns and e-
G4VAtomDeexcitation* fAtomDeexcitation = nullptr;
G4Material* nistSi = nullptr;
@@ -78,12 +78,9 @@ class G4MicroElecLOPhononModel : public G4VEmModel
G4MicroElecLOPhononModel& operator=(const G4MicroElecLOPhononModel&) = delete;
G4MicroElecLOPhononModel(const G4MicroElecLOPhononModel&) = delete;
protected:
G4ParticleChangeForGamma* fParticleChangeForGamma;
private:
G4ParticleChangeForGamma* fParticleChangeForGamma = nullptr;
G4double phononEnergy = 0.;
G4bool Interband = false;
G4bool isInitialised = false;
@@ -131,19 +131,27 @@ G4MicroElecInelasticModel_new::~G4MicroElecInelasticModel_new()
{
// Cross section
// (0)
TCSMap::iterator pos2;
for (pos2 = tableTCS.begin(); pos2 != tableTCS.end(); ++pos2) {
MapData* tableData = pos2->second;
for (auto pos = tableData->begin(); pos != tableData->end(); ++pos)
{
G4MicroElecCrossSectionDataSet_new* table = pos->second;
delete table;
}
for (auto const& p : tableTCS) {
MapData* tableData = p.second;
for (auto const& pos : *tableData) { delete pos.second; }
delete tableData;
}
tableTCS.clear();
// (1)
for (auto const & obj : eDiffDatatable) {
auto ptr = obj.second;
ptr->clear();
delete ptr;
}
for (auto const & obj : pDiffDatatable) {
auto ptr = obj.second;
ptr->clear();
delete ptr;
}
// (2)
for (auto const & obj : eNrjTransStorage) {
delete obj.second;
}
@@ -151,71 +159,37 @@ G4MicroElecInelasticModel_new::~G4MicroElecInelasticModel_new()
delete obj.second;
}
// (2)
for (auto const & obj : eDiffDatatable) {
delete obj.second;
}
for (auto const & obj : pDiffDatatable) {
delete obj.second;
// (3)
for (auto const& p : eProbaShellStorage) {
delete p.second;
}
// (3)
dataProbaShellMap::iterator iterator_probaShell;
for (iterator_probaShell = eProbaShellStorage.begin(); iterator_probaShell != eProbaShellStorage.end(); ++iterator_probaShell) {
vector<VecMap>* eProbaShellMap = iterator_probaShell->second;
eProbaShellMap->clear();
delete eProbaShellMap;
for (auto const& p : pProbaShellStorage) {
delete p.second;
}
eProbaShellStorage.clear();
for (iterator_probaShell = pProbaShellStorage.begin(); iterator_probaShell != pProbaShellStorage.end(); ++iterator_probaShell) {
vector<VecMap>* pProbaShellMap = iterator_probaShell->second;
pProbaShellMap->clear();
delete pProbaShellMap;
}
pProbaShellStorage.clear();
// (4)
TranfEnergyMap::iterator iterator_nrjtransf;
for (iterator_nrjtransf = eVecmStorage.begin(); iterator_nrjtransf != eVecmStorage.end(); ++iterator_nrjtransf) {
VecMap* eVecm = iterator_nrjtransf->second;
eVecm->clear();
delete eVecm;
for (auto const& p : eIncidentEnergyStorage) {
delete p.second;
}
eVecmStorage.clear();
for (iterator_nrjtransf = pVecmStorage.begin(); iterator_nrjtransf != pVecmStorage.end(); ++iterator_nrjtransf) {
VecMap* pVecm = iterator_nrjtransf->second;
pVecm->clear();
delete pVecm;
for (auto const& p : pIncidentEnergyStorage) {
delete p.second;
}
pVecmStorage.clear();
// (5)
incidentEnergyMap::iterator iterator_energy;
for (iterator_energy = eIncidentEnergyStorage.begin(); iterator_energy != eIncidentEnergyStorage.end(); ++iterator_energy) {
std::vector<G4double>* eTdummyVec = iterator_energy->second;
eTdummyVec->clear();
delete eTdummyVec;
for (auto const& p : eVecmStorage) {
delete p.second;
}
eIncidentEnergyStorage.clear();
for (iterator_energy = pIncidentEnergyStorage.begin(); iterator_energy != pIncidentEnergyStorage.end(); ++iterator_energy) {
std::vector<G4double>* pTdummyVec = iterator_energy->second;
pTdummyVec->clear();
delete pTdummyVec;
for (auto const& p : pVecmStorage) {
delete p.second;
}
pIncidentEnergyStorage.clear();
// (6)
MapStructure::iterator iterator_matStructure;
for (iterator_matStructure = tableMaterialsStructures.begin();
iterator_matStructure != tableMaterialsStructures.end(); ++iterator_matStructure) {
currentMaterialStructure = iterator_matStructure->second;
delete currentMaterialStructure;
for (auto const& p : tableMaterialsStructures) {
delete p.second;
}
tableMaterialsStructures.clear();
currentMaterialStructure = nullptr;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -304,6 +278,7 @@ void G4MicroElecInelasticModel_new::Initialise(const G4ParticleDefinition* parti
// Octobre 22nd, 2014 - Melanie Raine
//Creating vectors of maps for DCS and Cumulated DCS for the current material.
//Each vector is storing one map for each shell.
G4bool isUsed1 = false;
vector<TriDimensionMap>* eDiffCrossSectionData =
new vector<TriDimensionMap>; //Storage of [IncidentEnergy, TransfEnergy, DCS values], used in slower code
vector<TriDimensionMap>* eNrjTransfData =
@@ -312,7 +287,7 @@ void G4MicroElecInelasticModel_new::Initialise(const G4ParticleDefinition* parti
vector<G4double>* eTdummyVec = new vector<G4double>; //Storage of incident energies for interpolation
VecMap* eVecm = new VecMap; //Transfered energy map for slower code
for (int j = 0; j < currentMaterialStructure->NumberOfLevels(); j++) //Filling the map vectors with an empty map for each shell
for (G4int j = 0; j < currentMaterialStructure->NumberOfLevels(); ++j) //Filling the map vectors with an empty map for each shell
{
eDiffCrossSectionData->push_back(TriDimensionMap());
eNrjTransfData->push_back(TriDimensionMap());
@@ -328,7 +303,7 @@ void G4MicroElecInelasticModel_new::Initialise(const G4ParticleDefinition* parti
if (tDummy != eTdummyVec->back()) eTdummyVec->push_back(tDummy);
G4double tmp; //probability
for (int j = 0; j < currentMaterialStructure->NumberOfLevels(); j++)
for (G4int j = 0; j < currentMaterialStructure->NumberOfLevels(); ++j)
{
eDiffCrossSection >> tmp;
(*eDiffCrossSectionData)[j][tDummy][eDummy] = tmp;
@@ -339,16 +314,17 @@ void G4MicroElecInelasticModel_new::Initialise(const G4ParticleDefinition* parti
(*eProbaShellMap)[j][tDummy].push_back((*eDiffCrossSectionData)[j][tDummy][eDummy]);
}
else { // SI - only if eof is not reached !
if (!eDiffCrossSection.eof()) (*eDiffCrossSectionData)[j][tDummy][eDummy] *= scaleFactor;
(*eDiffCrossSectionData)[j][tDummy][eDummy] *= scaleFactor;
(*eVecm)[tDummy].push_back(eDummy);
}
}
}
//
G4cout << "add to material vector" << G4endl;
//G4cout << "add to material vector" << G4endl;
//Filing maps for the current material into the master maps
if (fasterCode) {
isUsed1 = true;
eNrjTransStorage[mat] = eNrjTransfData;
eProbaShellStorage[mat] = eProbaShellMap;
}
@@ -359,9 +335,13 @@ void G4MicroElecInelasticModel_new::Initialise(const G4ParticleDefinition* parti
eIncidentEnergyStorage[mat] = eTdummyVec;
//Cleanup support vectors
// delete eProbaShellMap;
// delete eDiffCrossSectionData;
// delete eNrjTransfData;
if (!isUsed1) {
delete eProbaShellMap;
delete eNrjTransfData;
} else {
delete eDiffCrossSectionData;
delete eVecm;
}
}
// *** PROTON
@@ -403,6 +383,7 @@ void G4MicroElecInelasticModel_new::Initialise(const G4ParticleDefinition* parti
//Creating vectors of maps for DCS and Cumulated DCS for the current material.
//Each vector is storing one map for each shell.
G4bool isUsed1 = false;
vector<TriDimensionMap>* pDiffCrossSectionData =
new vector<TriDimensionMap>; //Storage of [IncidentEnergy, TransfEnergy, DCS values], used in slower code
vector<TriDimensionMap>* pNrjTransfData =
@@ -411,9 +392,9 @@ void G4MicroElecInelasticModel_new::Initialise(const G4ParticleDefinition* parti
new vector<VecMap>; //Storage of the vectors containing all cumulated DCS values for an initial energy, by shell
vector<G4double>* pTdummyVec =
new vector<G4double>; //Storage of incident energies for interpolation
VecMap* eVecm = new VecMap; //Transfered energy map for slower code
VecMap* pVecm = new VecMap; //Transfered energy map for slower code
for (int j = 0; j < currentMaterialStructure->NumberOfLevels(); ++j)
for (G4int j = 0; j < currentMaterialStructure->NumberOfLevels(); ++j)
//Filling the map vectors with an empty map for each shell
{
pDiffCrossSectionData->push_back(TriDimensionMap());
@@ -430,7 +411,7 @@ void G4MicroElecInelasticModel_new::Initialise(const G4ParticleDefinition* parti
if (tDummy != pTdummyVec->back()) pTdummyVec->push_back(tDummy);
G4double tmp; //probability
for (int j = 0; j < currentMaterialStructure->NumberOfLevels(); j++)
for (G4int j = 0; j < currentMaterialStructure->NumberOfLevels(); j++)
{
pDiffCrossSection >> tmp;
(*pDiffCrossSectionData)[j][tDummy][eDummy] = tmp;
@@ -444,28 +425,32 @@ void G4MicroElecInelasticModel_new::Initialise(const G4ParticleDefinition* parti
(*pProbaShellMap)[j][tDummy].push_back((*pDiffCrossSectionData)[j][tDummy][eDummy]);
}
else { // SI - only if eof is not reached !
if (!pDiffCrossSection.eof()) (*pDiffCrossSectionData)[j][tDummy][eDummy] *= scaleFactor;
(*eVecm)[tDummy].push_back(eDummy);
(*pDiffCrossSectionData)[j][tDummy][eDummy] *= scaleFactor;
(*pVecm)[tDummy].push_back(eDummy);
}
}
}
//Filing maps for the current material into the master maps
if (fasterCode) {
isUsed1 = true;
pNrjTransStorage[mat] = pNrjTransfData;
pProbaShellStorage[mat] = pProbaShellMap;
}
else {
pDiffDatatable[mat] = pDiffCrossSectionData;
pVecmStorage[mat] = eVecm;
pVecmStorage[mat] = pVecm;
}
pIncidentEnergyStorage[mat] = pTdummyVec;
//Cleanup support vectors
//delete pNrjTransfData;
//delete eVecm;
//delete pDiffCrossSectionData;
//delete pProbaShellMap;
if (!isUsed1) {
delete pProbaShellMap;
delete pNrjTransfData;
} else {
delete pDiffCrossSectionData;
delete pVecm;
}
}
tableTCS[mat] = tableData;
}
@@ -494,7 +479,7 @@ void G4MicroElecInelasticModel_new::Initialise(const G4ParticleDefinition* parti
}
fAtomDeexcitation = G4LossTableManager::Instance()->AtomDeexcitation();
fParticleChangeForGamma = GetParticleChangeForGamma();
isInitialised = true;
}
@@ -603,8 +588,8 @@ G4double G4MicroElecInelasticModel_new::CrossSectionPerVolume(const G4Material*
G4cout << " - Cross section per Si atom (cm^-1)=" << sigma*density / (1. / cm) << G4endl;
}
return (sigma)*density;}
return (sigma)*density;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -745,9 +730,6 @@ void G4MicroElecInelasticModel_new::SampleSecondaries(std::vector<G4DynamicParti
//if (!SEFromFermiLevel && weaklyBound) limitEnergy += currentMaterialStructure->GetEnergyGap();
fParticleChangeForGamma->SetProposedKineticEnergy(ekin - secondaryKinetic-limitEnergy); //Ef = Ei-(Q-El)-El = Ei-Q
fParticleChangeForGamma->ProposeLocalEnergyDeposit(limitEnergy-deexSecEnergy);
if (secondaryKinetic>0)
{
@@ -848,7 +830,7 @@ G4double G4MicroElecInelasticModel_new::RandomizeEjectedElectronEnergyFromCumula
if(secondaryElectronKineticEnergy <= 0.) {
secondaryElectronKineticEnergy = 0.0;
}
}
}
else {
secondaryElectronKineticEnergy = transf - currentMaterialStructure->GetLimitEnergy(shell);
// for weaklybound electrons = gap + average energy in the energy band
@@ -61,9 +61,8 @@ G4MicroElecLOPhononModel::G4MicroElecLOPhononModel(const G4ParticleDefinition*,
const G4String& nam)
: G4VEmModel(nam),isInitialised(false)
{
fParticleChangeForGamma = GetParticleChangeForGamma();
G4cout << "Phonon model is constructed " << G4endl
<< "Phonon Energy = " << phononEnergy / eV << " eV "<< G4endl;
<< "Phonon Energy = " << phononEnergy / eV << " eV "<< G4endl;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -6,6 +6,13 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2024-01-23 V.Ivanchenko (emstand-V11-01-25)
- G4IonICRU73Data - fixed bug #2586 for the case if target material has
an element with Z>92, improve debug printouts. In the Lindhard-Sorensen
model to compute dEdx the first try is to take it from ICRU73 or ICRU90
data, if this class return 0.0, then dEdx is computed from G4GenericIon
and effective charge.
## 2023-11-03 Ben Morgan (emstand-V11-01-24)
- Use "G4" prefixed version of EXPAT/ZLIB CMake variables
@@ -65,6 +65,7 @@ public:
// Z - atomic number of the projectile
// e - energy per nucleon, loge = log(e)
// if data for a given combination Z/material exist the DEDX > 0.
G4double GetDEDX(const G4Material*, const G4int Z,
const G4double e, const G4double loge) const;
@@ -97,7 +98,6 @@ private:
G4PhysicsLogVector* fElmData[81][93] = {{nullptr}};
G4PhysicsFreeVector* fVector = nullptr;
G4int fNmat = 0;
G4int fNbins = 0;
G4int fNbinsPerDecade = 10;
G4int fVerbose = 0;
@@ -130,16 +130,19 @@ G4IonICRU73Data::~G4IonICRU73Data()
G4double G4IonICRU73Data::GetDEDX(const G4Material* mat, const G4int Z,
const G4double e, const G4double loge) const
{
// if data does not exist the result is zero
if (Z > ZPROJMAX) { return 0.0; }
G4PhysicsLogVector* v = nullptr;
G4int Z2 = std::min(Z, ZPROJMAX);
if(1 == mat->GetNumberOfElements()) {
G4int Z1 = std::min((*(mat->GetElementVector()))[0]->GetZasInt(), ZTARGMAX);
v = fElmData[Z2][Z1];
} else {
if (1 == mat->GetNumberOfElements()) {
G4int Z1 = (*(mat->GetElementVector()))[0]->GetZasInt();
if(Z1 > ZTARGMAX) { return 0.0; }
v = fElmData[Z][Z1];
}
else {
G4int idx = fMatIndex[mat->GetIndex()];
if(idx < fNmat) {
v = (*(fMatData[Z2]))[idx];
}
if (idx < 0) { return 0.0; }
v = (*(fMatData[Z]))[idx];
}
if(nullptr == v) { return 0.0; }
G4double res = (e > fEmin) ? v->LogVectorValue(e, loge)
@@ -158,9 +161,13 @@ void G4IonICRU73Data::Initialise()
fDataDirectory = ost.str();
}
std::size_t nmat = G4Material::GetNumberOfMaterials();
const std::size_t nmat = G4Material::GetNumberOfMaterials();
// do nothing if for a new run list of materials is not changed
if(nmat == fMatIndex.size()) { return; }
// look over all materials and recompute all materials
// do not recompute element data if exist
if(1 < fVerbose) {
G4cout << "### G4IonICRU73Data::Initialise() for " << nmat
<< " materials" << G4endl;
@@ -173,55 +180,64 @@ void G4IonICRU73Data::Initialise()
auto mtable = G4Material::GetMaterialTable();
for(G4int i=0; i<(G4int)nmat; ++i) {
fNmat = i;
const G4Material* mat = (*mtable)[i];
const G4String matname = mat->GetName();
G4int idx = (G4int)mat->GetIndex();
if(1 < fVerbose) {
G4cout << i << ". material:" << mat->GetName()
G4cout << i << ". material: " << matname
<< " idx=" << idx << " matIdx=" << fMatIndex[idx]
<< " fNmat=" << fNmat << G4endl;
<< G4endl;
}
if(fMatIndex[idx] == -1) {
fMatIndex[idx] = i;
G4String matname = mat->GetName();
G4bool isOK = false;
if(1 == mat->GetNumberOfElements()) {
ReadElementData(mat, useICRU90);
isOK = true;
if(1 < fVerbose) {
G4cout << "Material from single element fNmat=" << fNmat << G4endl;
}
}
if(!isOK && useICRU90) {
// for material in ICRU90
if(useICRU90) {
for(G4int j=0; j<3; ++j) {
if(matname == namesICRU90[j]) {
ReadMaterialData(mat, densityCoef[j], true);
isOK = true;
if(1 < fVerbose) {
G4cout << "ICRU90 material" << G4endl;
G4cout << "ICRU90 material " << matname << G4endl;
}
break;
}
}
}
// for material in ICRU73
if(!isOK) {
for(G4int j=0; j<31; ++j) {
if(matname == namesICRU73[j]) {
ReadMaterialData(mat, 1.0, false);
isOK = true;
if(1 < fVerbose) {
G4cout << "ICRU73 material" << G4endl;
G4cout << "ICRU73 material " << matname << G4endl;
}
break;
}
}
}
// dEdx is combined from element stopping power
// Target element Z <= ZTARGMAX
if(!isOK) {
ReadElementData(mat, useICRU90);
if(1 < fVerbose) {
G4cout << "Read element data" << G4endl;
}
const std::size_t nelm = mat->GetNumberOfElements();
auto elmv = mat->GetElementVector();
G4bool isOut = false;
for (std::size_t j=0; j<nelm; ++j) {
if ((*elmv)[j]->GetZasInt() > ZTARGMAX) {
isOut = true;
break;
}
}
if (!isOut) {
ReadElementData(mat, useICRU90);
isOK = true;
if(1 < fVerbose) {
G4cout << "Data via elements for " << matname << G4endl;
}
}
}
if(isOK) { fMatIndex[idx] = i; }
}
if(1 < fVerbose) {
G4cout << " matData: " << fMatData[i] << G4endl;
@@ -235,7 +251,8 @@ void G4IonICRU73Data::ReadMaterialData(const G4Material* mat,
const G4double coeff,
const G4bool useICRU90)
{
G4String name = mat->GetName();
const G4String name = mat->GetName();
const G4int idx = (G4int)mat->GetIndex();
for(G4int Z=3; Z<=ZPROJMAX; ++Z) {
std::ostringstream ost;
ost << fDataDirectory << "icru";
@@ -262,7 +279,7 @@ void G4IonICRU73Data::ReadMaterialData(const G4Material* mat,
}
}
}
if(nullptr == (*(fMatData[Z1]))[fNmat]) {
if(nullptr == (*(fMatData[Z1]))[idx]) {
ost << "/z" << Z1 << "_" << name << ".dat";
G4PhysicsLogVector* v = RetrieveVector(ost, false);
if(nullptr != v) {
@@ -274,14 +291,14 @@ void G4IonICRU73Data::ReadMaterialData(const G4Material* mat,
<< " and projectile Z=" << Z1 << G4endl;
G4cout << *v << G4endl;
}
(*(fMatData[Z1]))[fNmat] = v;
(*(fMatData[Z1]))[idx] = v;
}
}
if(Z != Z1) {
auto v2 = (*(fMatData[Z1]))[fNmat];
auto v2 = (*(fMatData[Z1]))[idx];
if(nullptr != v2) {
auto v1 = new G4PhysicsLogVector(*v2);
(*(fMatData[Z]))[fNmat] = v1;
(*(fMatData[Z]))[idx] = v1;
v1->ScaleVector(1.0, scale);
}
}
@@ -295,7 +312,11 @@ void G4IonICRU73Data::ReadElementData(const G4Material* mat, G4bool useICRU90)
const G4ElementVector* elmv = mat->GetElementVector();
const G4double* dens = mat->GetFractionVector();
const G4int nelm = (G4int)mat->GetNumberOfElements();
for(G4int Z=3; Z<ZPROJMAX; ++Z) {
for(G4int Z=3; Z<=ZPROJMAX; ++Z) {
if (1 < fVerbose) {
G4cout << "ReadElementData for " << mat->GetName() << " Z=" << Z
<< " Nelm=" << nelm << G4endl;
}
G4PhysicsLogVector* v = nullptr;
if(1 == nelm) {
v = FindOrBuildElementData(Z, (*elmv)[0]->GetZasInt(), useICRU90);
@@ -311,7 +332,7 @@ void G4IonICRU73Data::ReadElementData(const G4Material* mat, G4bool useICRU90)
v->PutValue(i, dedx);
}
if(fSpline) { v->FillSecondDerivatives(); }
(*(fMatData[Z]))[fNmat] = v;
(*(fMatData[Z]))[(G4int)mat->GetIndex()] = v;
}
// scale data for correct units
if(nullptr != v) {
@@ -6,7 +6,11 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2022-12-01 John Allison (emutils-V11-01-25)
## 2023-12-15 V.Ivanchenko (emutils-V11-01-26)
- G4VEmProcess, G4VEnergyLossProcess - minor CPU optimisation by reduction
of number of calls for Log of kinetic energy
## 2023-12-01 John Allison (emutils-V11-01-25)
- G4EmParametersMessenger:
- Fix "/process/eloss/setFluctModel" - change "eloss" to "eLoss".
@@ -314,7 +314,9 @@ private:
void PrintWarning(G4String tit, G4double val);
void ComputeIntegralLambda(G4double kinEnergy, G4double logKinEnergy);
void ComputeIntegralLambda(G4double kinEnergy, const G4Track&);
inline G4double LogEkin(const G4Track&);
inline G4double GetLambdaFromTable(G4double kinEnergy);
@@ -385,7 +387,6 @@ protected:
G4double mfpKinEnergy = DBL_MAX;
G4double preStepKinEnergy = 0.0;
G4double preStepLogKinEnergy = LOG_EKIN_MIN;
G4double preStepLambda = 0.0;
private:
@@ -516,6 +517,13 @@ inline G4double G4VEmProcess::GetLambdaFromTable(G4double e)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEmProcess::LogEkin(const G4Track& track)
{
return track.GetDynamicParticle()->GetLogKineticEnergy();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEmProcess::GetLambdaFromTable(G4double e, G4double loge)
{
return ((*theLambdaTable)[basedCoupleIndex])->LogVectorValue(e, loge);
@@ -403,8 +403,10 @@ private:
inline G4double GetLambdaForScaledEnergy(G4double scaledKinE,
G4double logScaledKinE);
inline G4double LogScaledEkin(const G4Track& aTrack);
void ComputeLambdaForScaledEnergy(G4double scaledKinE,
G4double logScaledKinE);
const G4Track& aTrack);
G4bool IsRegionForCubcutProcessor(const G4Track& aTrack);
@@ -472,9 +474,7 @@ protected:
G4double preStepLambda = 0.0;
G4double preStepKinEnergy = 0.0;
G4double preStepLogKinEnergy = LOG_EKIN_MIN;
G4double preStepScaledEnergy = 0.0;
G4double preStepLogScaledEnergy = LOG_EKIN_MIN;
G4double mfpKinEnergy = 0.0;
std::size_t currentCoupleIndex = 0;
@@ -582,6 +582,8 @@ inline G4double G4VEnergyLossProcess::GetDEDXForScaledEnergy(G4double e)
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline
G4double G4VEnergyLossProcess::GetDEDXForScaledEnergy(G4double e, G4double loge)
{
@@ -702,6 +704,13 @@ G4VEnergyLossProcess::GetLambdaForScaledEnergy(G4double e, G4double loge)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEnergyLossProcess::LogScaledEkin(const G4Track& track)
{
return track.GetDynamicParticle()->GetLogKineticEnergy() + logMassRatio;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double
G4VEnergyLossProcess::GetDEDX(G4double kinEnergy,
const G4MaterialCutsCouple* couple)
@@ -335,6 +335,7 @@ void G4VEmProcess::StartTracking(G4Track* track)
currentParticle = track->GetParticleDefinition();
theNumberOfInteractionLengthLeft = -1.0;
mfpKinEnergy = DBL_MAX;
preStepLambda = 0.0;
if(isIon) { massRatio = proton_mass_c2/currentParticle->GetPDGMass(); }
@@ -359,8 +360,7 @@ G4double G4VEmProcess::PostStepGetPhysicalInteractionLength(
G4double x = DBL_MAX;
DefineMaterial(track.GetMaterialCutsCouple());
preStepKinEnergy = track.GetKineticEnergy();
preStepLogKinEnergy = track.GetDynamicParticle()->GetLogKineticEnergy();
preStepKinEnergy = track.GetKineticEnergy();
const G4double scaledEnergy = preStepKinEnergy*massRatio;
SelectModel(scaledEnergy, currentCoupleIndex);
/*
@@ -370,6 +370,8 @@ G4double G4VEmProcess::PostStepGetPhysicalInteractionLength(
if(!currentModel->IsActive(scaledEnergy)) {
theNumberOfInteractionLengthLeft = -1.0;
currentInteractionLength = DBL_MAX;
mfpKinEnergy = DBL_MAX;
preStepLambda = 0.0;
return x;
}
@@ -384,7 +386,8 @@ G4double G4VEmProcess::PostStepGetPhysicalInteractionLength(
}
// compute mean free path
ComputeIntegralLambda(preStepKinEnergy, preStepLogKinEnergy);
ComputeIntegralLambda(preStepKinEnergy, track);
// zero cross section
if(preStepLambda <= 0.0) {
@@ -417,15 +420,15 @@ G4double G4VEmProcess::PostStepGetPhysicalInteractionLength(
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VEmProcess::ComputeIntegralLambda(G4double e, G4double loge)
void G4VEmProcess::ComputeIntegralLambda(G4double e, const G4Track& track)
{
if(fXSType == fEmNoIntegral) {
preStepLambda = GetCurrentLambda(e, loge);
if (fXSType == fEmNoIntegral) {
preStepLambda = GetCurrentLambda(e, LogEkin(track));
} else if(fXSType == fEmIncreasing) {
} else if (fXSType == fEmIncreasing) {
if(e*invLambdaFactor < mfpKinEnergy) {
mfpKinEnergy = e;
preStepLambda = GetCurrentLambda(e, loge);
preStepLambda = GetCurrentLambda(e, LogEkin(track));
mfpKinEnergy = (preStepLambda > 0.0) ? e : 0.0;
}
} else if(fXSType == fEmDecreasing) {
@@ -439,17 +442,16 @@ void G4VEmProcess::ComputeIntegralLambda(G4double e, G4double loge)
const G4double epeak = (*theEnergyOfCrossSectionMax)[currentCoupleIndex];
if(e <= epeak) {
if(e*invLambdaFactor < mfpKinEnergy) {
mfpKinEnergy = e;
preStepLambda = GetCurrentLambda(e, loge);
preStepLambda = GetCurrentLambda(e, LogEkin(track));
mfpKinEnergy = (preStepLambda > 0.0) ? e : 0.0;
}
} else if(e < mfpKinEnergy) {
const G4double e1 = std::max(epeak, e*lambdaFactor);
preStepLambda = GetCurrentLambda(e1);
preStepLambda = GetCurrentLambda(e1);
mfpKinEnergy = e1;
}
} else {
preStepLambda = GetCurrentLambda(e, loge);
preStepLambda = GetCurrentLambda(e, LogEkin(track));
}
}
@@ -546,6 +546,7 @@ void G4VEnergyLossProcess::StartTracking(G4Track* track)
// reset parameters for the new track
theNumberOfInteractionLengthLeft = -1.0;
mfpKinEnergy = DBL_MAX;
preStepLambda = 0.0;
currentCouple = nullptr;
// reset ion
@@ -567,13 +568,13 @@ void G4VEnergyLossProcess::StartTracking(G4Track* track)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4VEnergyLossProcess::AlongStepGetPhysicalInteractionLength(
const G4Track&,G4double,G4double,G4double&,
const G4Track& track, G4double, G4double, G4double&,
G4GPILSelection* selection)
{
G4double x = DBL_MAX;
*selection = aGPILSelection;
if(isIonisation && currentModel->IsActive(preStepScaledEnergy)) {
GetScaledRangeForScaledEnergy(preStepScaledEnergy, preStepLogScaledEnergy);
GetScaledRangeForScaledEnergy(preStepScaledEnergy, LogScaledEkin(track));
x = (useCutAsFinalRange) ? std::min(finalRange,
currentCouple->GetProductionCuts()->GetProductionCut(1)) : finalRange;
x = (fRange > x) ? fRange*dRoverRange + x*(1.0 - dRoverRange)*(2.0 - x/fRange)
@@ -601,15 +602,15 @@ G4double G4VEnergyLossProcess::PostStepGetPhysicalInteractionLength(
// at the beginning of the step
DefineMaterial(track.GetMaterialCutsCouple());
preStepKinEnergy = track.GetKineticEnergy();
preStepLogKinEnergy = track.GetDynamicParticle()->GetLogKineticEnergy();
preStepScaledEnergy = preStepKinEnergy*massRatio;
preStepLogScaledEnergy = preStepLogKinEnergy + logMassRatio;
SelectModel(preStepScaledEnergy);
if(!currentModel->IsActive(preStepScaledEnergy)) {
theNumberOfInteractionLengthLeft = -1.0;
mfpKinEnergy = DBL_MAX;
preStepLambda = 0.0;
currentInteractionLength = DBL_MAX;
return x;
return x;
}
// change effective charge of a charged particle on fly
@@ -632,9 +633,8 @@ G4double G4VEnergyLossProcess::PostStepGetPhysicalInteractionLength(
}
}
// compute mean free path
ComputeLambdaForScaledEnergy(preStepScaledEnergy, preStepLogScaledEnergy);
ComputeLambdaForScaledEnergy(preStepScaledEnergy, track);
// zero cross section
if(preStepLambda <= 0.0) {
theNumberOfInteractionLengthLeft = -1.0;
@@ -681,13 +681,13 @@ G4double G4VEnergyLossProcess::PostStepGetPhysicalInteractionLength(
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void
G4VEnergyLossProcess::ComputeLambdaForScaledEnergy(G4double e, G4double loge)
G4VEnergyLossProcess::ComputeLambdaForScaledEnergy(G4double e, const G4Track& track)
{
// cross section increased with energy
if(fXSType == fEmIncreasing) {
if(e*invLambdaFactor < mfpKinEnergy) {
mfpKinEnergy = e;
preStepLambda = GetLambdaForScaledEnergy(e, loge);
preStepLambda = GetLambdaForScaledEnergy(e, LogScaledEkin(track));
mfpKinEnergy = (preStepLambda > 0.0) ? e : 0.0;
}
// cross section has one peak
@@ -695,8 +695,8 @@ G4VEnergyLossProcess::ComputeLambdaForScaledEnergy(G4double e, G4double loge)
const G4double epeak = (*theEnergyOfCrossSectionMax)[basedCoupleIndex];
if(e <= epeak) {
if(e*invLambdaFactor < mfpKinEnergy) {
mfpKinEnergy = e;
preStepLambda = GetLambdaForScaledEnergy(e, loge);
preStepLambda = GetLambdaForScaledEnergy(e, LogScaledEkin(track));
mfpKinEnergy = (preStepLambda > 0.0) ? e : 0.0;
}
} else if(e < mfpKinEnergy) {
const G4double e1 = std::max(epeak, e*lambdaFactor);
@@ -712,8 +712,8 @@ G4VEnergyLossProcess::ComputeLambdaForScaledEnergy(G4double e, G4double loge)
// below the 1st peak
if(e <= e1peak) {
if(e*invLambdaFactor < mfpKinEnergy) {
mfpKinEnergy = e;
preStepLambda = GetLambdaForScaledEnergy(e, loge);
preStepLambda = GetLambdaForScaledEnergy(e, LogScaledEkin(track));
mfpKinEnergy = (preStepLambda > 0.0) ? e : 0.0;
}
return;
}
@@ -732,7 +732,7 @@ G4VEnergyLossProcess::ComputeLambdaForScaledEnergy(G4double e, G4double loge)
if(e <= e2peak) {
if(e*invLambdaFactor < mfpKinEnergy) {
mfpKinEnergy = e;
preStepLambda = GetLambdaForScaledEnergy(e, loge);
preStepLambda = GetLambdaForScaledEnergy(e, LogScaledEkin(track));
}
return;
}
@@ -751,7 +751,7 @@ G4VEnergyLossProcess::ComputeLambdaForScaledEnergy(G4double e, G4double loge)
if(e <= e3peak) {
if(e*invLambdaFactor < mfpKinEnergy) {
mfpKinEnergy = e;
preStepLambda = GetLambdaForScaledEnergy(e, loge);
preStepLambda = GetLambdaForScaledEnergy(e, LogScaledEkin(track));
}
return;
}
@@ -763,7 +763,7 @@ G4VEnergyLossProcess::ComputeLambdaForScaledEnergy(G4double e, G4double loge)
}
// integral method is not used
} else {
preStepLambda = GetLambdaForScaledEnergy(e, loge);
preStepLambda = GetLambdaForScaledEnergy(e, LogScaledEkin(track));
}
}
@@ -820,7 +820,7 @@ G4VParticleChange* G4VEnergyLossProcess::AlongStepDoIt(const G4Track& track,
// Short step
eloss = length*GetDEDXForScaledEnergy(preStepScaledEnergy,
preStepLogScaledEnergy);
LogScaledEkin(track));
/*
G4cout << "##### Short STEP: eloss= " << eloss
<< " Escaled=" << preStepScaledEnergy
@@ -6,6 +6,13 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2024-01-10 Soon Yung Jun (xrays-V11-01-10)
- G4Scintillation::sample_time - refactor the scintillation time sampling
## 2023-12-16 Vladimir Grichine
- G4GaussXTRadiator, G4VXTRenergyLoss - flexible summation in
SpectralXTRdEdx, clean-up in GetStackFactor based on std::complex methods
## 2023-11-04 Vladimir Grichine (xrays-V11-01-09)
- G4GaussXTRadiator - bug fixed by renaming virtual function to prevent
clash between base and inhereted classes, new name SpectralXTRdEdxFS
@@ -53,7 +53,7 @@ class G4GaussXTRadiator : public G4VXTRenergyLoss
~G4GaussXTRadiator();
// reimplementation of base class function in analytical way
G4double SpectralXTRdEdxFS(G4double energy);
G4double SpectralXTRdEdx(G4double energy) override;
G4double GetStackFactor(G4double energy, G4double gamma,
G4double varAngle) override;
@@ -151,6 +151,8 @@ class G4VXTRenergyLoss : public G4VDiscreteProcess
void SetCompton(G4bool pC) { fCompton = pC; };
G4bool GetCompton() { return fCompton; };
G4int GetKrange(){ return fKrange;};
void SetKrange( G4int kk ){ fKrange = kk;};
void SetAlphaGas(G4double ag){ fAlphaGas = ag;};
@@ -214,7 +216,7 @@ class G4VXTRenergyLoss : public G4VDiscreteProcess
G4int fTotBin; // number of bins in log-gamma scale
G4int fBinTR; // number of bins in TR energy-angle vectors
G4int fKrange;
G4ParticleDefinition* fPtrGamma; // pointer to TR photon
G4double* fGammaCutInKineticEnergy; // TR photon cut in energy array
@@ -60,9 +60,9 @@ void G4GaussXTRadiator::ProcessDescription(std::ostream& out) const
///////////////////////////////////////////////////////////////////////////
//
// The Fabian-Strujinsky (FS) algorithm for integration over XTR angle,
// resolution is about 0.5 mrad
// resolution is about 0.1-0.5 mrad
G4double G4GaussXTRadiator::SpectralXTRdEdxFS(G4double energy)
G4double G4GaussXTRadiator::SpectralXTRdEdx(G4double energy)
{
G4double result, sum = 0., tmp, cof1, cof2, cofMin, cofPHC, theta2, theta2k;
G4int k, kMax, kMin;
@@ -82,7 +82,7 @@ G4double G4GaussXTRadiator::SpectralXTRdEdxFS(G4double energy)
if(cofMin > kMin)
kMin++;
kMax = kMin + 49;
kMax = kMin + fKrange;
if(verboseLevel > 2)
{
@@ -130,88 +130,27 @@ G4double G4GaussXTRadiator::GetStackFactor(G4double energy,
G4double gamma,
G4double varAngle)
{
G4double result, Qa, Qb, Q, Qn, aZa, bZb, aMa, bMb;
G4double Ma, Mb, Za, Zb;
G4double result(0.);
G4double sa = fPlateThick/fAlphaPlate;
G4double sb = fGasThick/fAlphaGas;
Za = GetPlateFormationZone(energy, gamma, varAngle);
aZa = fPlateThick / Za ;
Zb = GetGasFormationZone(energy, gamma, varAngle);
bZb = fGasThick / Zb ;
Ma = GetPlateLinearPhotoAbs(energy);
aMa = fPlateThick * Ma;
Mb = GetGasLinearPhotoAbs(energy);
bMb = fGasThick * Mb;
// Gauss fluctuation of gas gaps according to RMS = sb = b/fAlphaGas
G4double gre, gim, pre, pim;
pre = -0.5 * aMa - sa * sa * ( 4./ Za / Za - Ma*Ma )/8.;
gre = -0.5 * bMb - sb * sb * ( 4./ Zb / Zb - Mb*Mb )/8.;
pim = sa * sa * Ma/2./Za - aZa;
gim = sb * sb * Mb/2./Zb - bZb;
Qa = std::exp(pre);
Qb = std::exp(gre);
// Q = Qa * Qb;
G4complex Ha( Qa * std::cos(pim), Qa * std::sin(pim) );
G4complex Hb( Qb * std::cos(gim), Qb * std::sin(gim) );
G4double hre, him, hnre, hnim;
hre = pre + gre;
him = pim + gim;
G4double nn = G4double(fPlateNumber);
hnre = nn*hre;
hnim = nn*him;
G4complex med( 0., 1.);
G4complex Z1 = GetPlateComplexFZ( energy, gamma, varAngle);
G4complex order1 = -0.5*med*fPlateThick/Z1 - 0.125*sa*sa/Z1/Z1;
Q = std::exp(hre);
Qn = std::exp(hnre);
// G4complex H = Ha * Hb;
G4complex Z2 = GetGasComplexFZ( energy, gamma, varAngle);
G4complex order2 = -0.5*med*fGasThick/Z2 - 0.125*sb*sb/Z2/Z2;
G4complex ordernn = ( order1 + order2 )*nn;
G4complex H( Q * std::cos(him), Q * std::sin(him) );
G4complex Hn( Qn * std::cos(hnim), Qn * std::sin(hnim) );
// G4complex Hs = conj(H);
// G4double sigma, D;
// sigma = aMa * fPlateThick + bMb * fGasThick;
// D = 1.0 / ((1 - Q) * (1 - Q) + 4 * Q * std::sin(0.5 * (aZa + bZb)) * std::sin(0.5 * (aZa + bZb)));
// G4complex F1 = ( 1.0 - Ha ) * ( 1.0 - Hb ) * ( 1.0 - Hs ) * G4double(fPlateNumber) * D;
G4complex Ha = exp( order1 );
G4complex Hb = exp( order2 );
G4complex H = Ha * Hb;
G4complex Hn = exp( ordernn );
G4complex F1 = ( 1.0 - Ha ) * ( 1.0 - Hb ) * nn / ( 1. - H );
// G4complex F2 = ( 1.0 - Ha ) * ( 1.0 - Ha ) * Hb * ( 1.0 - Hs ) * ( 1.0 - Hs ) * (1.0 - std::exp( -0.5 * fPlateNumber * sigma) ) * D * D;
G4complex F2 = ( 1.0 - Ha ) * ( 1.0 - Ha ) * Hb * ( 1. - Hn ) / ( 1. - H ) / ( 1. - H );
G4complex R = (F1 + F2) * OneInterfaceXTRdEdx(energy, gamma, varAngle);
@@ -639,21 +639,16 @@ G4double G4Scintillation::sample_time(G4double tau1, G4double tau2)
{
// tau1: rise time and tau2: decay time
// Loop checking, 07-Aug-2015, Vladimir Ivanchenko
while(true)
{
G4double ran1 = G4UniformRand();
G4double ran2 = G4UniformRand();
G4double t;
// exponential distribution as envelope function: very efficient
G4double d = (tau1 + tau2) / tau2;
// make sure the envelope function is
// always larger than the bi-exponential
G4double t = -1.0 * tau2 * std::log(1. - ran1);
G4double gg = d * single_exp(t, tau2);
if(ran2 <= bi_exp(t, tau1, tau2) / gg)
return t;
do
{
// The exponential distribution as an envelope function: very efficient
t = -1.0 * tau2 * G4Log(1.0 - G4UniformRand());
}
return -1.0;
while (G4UniformRand() > (1.0 - G4Exp(-t/tau1)));
return t;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -87,8 +87,8 @@ G4VXTRenergyLoss::G4VXTRenergyLoss(G4LogicalVolume* anEnvelope,
fTheMaxAngle = 4.e-4;
fTotBin = 50; // number of bins in log scale
fBinTR = 100; // number of bins in TR vectors
fBinTR = 100; // number of bins in TR vectors
fKrange = 229;
// min/max angle2 in log-vectors
fMinThetaTR = 3.0e-9;
@@ -6,6 +6,10 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2023-12-09 Vladimir Ivanchenko (hadr-cross-V11-01-17)
- G4KokoulinMuonNuclearXS - use faster interface to G4PhysicsVector
- G4ElectroNuclearCrossSection - added low-energy limit 100 MeV for x-section
## 2023-11-18 I. Hrivnacova (hadr-cross-V11-01-16)
- G4PhotoNuclearCrossSection - fix memory leaks
@@ -61,6 +61,7 @@ G4_DECLARE_XS_FACTORY(G4ElectroNuclearCrossSection);
// removing all the static consts and putting them here
// Parametrization of the PhotoNucCS
static const G4double sLowEnergyLimit = 100.; // Low-energy limit for the process in MeV
static const G4double shd=1.0734; // HE PomShadowing(D)
static const G4double poc=0.0375; // HE Pomeron coefficient
static const G4double pos=16.5; // HE Pomeron shift
@@ -2254,17 +2255,16 @@ G4ElectroNuclearCrossSection::CrossSectionDescription(std::ostream& outFile) con
<< "all energies.\n";
}
G4bool G4ElectroNuclearCrossSection::IsElementApplicable(const G4DynamicParticle* /*aParticle*/, G4int Z, const G4Material*)
G4bool G4ElectroNuclearCrossSection::IsElementApplicable(const G4DynamicParticle*, G4int, const G4Material*)
{
return (Z>0 && Z<120);
return true;
}
G4double G4ElectroNuclearCrossSection::GetElementCrossSection(const G4DynamicParticle* aPart, G4int ZZ, const G4Material*)
{
const G4double Energy = aPart->GetKineticEnergy()/MeV; // Energy of the electron
const G4double Energy = aPart->GetKineticEnergy(); // Energy of the electron
if (Energy<=EMi) return 0.; // Energy is below the minimum energy in the table
if (Energy <= sLowEnergyLimit || ZZ >= 120) return 0.; // Energy is below the minimum energy of the process
if(ZZ!=lastZ) // This nucleus was not the last used element
{
@@ -219,11 +219,11 @@ ComputeDDMicroscopicCrossSection(G4double KineticEnergy, G4double,
G4double G4KokoulinMuonNuclearXS::
GetElementCrossSection(const G4DynamicParticle* aPart,
G4int Z, const G4Material*)
G4int ZZ, 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());
G4int Z = std::min(ZZ, 92);
return theCrossSection[Z]->LogVectorValue(aPart->GetKineticEnergy(),
aPart->GetLogKineticEnergy());
}
@@ -6,6 +6,11 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2023-12-09 Vladimir Ivanchenko (hadr-man-V11-01-09)
- G4HadronicProcess - explicitly define cross section type per particle type,
this should improve CPU performance for hadronic showers for ~1%
## 2023-11-18 I. Hrivnacova (hadr-man-V11-01-08)
- G4HadronicProcess, G4HadXSHelper - fixed memory leak at exit
@@ -205,23 +205,28 @@ void G4HadronicProcess::BuildPhysicsTable(const G4ParticleDefinition& p)
// check particle for integral method
if(isMaster || nullptr == masterProcess) {
G4double charge = p.GetPDGCharge()/eplus;
G4bool isLepton = (p.GetLeptonNumber() != 0);
G4bool ok = (p.GetAtomicNumber() != 0 || p.GetPDGMass() < GeV);
// select cross section shape
if(charge != 0.0 && useIntegralXS && !isLepton && ok) {
if(charge != 0.0 && useIntegralXS) {
G4double tmax = param->GetMaxEnergy();
fXSType = (charge > 0.0) ? fHadIncreasing : fHadDecreasing;
currentParticle = firstParticle;
// initialisation in the master thread
G4int pdg = p.GetPDGEncoding();
if(std::abs(pdg) == 211) {
if (std::abs(pdg) == 211) {
fXSType = fHadTwoPeaks;
} else if(pdg == 321) {
} else if (pdg == 321) {
fXSType = fHadOnePeak;
} else if(pdg == 2212) {
} else if (pdg == -321) {
fXSType = fHadDecreasing;
} else if (pdg == 2212) {
fXSType = fHadTwoPeaks;
} else if (pdg == -2212 || pdg == -1000010020 || pdg == -1000010030 ||
pdg == -1000020030 || pdg == -1000020040) {
fXSType = fHadDecreasing;
} else if (charge > 0.0 || pdg == 11 || pdg == 13) {
fXSType = fHadIncreasing;
}
delete theEnergyOfCrossSectionMax;
theEnergyOfCrossSectionMax = nullptr;
if(fXSType == fHadTwoPeaks) {
@@ -280,18 +285,8 @@ G4double G4HadronicProcess::PostStepGetPhysicalInteractionLength(
mfpKinEnergy = DBL_MAX;
matIdx = (G4int)track.GetMaterial()->GetIndex();
}
/*
G4cout << GetProcessName() << " E=" << track.GetKineticEnergy()
<< " " << currentParticle->GetParticleName()
<< " lastxs=" << theLastCrossSection
<< " lastmfp=" << theMFP << G4endl;
*/
UpdateCrossSectionAndMFP(track.GetKineticEnergy());
/*
G4cout << " xs=" << theLastCrossSection
<< " mfp=" << theMFP << " nleft=" << theNumberOfInteractionLengthLeft
<< G4endl;
*/
// zero cross section
if(theLastCrossSection <= 0.0) {
theNumberOfInteractionLengthLeft = -1.0;
@@ -6,6 +6,17 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2024-01-29 Vladimir Ivanchenko (hadr-deex-V11-01-12)
- G4StatMFChannel - fixed compilation warnings at alma9-gcc131 seen in CMSSW
by substitution of C-arrays by std::vector
## 2024-01-25 Vladimir Ivanchenko
- G4FermiBreakUpVI, G4FermiFragmentsPoolVI - fixed problem 2584 (production
of fake excited isomeres) by moving the check on lifetime limit from the
pull (initialized once as a static object) to the Initialise() method of
the model allowing to change this limit in an application, do not consider
decay chains with no final state.
## 2023-11-15 Vladimir Ivanchenko (hadr-deex-V11-01-11)
- G4FermiChannels - fixed memory leak at exit
@@ -76,6 +76,7 @@ private:
G4double fTolerance{0.0};
G4double fElim{0.0};
G4double fTimeLim{1.0}; // in ns
G4bool isFirst{false};
@@ -71,7 +71,6 @@ private:
G4double fTolerance{0.0};
G4double fElim{0.0};
G4double fTimeLim{0.0};
const G4int maxZ{9};
const G4int maxA{17};
@@ -39,15 +39,9 @@
#include "G4PhysicsModelCatalog.hh"
#include "Randomize.hh"
#include "G4RandomDirection.hh"
#include "G4AutoLock.hh"
G4FermiFragmentsPoolVI* G4FermiBreakUpVI::fPool = nullptr;
namespace
{
G4Mutex theFBUMutex = G4MUTEX_INITIALIZER;
}
G4FermiBreakUpVI::G4FermiBreakUpVI()
{
frag.reserve(10);
@@ -55,13 +49,9 @@ G4FermiBreakUpVI::G4FermiBreakUpVI()
secID = G4PhysicsModelCatalog::GetModelID("model_G4FermiBreakUpVI");
prob.resize(12,0.0);
if (nullptr == fPool) {
G4AutoLock l(&theFBUMutex);
if (nullptr == fPool) {
fPool = new G4FermiFragmentsPoolVI();
fPool->Initialise();
isFirst = true;
}
l.unlock();
fPool = new G4FermiFragmentsPoolVI();
fPool->Initialise();
isFirst = true;
}
}
@@ -79,6 +69,7 @@ void G4FermiBreakUpVI::Initialise()
G4NuclearLevelData::GetInstance()->GetParameters();
fTolerance = param->GetMinExcitation();
fElim = param->GetFBUEnergyLimit();
fTimeLim = param->GetMaxLifeTime();
if (verbose > 1) {
G4cout << "### G4FermiBreakUpVI::Initialise(): the pool is initilized="
<< fPool->IsInitialized() << " fTolerance(eV)=" << fTolerance/CLHEP::eV
@@ -125,8 +116,8 @@ void G4FermiBreakUpVI::BreakFragment(G4FragmentVector* theResult,
A = frag[i]->GetA();
excitation = frag[i]->GetExcitationEnergy();
lv0 = lvect[i];
G4bool unstable = IsApplicable(Z, A, excitation);
if (unstable) {
G4bool unstable = (IsApplicable(Z, A, excitation) && frag[i]->GetLifeTime() < fTimeLim);
if (unstable) {
mass = frag[i]->GetTotalEnergy();
if (verbose > 1) {
G4cout << "# FermiFrag " << i << ". Z= " << Z << " A= " << A
@@ -43,7 +43,7 @@ G4FermiFragmentsPoolVI::G4FermiFragmentsPoolVI()
G4FermiFragmentsPoolVI::~G4FermiFragmentsPoolVI()
{
for (G4int i=1; i<maxA; ++i) {
for (G4int i=0; i<maxA; ++i) {
for (G4int j=0; j<maxZ; ++j) {
auto ptr = list_c[j][i];
if (nullptr != ptr) {
@@ -79,6 +79,7 @@ G4FermiFragmentsPoolVI::ClosestChannels(G4int Z, G4int A, G4double etot) const
G4double demax = 1.e+9;
for (auto const & ch : *chan) {
if (ch->NumberPairs() == 0) { continue; }
G4double de = etot - ch->GetFragment()->GetTotalEnergy();
// an excitation coincide with a level
if (std::abs(de) <= fTolerance) {
@@ -111,7 +112,6 @@ void G4FermiFragmentsPoolVI::Initialise()
G4NuclearLevelData::GetInstance()->GetParameters();
fTolerance = 2*CLHEP::eV;
fElim = param->GetFBUEnergyLimit();
fTimeLim = param->GetMaxLifeTime();
fragment_pool.reserve(991);
@@ -200,8 +200,7 @@ void G4FermiFragmentsPoolVI::Initialise()
auto ch = (*chan)[k];
const G4double e0 = ch->GetMass();
auto f0 = ch->GetFragment();
if (e0 > minE && f0->GetLifeTime() <= fTimeLim &&
G4FermiBreakUpUtil::CheckSpinParity(f1, f2, f0)) {
if (e0 > minE && G4FermiBreakUpUtil::CheckSpinParity(f1, f2, f0)) {
const G4double cb =
G4FermiBreakUpUtil::CoulombBarrier(Z1, A1, Z2, A2, ch->GetExcitation());
if (e0 >= minE + cb) {
@@ -32,6 +32,7 @@
#define G4StatMFChannel_h 1
#include <deque>
#include <vector>
#include "G4StatMFParameters.hh"
#include "G4StatMFFragment.hh"
@@ -93,6 +94,9 @@ private:
private:
std::deque<G4StatMFFragment*> _theFragments;
std::vector<G4ThreeVector> Pos;
std::vector<G4ThreeVector> Vel;
std::vector<G4ThreeVector> Accel;
G4int _NumOfNeutralFragments;
@@ -46,7 +46,11 @@
G4StatMFChannel::G4StatMFChannel() :
_NumOfNeutralFragments(0),
_NumOfChargedFragments(0)
{}
{
Pos.resize(8);
Vel.resize(8);
Accel.resize(8);
}
G4StatMFChannel::~G4StatMFChannel()
{
@@ -351,10 +355,11 @@ void G4StatMFChannel::SolveEqOfMotion(G4int anA, G4int anZ, G4double T)
G4double TimeN = 0.0;
G4double TimeS = 0.0;
G4double DeltaTime = 10.0;
G4ThreeVector * Pos = new G4ThreeVector[_NumOfChargedFragments];
G4ThreeVector * Vel = new G4ThreeVector[_NumOfChargedFragments];
G4ThreeVector * Accel = new G4ThreeVector[_NumOfChargedFragments];
if (_NumOfChargedFragments > (G4int)Pos.size()) {
Pos.resize(_NumOfChargedFragments);
Vel.resize(_NumOfChargedFragments);
Accel.resize(_NumOfChargedFragments);
}
G4int i;
for (i = 0; i < _NumOfChargedFragments; ++i)
@@ -412,12 +417,6 @@ void G4StatMFChannel::SolveEqOfMotion(G4int anA, G4int anZ, G4double T)
{
_theFragments[i]->SetMomentum((_theFragments[i]->GetNuclearMass()*Eta)*Vel[i]);
}
// garbage collection
delete [] Pos;
delete [] Vel;
delete [] Accel;
return;
}
@@ -5,6 +5,16 @@ which **must** added in reverse chronological order (newest at the top).
It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2024-01-29 Vladimir Ivanchenko (hadr-lend-V11-01-03)
- MCGIDI_product, MCGIDI_outputChannel, MCGIDI_distribution - fixed alma9-gcc131
compilation warnings seen in CMSSW
## 2023-12-18 Gabriele Cosmo
- Fixed compilation error on latest Windows VC++ compiler 17.8.3 for use of
std::isfinite() in nf_specialFunctions_h and in nf_floatToShortestString().
Addressing problem report #2582.
## 2023-11-03 Ben Morgan (hadr-lend-V11-01-02)
- Use "G4" prefixed version of EXPAT/ZLIB CMake variables
@@ -8,12 +8,11 @@
#include <math.h>
#include <float.h>
#include <nf_utilities.h>
#include "nf_utilities.h"
#ifdef WIN32
#define isfinite _finite
#define M_PI 3.141592653589793238463
/*#define INFINITY (DBL_MAX+DBL_MAX)*/
#endif
#if defined __cplusplus
@@ -61,7 +61,7 @@ int MCGIDI_distribution_release( statusMessageReporting *smr, MCGIDI_distributio
int MCGIDI_distribution_parseFromTOM( statusMessageReporting *smr, xDataTOM_element *element, MCGIDI_product *product, MCGIDI_POPs * /*pops*/, ptwXYPoints *norms ) {
char const *nativeData, *gammaEnergy;
double gammaEnergy_MeV;
double gammaEnergy_MeV{0.0};
MCGIDI_distribution *distribution = &(product->distribution);
xDataTOM_element *distributionElement;
enum MCGIDI_energyType energyType = MCGIDI_energyType_unknown;
@@ -61,9 +61,9 @@ int MCGIDI_outputChannel_release( statusMessageReporting *smr, MCGIDI_outputChan
int MCGIDI_outputChannel_parseFromTOM( statusMessageReporting *smr, xDataTOM_element *element, MCGIDI_POPs *pops, MCGIDI_outputChannel *outputChannel,
MCGIDI_reaction *reaction, MCGIDI_product *parent ) {
int n, delayedNeutronIndex = 0;
char const *genre, *Q;
xDataTOM_element *child;
int n{0}, delayedNeutronIndex{0};
char const *genre{""}, *Q{""};
xDataTOM_element *child{nullptr};
MCGIDI_outputChannel_initialize( smr, outputChannel );
@@ -82,9 +82,9 @@ int MCGIDI_product_release( statusMessageReporting *smr, MCGIDI_product *product
int MCGIDI_product_parseFromTOM( statusMessageReporting *smr, xDataTOM_element *element, MCGIDI_outputChannel *outputChannel,
MCGIDI_POPs *pops, MCGIDI_product *product, int *delayedNeutronIndex ) {
char const *name, *label, *delayedNeutron, *multiplicityStr, *multiplicityUnits[2] = { "MeV", "" };
xDataTOM_element *multiplicity, *multiplicityTOM, *decayChannelElement;
nfu_status status;
char const *name{""}, *label{""}, *delayedNeutron{""}, *multiplicityStr{""}, *multiplicityUnits[2] = { "MeV", "" };
xDataTOM_element *multiplicity{nullptr}, *multiplicityTOM{nullptr}, *decayChannelElement{nullptr};
nfu_status status{nfu_Okay};
ptwXYPoints *multiplicityVsEnergy = NULL, *norms1 = NULL, *norms2 = NULL;
MCGIDI_product_initialize( smr, product );
@@ -4,17 +4,11 @@
*/
#include <stdlib.h>
#include <float.h>
#include <cmath>
#include "nf_utilities.h"
#ifdef WIN32
#include <float.h>
#define isfinite _finite
#else
#define isfinite std::isfinite
#endif
#if defined __cplusplus
namespace GIDI {
using namespace GIDI;
@@ -71,7 +65,7 @@ char *nf_floatToShortestString( double value, int significantDigits, int favorEF
if( flags & nf_floatToShortestString_includeSign ) sign = "+";
if( !isfinite( value ) ) {
if( !std::isfinite( value ) ) {
snprintf( Fmt, sizeof Fmt, "%%%sf", sign );
snprintf( Str_e, sizeof Str_e, Fmt, value );
return( strdup( Str_e ) );
@@ -6,6 +6,16 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2024-01-30 Vladimir Ivanchenko (hadr-hpp-V11-01-25)
- G4ParticleHPFSFissionFS, G4ParticleHPFissionBaseFS - substitute
C-arrays with std::vector in order to reduce compilation warnings on gcc
with LTO settings.
## 2024-01-26 Vladimir Ivanchenko
- G4ParticleHPFissionFS, G4ParticleHPFFFissionFS - added extra protections
against cases when fission data are not available for some isotopes
(fixed problem #2590)
## 2023-11-04 Vladimir Ivanchenko (hadr-hpp-V11-01-24)
- G4ParticleHPManager - set default upper limit on Doppler broading
30 keV instead of 100 keV
@@ -164,8 +164,11 @@ void G4ParticleHPFFFissionFS::GetAFissionFragment(G4double energy, G4int& fragZ,
G4double rand = G4UniformRand();
// G4cout << rand << G4endl;
std::map<G4double, std::map<G4int, G4double>*>* mEnergyFSPData =
FissionProductYieldData.find(454)->second;
auto ptr = FissionProductYieldData.find(454);
if (ptr == FissionProductYieldData.end())
return;
auto mEnergyFSPData = ptr->second;
// It is not clear that the treatment of the scheme 2 on two-dimensional interpolation.
// So, here just use the closest energy point array of yield data.
@@ -108,8 +108,9 @@ G4DynamicParticleVector* G4ParticleHPFSFissionFS::ApplyYourself(G4int nPrompt, G
G4double eKinetic = boosted.GetKineticEnergy();
// Build neutrons
auto theNeutrons = new G4ReactionProduct[nPrompt + nDelayed];
std::vector<G4ReactionProduct> theNeutrons;
for (i = 0; i < nPrompt + nDelayed; ++i) {
theNeutrons.emplace_back();
theNeutrons[i].SetDefinition(G4Neutron::Neutron());
}
@@ -140,8 +141,6 @@ G4DynamicParticleVector* G4ParticleHPFSFissionFS::ApplyYourself(G4int nPrompt, G
dp->SetMomentum(theNeutrons[i].GetMomentum());
aResult->push_back(dp);
}
delete[] theNeutrons;
return aResult;
}
@@ -108,8 +108,9 @@ G4DynamicParticleVector* G4ParticleHPFissionBaseFS::ApplyYourself(G4int nPrompt)
G4double eKinetic = boosted.GetKineticEnergy();
// Build neutrons
auto theNeutrons = new G4ReactionProduct[nPrompt];
std::vector<G4ReactionProduct> theNeutrons;
for (i = 0; i < nPrompt; i++) {
theNeutrons.emplace_back();
theNeutrons[i].SetDefinition(G4Neutron::Neutron());
}
@@ -132,7 +133,6 @@ G4DynamicParticleVector* G4ParticleHPFissionBaseFS::ApplyYourself(G4int nPrompt)
it->SetMomentum(theNeutrons[i].GetMomentum());
aResult->push_back(it);
}
delete[] theNeutrons;
// return the result
return aResult;
@@ -251,6 +251,7 @@ G4HadFinalState* G4ParticleHPFissionFS::ApplyYourself(const G4HadProjectile& the
G4int fragA_M = 0;
// System is traget rest!
theFF.GetAFissionFragment(eKinetic, fragA_Z, fragA_A, fragA_M);
if (0 == fragA_A) { return theResult.Get(); }
G4int fragB_Z = (G4int)theBaseZ - fragA_Z;
G4int fragB_A = (G4int)theBaseA - fragA_A - Prompt;
@@ -6,6 +6,9 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2023-12-21 Yoshihide Sato (hadr-qmd-V11-01-04)
- G4LightIonQMDReaction.cc: Fix model ID (model_LightIonQMDModel).
## 2023-10-27 Yoshihide Sato (hadr-qmd-V11-01-03)
- Add files for the Light Ion QMD which is qmd optimized for light ion.
The name of the added files start with G4LightIonQMD.
@@ -111,7 +111,7 @@ G4LightIonQMDReaction::G4LightIonQMDReaction()
coulomb_collision_px_targ = 0.0;
coulomb_collision_pz_targ = 0.0;
secID = G4PhysicsModelCatalog::GetModelID( "model_QMDModel" );
secID = G4PhysicsModelCatalog::GetModelID( "model_LightIonQMDModel" );
}
@@ -6,6 +6,14 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2024-02-13 Vladimir Ivanchenko (radioactive_decay-V11-01-10)
- G4BetaPlusDecay, G4BetaMinusDecay - fixed sampling algorithm (problem #2588)
## 2024-01-13 Alexander Howard
- G4Radioactivation : added DBL_EPSILON check on transition energy for
metastables to prevent creation of zero energy levels which have no decay
products!
## 2023-11-16 Alberto Ribon (radioactive_decay-V11-01-09)
- G4RadioactiveDecay, G4Radioactivation : added an extra parameter in the
constructor of these classes, to be able to set, directly at the level
@@ -58,7 +58,7 @@ G4BetaMinusDecay::G4BetaMinusDecay(const G4ParticleDefinition* theParentNucleus,
const G4Ions::G4FloatLevelBase& flb,
const G4BetaDecayType& betaType)
: G4NuclearDecay("beta- decay", BetaMinus, excitationE, flb),
maxEnergy(e0),
maxEnergy(e0/eMass),
estep(maxEnergy/(G4double)(npti - 1))
{
SetParent(theParentNucleus); // Store name of parent nucleus, delete G4MT_parent
@@ -98,7 +98,7 @@ G4DecayProducts* G4BetaMinusDecay::DecayIt(G4double)
G4DynamicParticle prim(fPrimaryIon, G4ThreeVector(0,0,1), 0.0);
G4DecayProducts* products = new G4DecayProducts(prim);
// Generate positron isotropic in angle, with energy from stored spectrum
// Generate electron isotropic in angle, with energy from stored spectrum
const G4double eKE = eMass*G4BetaSpectrumSampler::shoot(npti, cdf, estep);
G4double eMomentum = std::sqrt(eKE*(eKE + 2.*eMass));
@@ -111,14 +111,14 @@ G4DecayProducts* G4BetaMinusDecay::DecayIt(G4double)
<< " + " << fNeutrino->GetParticleName() << " Ee(MeV)=" << eKE
<< G4endl;
*/
// Fill G4MT_parent with theParentNucleus (stored by SetParent in ctor)
// 4-momentum of residual ion and neutrino
G4LorentzVector lv(-eMomentum*dir.x(), -eMomentum*dir.y(), -eMomentum*dir.z(),
parentMass - eKE - eMass);
G4double edel = std::max(lv.e() - resMass, 0.0);
if (edel > CLHEP::eV) {
G4double edel = std::max(lv.e() - resMass, 0.0);
// Free energy should be above zero
if (edel > 0.0) {
// centrum of mass system
G4double M = lv.mag();
@@ -157,16 +157,17 @@ G4BetaMinusDecay::SetUpBetaSpectrumSampler(const G4int& daughterZ,
{
cdf[0] = 0.0;
// Check for cases in which Q < 2Me (e.g. z67.a162)
// Check for cases in which Q < 0
if (maxEnergy > 0.) {
G4BetaDecayCorrections corrections(daughterZ, daughterA);
// Fill array to store cumulative spectrum
G4double ex;
G4double p; // Positron momentum in units of electron mass
G4double ex; // Kinetic energy normalized on electron mass
G4double p; // Momentum in units of electron mass
G4double f; // Spectral shape function
G4double f0 = 0.0;
G4double sum = 0.0;
for (G4int i = 1; i < npti; ++i) {
for (G4int i = 1; i < npti-1; ++i) {
ex = estep*i;
p = std::sqrt(ex*(ex + 2.));
f = p*(1. + ex)*(maxEnergy - ex)*(maxEnergy - ex);
@@ -176,9 +177,11 @@ G4BetaMinusDecay::SetUpBetaSpectrumSampler(const G4int& daughterZ,
// Apply shape factor for forbidden transitions
f *= corrections.ShapeFactor(betaType, p, maxEnergy - ex);
sum += f;
sum += f + f0;
cdf[i] = sum;
f0 = f;
}
cdf[npti-1] = sum + f0;
} else {
for (G4int i = 1; i < npti; ++i) { cdf[i] = 0.0; }
}
@@ -59,7 +59,7 @@ G4BetaPlusDecay::G4BetaPlusDecay(const G4ParticleDefinition* theParentNucleus,
const G4Ions::G4FloatLevelBase& flb,
const G4BetaDecayType& betaType)
: G4NuclearDecay("beta+ decay", BetaPlus, excitationE, flb),
maxEnergy((e0 - 2*eMass)/eMass),
maxEnergy(e0/eMass - 2.0),
estep(maxEnergy/(G4double)(npti - 1))
{
SetParent(theParentNucleus); // Store name of parent nucleus, delete G4MT_parent
@@ -88,7 +88,7 @@ G4BetaPlusDecay::G4BetaPlusDecay(const G4ParticleDefinition* theParentNucleus,
// Fill G4MT_parent with theParentNucleus (stored by SetParent in ctor)
CheckAndFillParent();
// Fill G4MT_daughters with e-, nu and residual nucleus (stored by SetDaughter)
// Fill G4MT_daughters with e+, nu and residual nucleus (stored by SetDaughter)
CheckAndFillDaughters();
}
@@ -117,8 +117,9 @@ G4DecayProducts* G4BetaPlusDecay::DecayIt(G4double)
G4LorentzVector lv(-eMomentum*dir.x(), -eMomentum*dir.y(), -eMomentum*dir.z(),
parentMass - eKE - eMass);
G4double edel = std::max(lv.e() - resMass, 0.0);
if (edel > CLHEP::eV) {
G4double edel = std::max(lv.e() - resMass, 0.0);
// Free energy should be above zero
if (edel > 0.0) {
// centrum of mass system
G4double M = lv.mag();
@@ -155,17 +156,20 @@ G4BetaPlusDecay::SetUpBetaSpectrumSampler(const G4int& daughterZ,
const G4int& daughterA,
const G4BetaDecayType& betaType)
{
cdf[0] = 0.0;
// Check for cases in which Q < 2Me (e.g. z67.a162)
if (maxEnergy > 0.) {
G4BetaDecayCorrections corrections(-daughterZ, daughterA);
// Fill array to store cumulative spectrum
G4double ex;
G4double ex; // Positron kinetic energy
G4double p; // Positron momentum in units of electron mass
G4double f; // Spectral shape function
G4double f0 = 0.0;
G4double sum = 0.0;
for (G4int i = 0; i < npti; ++i) {
ex = (0 == i) ? maxEnergy*1.e-6 : estep*i;
for (G4int i = 1; i < npti-1; ++i) {
ex = estep*i;
p = std::sqrt(ex*(ex + 2.));
f = p*(1. + ex)*(maxEnergy - ex)*(maxEnergy - ex);
@@ -174,9 +178,11 @@ G4BetaPlusDecay::SetUpBetaSpectrumSampler(const G4int& daughterZ,
// Apply shape factor for forbidden transitions
f *= corrections.ShapeFactor(betaType, p, maxEnergy - ex);
sum += f;
sum += f + f0;
cdf[i] = sum;
f0 = f;
}
cdf[npti-1] = sum + f0;
} else {
for (G4int i = 0; i < npti; ++i) { cdf[i] = 0.0; }
}
@@ -459,7 +459,7 @@ CalculateChainsFromParent(const G4ParticleDefinition& theParentNucleus)
// summedDecayTable. If not, just add its BR to sum for that decay mode.
if (levelManager->NumberOfTransitions() ) {
nearestEnergy = levelManager->NearestLevelEnergy(daughterExcitation);
if (std::abs(daughterExcitation - nearestEnergy) < levelTolerance) {
if ((std::abs(daughterExcitation - nearestEnergy) < levelTolerance) && (std::abs(daughterExcitation - nearestEnergy) > DBL_EPSILON)) {
// Level half-life is in ns and the threshold is set to 1 micros
// by default, user can set it via the UI command
nearestLevelIndex = (G4int)levelManager->NearestLevelIndex(daughterExcitation);
+3
View File
@@ -6,6 +6,9 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2023-12-13 Ben Morgan (run-V11-01-11)
- Fix Issue #86: report number of threads from G4TaskRunManager correctly.
## 2023-11-17 I. Hrivnacova (run-V11-01-10)
- Do not call G4ParticleTable::WorkerG4ParticleTable() in
G4WorkerRunManager constructor as this function
+1 -1
View File
@@ -101,7 +101,7 @@ class G4TaskRunManager : public G4MTRunManager, public PTL::TaskRunManager
inline G4int GetNumberOfEventsPerTask() const { return numberOfEventsPerTask; }
void SetNumberOfThreads(G4int n) override;
G4int GetNumberOfThreads() const override { return PTL::TaskRunManager::GetNumberOfThreads(); }
G4int GetNumberOfThreads() const override;
size_t GetNumberActiveThreads() const override
{
return PTL::TaskRunManager::GetNumberActiveThreads();
+9
View File
@@ -212,6 +212,15 @@ void G4TaskRunManager::SetNumberOfThreads(G4int n)
//============================================================================//
G4int G4TaskRunManager::GetNumberOfThreads() const
{
// If the ThreadPool isn't initialized, it will return 0 even if we've already
// set nworkers
return poolInitialized ? PTL::TaskRunManager::GetNumberOfThreads() : nworkers;
}
//============================================================================//
void G4TaskRunManager::Initialize()
{
G4bool firstTime = (threadPool == nullptr);
+6 -1
View File
@@ -6,6 +6,11 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2023-12-11 Vladimir Ivanchenko (tracking-V11-01-03)
- G4TrackingMessenger - fixed Coverity report on memory leak at exit by
move static thread local variable to be class member, because G4TrackingManager
and its messenger are thread local by nature.
## 2023-09-04 Gabriele Cosmo (tracking-V11-01-02)
- Removed references to G4TouchableHistoryHandle, which is now deprecated.
@@ -23,7 +28,7 @@ It must **not** be used as a substitute for writing good git commit messages!
## 2022-11-02 Vladimir Ivanchenko (tracking-V11-00-07)
- G4SteppingManager - removed G4Exception with JustWarning severity
for the case if no active at rest processes exist - fix problem #2493
for the case if no active at rest processes exist - fix problem #2493
## 2022-06-21 Ben Morgan (tracking-V11-00-06)
- Merge `G4SteppingManager` implementation files
@@ -47,6 +47,7 @@ class G4UIcmdWithAnInteger;
class G4UIcmdWithABool;
class G4TrackingManager;
class G4SteppingManager;
class G4IdentityTrajectoryFilter;
class G4TrackingMessenger : public G4UImessenger
{
@@ -59,9 +60,9 @@ class G4TrackingMessenger : public G4UImessenger
private:
G4TrackingManager* trackingManager = nullptr;
G4SteppingManager* steppingManager = nullptr;
G4IdentityTrajectoryFilter* auxiliaryPointsFilter = nullptr;
// commands
G4UIdirectory* TrackingDirectory = nullptr;
G4UIcmdWithoutParameter* AbortCmd = nullptr;
G4UIcmdWithoutParameter* ResumeCmd = nullptr;
+5 -4
View File
@@ -105,6 +105,7 @@ G4TrackingMessenger::~G4TrackingMessenger()
delete ResumeCmd;
delete StoreTrajectoryCmd;
delete VerboseCmd;
delete auxiliaryPointsFilter;
}
///////////////////////////////////////////////////////////////////////////////
@@ -124,13 +125,13 @@ void G4TrackingMessenger::SetNewValue(G4UIcommand* command, G4String newValues)
G4UImanager::GetUIpointer()->ApplyCommand("/control/exit");
}
static G4ThreadLocal G4IdentityTrajectoryFilter* auxiliaryPointsFilter = nullptr;
if (auxiliaryPointsFilter == nullptr) {
auxiliaryPointsFilter = new G4IdentityTrajectoryFilter;
}
if (command == StoreTrajectoryCmd) {
G4int trajType = StoreTrajectoryCmd->ConvertToInt(newValues);
if (trajType == 2 || trajType == 4) {
if (nullptr == auxiliaryPointsFilter) {
auxiliaryPointsFilter = new G4IdentityTrajectoryFilter;
}
G4TransportationManager::GetTransportationManager()
->GetPropagatorInField()
->SetTrajectoryFilter(auxiliaryPointsFilter);