Import Geant4 11.4.0 source tree

This commit is contained in:
Gabriele Cosmo
2025-12-05 08:54:02 +01:00
parent a499fb82e9
commit b4a16de652
6484 changed files with 232674 additions and 221097 deletions
@@ -6,6 +6,43 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2025-10-18 Sebastien Incerti, Wook Geun Shin (emdna-V11-03-20)
- Extended G4DNAELSEPAElasticModel up to 10 MeV for water.
Requires G4EMLOW8.8
## 2025-10-10 Le Tuan Anh (emdna-V11-03-19)
- Changed the condition in calculateDistanceFromTimeStep
(G4ChemReboundTransportation) to allow calculate even with DiffusionCoefficient = 0.
## 2025-09-30 Vladimir Ivanchenko (emdna-V11-03-18)
- G4DNARuddIonisationDynamicModel - use G4ExtendedPhysicsVector for data,
results are unchanged, performance should be improved.
## 2025-09-22 Hoang Tran (emdna-V11-03-17)
- Fixed the state update in AlongStepDoIt (G4ChemReboundTransportation) to
avoid setting incorrect molecule positions (leading tracks) when the scavenger
process is called.
- Fixed the IRT_syn model (Stepper) to ensure it does not use minTimeStep (default = 1 ps)
when DNA reactions do not yet share the same minTimeStep(The MinTimeStep is
used to optimize the chemistry).
- Fixed the missed Equilibrium process (in G4DNAMakeReaction) for particle-based
models (SBS, IRT_syn).
- Deleted exception of no reactant (or reactions for the defined molecules) that
should return nullptr for no reaction data.
## 2025-09-10 Vladimir Ivanchenko (emdna-V11-03-16)
- for DNA Rudd and Born models enable atomic de-excitation in stationary regime.
## 2025-07-06 Vladimir Ivanchenko (emdna-V11-03-15)
- G4DNARuddIonisationDynamicModel - simplified model using alpha and alpha+ data
## 2025-07-23 Sebastien Incerti (emdna-V11-03-14)
- force cross section to zero below limit of validity of G4DNACPA100ElasticModel
## 2025-07-06 Vladimir Ivanchenko (emdna-V11-03-13)
- G4DNARuddIonisationDynamicModel - fixed problem in sampling of electron energy
- G4DNARuddIonisationExtendedModel - improved debug printout
## 2025-05-28 Hoang Tran (emdna-V11-03-12)
- Fixed COVERTY issues on new moleculecounter imple
@@ -41,8 +41,9 @@
class G4DNAChemistryManager;
class G4VAtomDeexcitation;
class G4DNACrossSectionDataSet;
class G4ExtendedPhysicsVector;
class G4Pow;
class G4EmCorrections;
class G4DNARuddIonisationDynamicModel : public G4VEmModel, public G4VSIntegration
{
@@ -119,18 +120,21 @@ private:
// Water density table
static const std::vector<G4double>* fpWaterDensity;
// data for protons
static G4DNACrossSectionDataSet* xsdata_hydrogen;
static G4DNACrossSectionDataSet* xsdata_helium;
static G4DNACrossSectionDataSet* xsdata_p;
// cross section data
static G4ExtendedPhysicsVector* xsdata_alpha;
static G4ExtendedPhysicsVector* xsdata_alphap;
static G4ExtendedPhysicsVector* xsdata_hydrogen;
static G4ExtendedPhysicsVector* xsdata_helium;
static G4ExtendedPhysicsVector* xsdata_p;
// run time data
G4DNACrossSectionDataSet* xsdata{nullptr};
G4ExtendedPhysicsVector* xsdata{nullptr};
const G4ParticleDefinition* fParticle{nullptr};
const G4Track* fTrack{nullptr};
G4DNAChemistryManager* fChemistry{nullptr};
G4EmCorrections* fEmCorrections;
G4Pow* fGpow;
//deexcitation manager to produce fluo photons and e-
@@ -148,7 +152,6 @@ private:
G4double slaterEffectiveCharge[3] = {0.0};
G4double sCoefficient[3] = {0.0};
G4double fTemp[5] = {0.0};
G4double F1{0.0};
G4double F2{0.0};
@@ -160,6 +163,7 @@ private:
G4int fSelectedShell{0};
G4int verbose{0};
std::size_t idx{0};
G4bool isFirst{false};
G4bool isInitialised{false};
@@ -169,8 +169,7 @@ void G4DNABornIonisationModel::Initialise(const G4ParticleDefinition* p,
statCode = G4EmParameters::Instance()->DNAStationary();
// initialise atomic de-excitation
if (!statCode)
fAtomDeexcitation = G4LossTableManager::Instance()->AtomDeexcitation();
fAtomDeexcitation = G4LossTableManager::Instance()->AtomDeexcitation();
// chemistry
auto chem = G4DNAChemistryManager::Instance();
@@ -183,7 +183,7 @@ G4double G4DNACPA100ElasticModel::CrossSectionPerVolume(const G4Material* pMater
if (ekin < fpModelData->GetHighELimit(materialID, p)) {
if (ekin < fKillBelowEnergy) {
return DBL_MAX;
return 0.;
}
auto tableData = fpModelData->GetData();
@@ -27,8 +27,8 @@
//
// Authors: D. Sakata, W.G. Shin, S. Incerti
//
// Based on a recent release of the ELSEPA code
// developed and provided kindly by F. Salvat et al.
// Based on a recent release of the ELSEPA code
// developed and provided kindly by F. Salvat et al.
// See
// Computer Physics Communications, 165(2), 157-190. (2005)
// http://dx.doi.org/10.1016/j.cpc.2004.09.006
@@ -48,21 +48,21 @@ using namespace std;
G4DNAELSEPAElasticModel::G4DNAELSEPAElasticModel(const G4ParticleDefinition*,
const G4String& nam) :
G4VEmModel(nam)
G4VEmModel(nam)
{
verboseLevel = 0;
G4ProductionCutsTable* theCoupleTable =
G4ProductionCutsTable::GetProductionCutsTable();
auto numOfCouples = (G4int)theCoupleTable->GetTableSize();
fpBaseWater = G4Material::GetMaterial("G4_WATER");
for(G4int i=0; i<numOfCouples; ++i)
{
const G4MaterialCutsCouple* couple =
theCoupleTable->GetMaterialCutsCouple(i);
const G4Material* material = couple->GetMaterial()->GetBaseMaterial();
if(!material) material = couple->GetMaterial();
@@ -86,7 +86,7 @@ G4VEmModel(nam)
}else{// Protection: H2O only is available
if(material==fpBaseWater){
flowEnergyLimit = 10. * eV;
fhighEnergyLimit = 1 * MeV;
fhighEnergyLimit = 10. * MeV;
SetLowEnergyLimit (flowEnergyLimit);
SetHighEnergyLimit(fhighEnergyLimit);
}else{
@@ -96,8 +96,8 @@ G4VEmModel(nam)
if (verboseLevel > 0)
{
G4cout << "ELSEPA Elastic model is constructed for "
<< material->GetName() << G4endl
G4cout << "ELSEPA Elastic model is constructed for "
<< material->GetName() << G4endl
<< "Energy range: "
<< flowEnergyLimit / eV << " eV - "
<< fhighEnergyLimit / MeV << " MeV"
@@ -143,11 +143,11 @@ const G4DataVector& )
FatalException,"Model not applicable to particle type.");
return;
}
G4ProductionCutsTable* theCoupleTable =
G4ProductionCutsTable::GetProductionCutsTable();
auto numOfCouples = (G4int)theCoupleTable->GetTableSize();
// UNIT OF TCS
G4double scaleFactor = 1.*cm*cm;
@@ -155,9 +155,9 @@ const G4DataVector& )
fpData_H2O=nullptr;
fpBaseWater = G4Material::GetMaterial("G4_WATER");
for(G4int i=0; i<numOfCouples; ++i)
for(G4int i=0; i<numOfCouples; ++i)
{
const G4MaterialCutsCouple* couple =
const G4MaterialCutsCouple* couple =
theCoupleTable->GetMaterialCutsCouple(i);
const G4Material* material = couple->GetMaterial()->GetBaseMaterial();
if(!material) material = couple->GetMaterial();
@@ -170,8 +170,8 @@ const G4DataVector& )
{
continue;
}
if (Z>0)
if (Z>0)
{
G4String fileZElectron("dna/sigma_elastic_e_elsepa_Z");
std::ostringstream oss;
@@ -184,7 +184,7 @@ const G4DataVector& )
eV,
scaleFactor );
fpData_Au->LoadData(fileZElectron);
std::ostringstream eFullFileNameZ;
const char *path = G4EmParameters::Instance()->GetDirLEDATA();
@@ -197,25 +197,25 @@ const G4DataVector& )
eFullFileNameZ.str("");
eFullFileNameZ.clear(stringstream::goodbit);
eFullFileNameZ
<< path
<< "/dna/sigmadiff_cumulated_elastic_e_elsepa_Z"
eFullFileNameZ
<< path
<< "/dna/sigmadiff_cumulated_elastic_e_elsepa_Z"
<< Z << "_muffintin.dat";
std::ifstream eDiffCrossSectionZ(eFullFileNameZ.str().c_str());
if (!eDiffCrossSectionZ)
{
G4Exception("G4DNAELSEPAElasticModel::Initialise","em0003",
FatalException,"Missing data file for cumulated DCS");
return;
}
eEdummyVec_Au.clear();
eCum_Au.clear();
fAngleData_Au.clear();
eEdummyVec_Au.push_back(0.);
do
{
@@ -233,7 +233,7 @@ const G4DataVector& )
eCum_Au[eDummy].push_back(cumDummy);
}
}while(!eDiffCrossSectionZ.eof());
}
}
}else{// Protection: H2O only is available
if(material == fpBaseWater && !fpData_H2O){
@@ -245,12 +245,12 @@ const G4DataVector& )
SetLowEnergyLimit(10.*eV);
}
if (HighEnergyLimit() > 1.*MeV)
if (HighEnergyLimit() > 10.*MeV)
{
G4cout<<"G4DNAELSEPAElasticModel: high energy limit decreased from "
<< HighEnergyLimit()/MeV << " MeV to " << 1. << " MeV"
<< HighEnergyLimit()/MeV << " MeV to " << 10. << " MeV"
<< G4endl;
SetHighEnergyLimit(1.*MeV);
SetHighEnergyLimit(10.*MeV);
}
G4String fileZElectron("dna/sigma_elastic_e_elsepa_muffin");
@@ -356,7 +356,7 @@ G4double G4DNAELSEPAElasticModel::CrossSectionPerVolume
{
// Protection: only for GOLD
if (material->GetZ()!=79) return 0.0;
const G4ElementVector* theElementVector = material->GetElementVector();
G4int Z = G4lrint((*theElementVector)[0]->GetZ());
@@ -377,11 +377,11 @@ G4double G4DNAELSEPAElasticModel::CrossSectionPerVolume
G4cout << "__________________________________" << G4endl;
G4cout << "=== G4DNAELSEPAElasticModel - XS INFO START" << G4endl;
G4cout << "=== Material is made of one element with Z =" << Z << G4endl;
G4cout << "=== Kinetic energy(eV)=" << ekin/eV << " particle : "
G4cout << "=== Kinetic energy(eV)=" << ekin/eV << " particle : "
<< particleName << G4endl;
G4cout << "=== Cross section per atom for Z="<<Z<<" is (cm^2)"
G4cout << "=== Cross section per atom for Z="<<Z<<" is (cm^2)"
<< sigma/cm/cm << G4endl;
G4cout << "=== Cross section per atom for Z="<<Z<<" is (cm^-1)="
G4cout << "=== Cross section per atom for Z="<<Z<<" is (cm^-1)="
<< sigma*atomicNDensity/(1./cm) << G4endl;
G4cout << "=== G4DNAELSEPAElasticModel - XS INFO END" << G4endl;
}
@@ -400,11 +400,11 @@ G4double G4DNAELSEPAElasticModel::CrossSectionPerVolume
{
G4cout << "__________________________________" << G4endl;
G4cout << "=== G4DNAELSEPAElasticModel - XS INFO START" << G4endl;
G4cout << "=== Kinetic energy(eV)=" << ekin/eV
G4cout << "=== Kinetic energy(eV)=" << ekin/eV
<< " particle : " << particle->GetParticleName() << G4endl;
G4cout << "=== Cross section per water molecule (cm^2)="
G4cout << "=== Cross section per water molecule (cm^2)="
<< sigma/cm/cm << G4endl;
G4cout << "=== Cross section per water molecule (cm^-1)="
G4cout << "=== Cross section per water molecule (cm^-1)="
<< sigma*atomicNDensity/(1./cm) << G4endl;
G4cout << "=== G4DNAELSEPAElasticModel - XS INFO END" << G4endl;
}
@@ -424,8 +424,8 @@ void G4DNAELSEPAElasticModel::SampleSecondaries(
{
if (verboseLevel > 3){
G4cout <<
"Calling SampleSecondaries() of G4DNAELSEPAElasticModel"
G4cout <<
"Calling SampleSecondaries() of G4DNAELSEPAElasticModel"
<< G4endl;
}
@@ -433,7 +433,7 @@ void G4DNAELSEPAElasticModel::SampleSecondaries(
const G4Material* material = couple->GetMaterial()->GetBaseMaterial();
if(!material) material = couple->GetMaterial();
std::size_t nelm = material->GetNumberOfElements();
if (nelm==1) // Protection: only for single element
{
@@ -457,12 +457,12 @@ void G4DNAELSEPAElasticModel::SampleSecondaries(
cosTheta = RandomizeCosTheta(Z,electronEnergy0);
}
else
{
{
cosTheta = RandomizeCosTheta(Z,10*eV);
}
G4double phi = 2. * CLHEP::pi * G4UniformRand();
G4ThreeVector zVers = aDynamicElectron->GetMomentumDirection();
G4ThreeVector xVers = zVers.orthogonal();
G4ThreeVector yVers = zVers.cross(xVers);
@@ -475,7 +475,7 @@ void G4DNAELSEPAElasticModel::SampleSecondaries(
G4ThreeVector zPrimeVers((xDir*xVers + yDir*yVers + cosTheta*zVers));
fParticleChangeForGamma->ProposeMomentumDirection(zPrimeVers.unit());
fParticleChangeForGamma->SetProposedKineticEnergy(electronEnergy0);
}
}
else
@@ -545,10 +545,10 @@ G4double G4DNAELSEPAElasticModel::Theta(G4int Z,
cum12 = std::upper_bound(eCum_Au[(*e1)].begin(),
eCum_Au[(*e1)].end(),integrDiff);
}
auto cum11 = cum12 - 1;
//std::vector<G4double>::iterator cum22
//std::vector<G4double>::iterator cum22
// = std::upper_bound(eCumZ[Z][(*e2)].begin(),
// eCumZ[Z][(*e2)].end(),integrDiff);
std::vector<G4double>::iterator cum22;
@@ -559,7 +559,7 @@ G4double G4DNAELSEPAElasticModel::Theta(G4int Z,
cum22 = std::upper_bound(eCum_Au[(*e2)].begin(),
eCum_Au[(*e2)].end(),integrDiff);
}
auto cum21 = cum22 - 1;
valueE1 = *e1;
@@ -585,7 +585,7 @@ G4double G4DNAELSEPAElasticModel::Theta(G4int Z,
if (a11 == 0 && a12 == 0 && a21 == 0 && a22 == 0) return (0.);
theta = QuadInterpolator(valuecum11, valuecum12, valuecum21, valuecum22,
theta = QuadInterpolator(valuecum11, valuecum12, valuecum21, valuecum22,
a11, a12,a21, a22, valueE1, valueE2, k, integrDiff);
return theta;
}
@@ -708,7 +708,7 @@ G4double G4DNAELSEPAElasticModel::RandomizeCosTheta(G4int Z, G4double k)
G4double cosTheta = 0.;
theta = Theta(Z, G4Electron::ElectronDefinition(), k / eV, integrdiff);
cosTheta = std::cos(theta * CLHEP::pi / 180.);
cosTheta = std::cos(theta * CLHEP::pi / 180.);
return cosTheta;
}
@@ -178,9 +178,14 @@ G4double G4DNAIndependentReactionTimeStepper::CalculateStep(const G4Track& track
continue;
}
fSampledMinTimeStep = tempMinET;
if (tempMinET < fUserMinTimeStep) {
fSampledMinTimeStep = fUserMinTimeStep;
}
// Fixed the IRT_syn model (Stepper) to ensure it does not use minTimeStep (default = 1 ps)
// when DNA reactions do not yet share
// the same minTimeStep(The MinTimeStep is used to optimize the chemistry).
// TODO: full test
//if (tempMinET < fUserMinTimeStep) {
// fSampledMinTimeStep = fUserMinTimeStep;
//}
}
CheckAndRecordResults(fSampledMinTimeStep, utils);
}
@@ -87,6 +87,9 @@ G4DNAMakeReaction::MakeReaction(const G4Track &trackA,
const auto pReactionData = fMolReactionTable->GetReactionData(pMoleculeA, pMoleculeB);
const G4int nbProducts = pReactionData->GetNbProducts();
//add Equilibrium process for particle-based models.
if(fpScavengerMaterial != nullptr) { fpScavengerMaterial->SetEquilibrium(pReactionData, trackA.GetGlobalTime()); }
// Notify molecule (reaction) counter
if (G4MoleculeCounterManager::Instance()->GetIsActive()) {
G4MoleculeCounterManager::Instance()->RecordReaction(pReactionData, trackA.GetGlobalTime());
@@ -35,14 +35,17 @@
#include "G4VAtomDeexcitation.hh"
#include "G4UAtomicDeexcitation.hh"
#include "G4LossTableManager.hh"
#include "G4EmCorrections.hh"
#include "G4NistManager.hh"
#include "G4DNAChemistryManager.hh"
#include "G4DNAMolecularMaterial.hh"
#include "G4LogLogInterpolation.hh"
#include "G4ProductionCutsTable.hh"
#include "G4DNAGenericIonsManager.hh"
#include "G4DNACrossSectionDataSet.hh"
#include "G4MatUtils.hh"
#include "G4ExtendedPhysicsVector.hh"
#include "G4EmParameters.hh"
#include "G4NistManager.hh"
#include "G4IonTable.hh"
@@ -57,9 +60,11 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4DNACrossSectionDataSet* G4DNARuddIonisationDynamicModel::xsdata_hydrogen = nullptr;
G4DNACrossSectionDataSet* G4DNARuddIonisationDynamicModel::xsdata_helium = nullptr;
G4DNACrossSectionDataSet* G4DNARuddIonisationDynamicModel::xsdata_p = nullptr;
G4ExtendedPhysicsVector* G4DNARuddIonisationDynamicModel::xsdata_alpha = nullptr;
G4ExtendedPhysicsVector* G4DNARuddIonisationDynamicModel::xsdata_alphap = nullptr;
G4ExtendedPhysicsVector* G4DNARuddIonisationDynamicModel::xsdata_hydrogen = nullptr;
G4ExtendedPhysicsVector* G4DNARuddIonisationDynamicModel::xsdata_helium = nullptr;
G4ExtendedPhysicsVector* G4DNARuddIonisationDynamicModel::xsdata_p = nullptr;
const std::vector<G4double>* G4DNARuddIonisationDynamicModel::fpWaterDensity = nullptr;
namespace
@@ -79,6 +84,7 @@ G4DNARuddIonisationDynamicModel::G4DNARuddIonisationDynamicModel(const G4Particl
const G4String& nam)
: G4VEmModel(nam)
{
fEmCorrections = G4LossTableManager::Instance()->EmCorrections();
fGpow = G4Pow::GetInstance();
fLowestEnergy = 100*CLHEP::eV;
fAbsorptionEnergy = 50*CLHEP::eV;
@@ -100,6 +106,8 @@ G4DNARuddIonisationDynamicModel::G4DNARuddIonisationDynamicModel(const G4Particl
G4DNARuddIonisationDynamicModel::~G4DNARuddIonisationDynamicModel()
{
if (isFirst) {
delete xsdata_alpha;
delete xsdata_alphap;
delete xsdata_p;
delete xsdata_hydrogen;
delete xsdata_helium;
@@ -111,17 +119,27 @@ G4DNARuddIonisationDynamicModel::~G4DNARuddIonisationDynamicModel()
void G4DNARuddIonisationDynamicModel::LoadData()
{
// initialisation of static data once
G4String filename = "dna/sigma_ionisation_p_rudd";
xsdata_p = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, CLHEP::eV, scaleFactor);
xsdata_p->LoadData(filename);
const G4String& dirpath = G4EmParameters::Instance()->GetDirLEDATA();
filename = "dna/sigma_ionisation_h_rudd";
xsdata_hydrogen = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, CLHEP::eV, scaleFactor);
xsdata_hydrogen->LoadData(filename);
G4String filename = "dna/sigma_ionisation_p_rudd.dat";
xsdata_p =
G4MatUtils::BuildExtendedVector(dirpath, filename, 5, 645, CLHEP::eV, scaleFactor);
filename = "dna/sigma_ionisation_he_rudd";
xsdata_helium = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, CLHEP::eV, scaleFactor);
xsdata_helium->LoadData(filename);
filename = "dna/sigma_ionisation_alphaplusplus_rudd.dat";
xsdata_alpha =
G4MatUtils::BuildExtendedVector(dirpath, filename, 5, 540, CLHEP::eV, scaleFactor);
filename = "dna/sigma_ionisation_alphaplus_rudd.dat";
xsdata_alphap =
G4MatUtils::BuildExtendedVector(dirpath, filename, 5, 540, CLHEP::eV, scaleFactor);
filename = "dna/sigma_ionisation_h_rudd.dat";
xsdata_hydrogen =
G4MatUtils::BuildExtendedVector(dirpath, filename, 5, 600, CLHEP::eV, scaleFactor);
filename = "dna/sigma_ionisation_he_rudd.dat";
xsdata_helium =
G4MatUtils::BuildExtendedVector(dirpath, filename, 5, 540, CLHEP::eV, scaleFactor);
// to avoid possible threading problem fill this vector only once
auto water = G4NistManager::Instance()->FindMaterial("G4_WATER");
@@ -168,6 +186,7 @@ void G4DNARuddIonisationDynamicModel::Initialise(const G4ParticleDefinition* p,
fLowestEnergy = 1*CLHEP::keV;
} else if (pname == "alpha+") {
isHelium = true;
xsdata = xsdata_alphap;
// The following values are provided by M. Dingfelder (priv. comm)
slaterEffectiveCharge[0]=2.0;
slaterEffectiveCharge[1]=2.0;
@@ -175,16 +194,21 @@ void G4DNARuddIonisationDynamicModel::Initialise(const G4ParticleDefinition* p,
sCoefficient[0]=0.7;
sCoefficient[1]=0.15;
sCoefficient[2]=0.15;
} else if (pname == "alpha") {
isHelium = true;
xsdata = xsdata_alpha;
} else if (pname == "hydrogen") {
xsdata = xsdata_hydrogen;
} else if (pname != "proton") {
isIon = true;
}
if (isHelium) { fLowestEnergy = 1*CLHEP::keV; }
// defined stationary mode
statCode = G4EmParameters::Instance()->DNAStationary();
// initialise atomic de-excitation
if (!statCode)
fAtomDeexcitation = G4LossTableManager::Instance()->AtomDeexcitation();
fAtomDeexcitation = G4LossTableManager::Instance()->AtomDeexcitation();
// chemistry
auto chem = G4DNAChemistryManager::Instance();
@@ -192,7 +216,7 @@ void G4DNARuddIonisationDynamicModel::Initialise(const G4ParticleDefinition* p,
fChemistry = chem;
}
InitialiseIntegrator(0.1, 0.25, 1.05, 1*CLHEP::eV, 0.2*CLHEP::eV, 10*CLHEP::keV);
InitialiseIntegrator(0.1, 0.25, 1.05, 4*CLHEP::eV, 0.2*CLHEP::eV, 10*CLHEP::keV);
if (verbose > 0) {
G4cout << "### G4DNARuddIonisationDynamicModel::Initialise(..) "
@@ -207,7 +231,10 @@ void G4DNARuddIonisationDynamicModel::SetParticle(const G4ParticleDefinition* p)
{
fParticle = p;
fMass = p->GetPDGMass();
fMassRate = CLHEP::proton_mass_c2/fMass;
if (isIon) {
fMassRate = CLHEP::proton_mass_c2/fMass;
fMass = CLHEP::proton_mass_c2;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -235,19 +262,17 @@ G4DNARuddIonisationDynamicModel::CrossSectionPerVolume(const G4Material* materia
// ion may be different
if (fParticle != part) { SetParticle(part); }
G4double q = fTrack->GetDynamicParticle()->GetCharge()*inveplus;
// cross section for scaled energy
G4double e = kinE*fMassRate;
auto xs = xsdata;
if (0.0 == q) { xs = isHelium ? xsdata_helium : xsdata_hydrogen; }
G4double sigma = (e > fLowestEnergy) ? xs->FindValue(e)
: xs->FindValue(fLowestEnergy) * e / fLowestEnergy;
G4double sigma = (e > fLowestEnergy) ? xsdata->LogLogValue(e, idx)
: xsdata->LogLogValue(fLowestEnergy, idx) * e / fLowestEnergy;
sigma *= density;
if (q > 1.5) { sigma *= q * q; }
if (isIon) {
sigma *= fEmCorrections->EffectiveChargeSquareRatio(part, material, kinE);
}
if (verbose > 1) {
G4cout << "G4DNARuddIonisationDynamicModel for " << part->GetParticleName()
@@ -323,7 +348,11 @@ G4DNARuddIonisationDynamicModel::SampleSecondaries(std::vector<G4DynamicParticle
<< G4endl;
}
scatteredEnergy = std::max(scatteredEnergy, 0.0);
/*
G4cout << "Eprim(keV)=" << kinE/CLHEP::keV << " Efin(keV)=" << scatteredEnergy/CLHEP::keV
<< " Esec(keV)=" << esec/CLHEP::keV << " Exc(keV)=" << exc/CLHEP::keV
<< " tolerance(keV)=" << tolerance/CLHEP::keV << G4endl;
*/
// projectile
if (!statCode) {
fParticleChangeForGamma->SetProposedKineticEnergy(scatteredEnergy);
@@ -347,20 +376,7 @@ G4DNARuddIonisationDynamicModel::SampleSecondaries(std::vector<G4DynamicParticle
G4int G4DNARuddIonisationDynamicModel::SelectShell()
{
G4double sum = 0.0;
G4double xs;
for (G4int i=0; i<5; ++i) {
auto ptr = xsdata->GetComponent(i);
xs = (fScaledEnergy > fLowestEnergy) ? ptr->FindValue(fScaledEnergy)
: ptr->FindValue(fLowestEnergy)*fScaledEnergy/fLowestEnergy;
sum += xs;
fTemp[i] = sum;
}
sum *= G4UniformRand();
for (G4int i=0; i<5; ++i) {
if (sum <= fTemp[i]) { return i; }
}
return 0;
return xsdata->SampleReactionChannel(fScaledEnergy, G4UniformRand(), idx);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -369,7 +385,7 @@ G4double
G4DNARuddIonisationDynamicModel::MaxEnergy()
{
// kinematic limit
G4double tau = fScaledEnergy/CLHEP::proton_mass_c2;
G4double tau = fScaledEnergy/fMass;
G4double gam = 1.0 + tau;
G4double emax = 2.0*CLHEP::electron_mass_c2*tau*(tau + 2.0);
@@ -431,6 +447,7 @@ G4DNARuddIonisationDynamicModel::SampleElectronEnergy()
G4cout << "G4DNARuddIonisationDynamicModel::SampleElectronEnergy: "
<< fParticle->GetParticleName()
<< " Escaled(keV)=" << fScaledEnergy/CLHEP::keV << " Ee(keV)=" << e/CLHEP::keV
<< " Emax(keV)=" << emax/CLHEP::keV << " shell=" << fSelectedShell
<< G4endl;
}
return e;
@@ -540,13 +557,13 @@ G4double G4DNARuddIonisationDynamicModel::Rh(G4double ekin, G4double etrans,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4DNARuddIonisationDynamicModel::CorrectionFactor()
G4double G4DNARuddIonisationDynamicModel::CorrectionFactor()
{
// ZF Shortened
G4double res = 1.0;
if (fSelectedShell < 4) {
const G4double ln10 = fGpow->logZ(10);
G4double x = 2.0*((G4Log(fScaledEnergy/CLHEP::eV)/ln10) - 4.2);
G4double x = 2.0*((G4Log(fScaledEnergy/(fMassRate*CLHEP::eV))/ln10) - 4.2);
// The following values are provided by M. Dingfelder (priv. comm)
res = 0.6/(1.0 + G4Exp(x)) + 0.9;
}
@@ -222,8 +222,7 @@ void G4DNARuddIonisationExtendedModel::Initialise(const G4ParticleDefinition* p,
statCode = G4EmParameters::Instance()->DNAStationary();
// initialise atomic de-excitation
if (!statCode)
fAtomDeexcitation = G4LossTableManager::Instance()->AtomDeexcitation();
fAtomDeexcitation = G4LossTableManager::Instance()->AtomDeexcitation();
if (verbose > 0) {
G4cout << "### G4DNARuddIonisationExtendedModel::Initialise(..) " << pname
@@ -343,7 +342,11 @@ G4DNARuddIonisationExtendedModel::SampleSecondaries(std::vector<G4DynamicParticl
<< G4endl;
}
scatteredEnergy = std::max(scatteredEnergy, 0.0);
/*
G4cout << "Eprim(keV)=" << kinE/CLHEP::keV << " Efin(keV)=" << scatteredEnergy/CLHEP::keV
<< " Esec(keV)=" << esec/CLHEP::keV << " Exc(keV)=" << exc/CLHEP::keV
<< " tolerance(keV)=" << tolerance/CLHEP::keV << G4endl;
*/
// projectile
if (!statCode) {
fParticleChangeForGamma->SetProposedKineticEnergy(scatteredEnergy);
@@ -449,8 +452,6 @@ G4double G4DNARuddIonisationExtendedModel::SampleElectronEnergy(G4double kine,
// find max probability
G4double pmax = ProbabilityFunction(kine, 0.0, shell);
//G4cout << "## E(keV)=" << kine/keV << " emax=" << emax/keV
// << " pmax(0)=" << pmax << " shell=" << shell << " nn=" << nn << G4endl;
G4double e0 = 0.0; // energy with max probability
// 2 areas after point with max probability
@@ -26,7 +26,7 @@
#ifndef G4MOLECULECOUNTERTIMECOMPARER_HH
#define G4MOLECULECOUNTERTIMECOMPARER_HH 1
#include "G4SystemOfUnits.hh"
#include <CLHEP/Units/PhysicalConstants.h>
#include "G4Types.hh"
#include <map>
@@ -58,7 +58,7 @@ class G4MoleculeCounterTimeComparer
private:
TimeComparerType fType;
G4double fPrecision{1 * picosecond};
G4double fPrecision{1 * CLHEP::picosecond};
std::map<G4double, G4double> fVariablePrecision{};
public: // Factory
@@ -26,6 +26,7 @@
// Author: Christian Velten (2025)
#include "G4VMoleculeCounterInternalBase.hh"
#include "G4SystemOfUnits.hh"
namespace G4
{
@@ -125,7 +125,7 @@ void G4ChemReboundTransportation::ComputeStep(const G4Track& track, const G4Step
spaceStep = 0.;
}
else {
auto molConf = GetMolecule(track)->GetMolecularConfiguration();
const auto molConf = GetMolecule(track)->GetMolecularConfiguration();
spaceStep = calculateDistanceFromTimeStep(molConf, timeStep);
}
State(fTransportEndPosition) =
@@ -240,7 +240,8 @@ G4double G4ChemReboundTransportation::AlongStepGetPhysicalInteractionLength(
geometryStepLength = calculateDistanceFromTimeStep(molConf, State(theInteractionTimeLeft));
State(fTransportEndPosition) =
geometryStepLength * track.GetMomentumDirection() + track.GetPosition();
BouncingAction(track.GetPosition() + geometryStepLength * G4RandomDirection());
State(fTimeStepReachedLimit) = true;
State(fCandidateEndGlobalTime) = track.GetGlobalTime() + State(theInteractionTimeLeft);
State(fEndGlobalTimeComputed) = true;
@@ -261,29 +262,33 @@ G4VParticleChange* G4ChemReboundTransportation::AlongStepDoIt(const G4Track& tra
const G4Step& step)
{
if (GetIT(track)->GetTrackingInfo()->IsLeadingStep()) {
G4double spaceStep = DBL_MAX;
auto molConf = GetMolecule(track)->GetMolecularConfiguration();
spaceStep = calculateDistanceFromTimeStep(molConf, State(theInteractionTimeLeft));
// Hoang fixed: - Fixed the state update in AlongStepDoIt (G4ChemReboundTransportation) to
// avoid setting incorrect molecule positions (leading tracks)
// when the scavenger process is called.
State(fGeometryLimitedStep) = false;
State(fTransportEndPosition) =
BouncingAction(track.GetPosition() + spaceStep * G4RandomDirection());
State(fEndPointDistance) = spaceStep;
// G4double spaceStep = DBL_MAX;
// const auto molConf = GetMolecule(track)->GetMolecularConfiguration();
// spaceStep = calculateDistanceFromTimeStep(molConf, State(theInteractionTimeLeft));
// State(fGeometryLimitedStep) = false;
// State(fTransportEndPosition) =
// BouncingAction(track.GetPosition() + spaceStep * G4RandomDirection());
// State(fEndPointDistance) = spaceStep;
if (fVerboseLevel > 1)
// if(GetMolecule(track)->GetName() == "e_aq^-1")
{
G4cout << "ChemReboundTransportation::AlongStepDoIt() :" << " trackID : "
<< track.GetTrackID()
<< " Molecule name: " << "prePosition : " << step.GetPreStepPoint()->GetPosition()
<< " postPostion : " << step.GetPostStepPoint()->GetPosition() << " "
<< GetMolecule(track)->GetName() << " State(theInteractionTimeLeft) : "
<< G4BestUnit(State(theInteractionTimeLeft), "Time")
<< " Diffusion length : " << G4BestUnit(step.GetStepLength(), "Length")
<< " within time step : " << G4BestUnit(step.GetDeltaTime(), "Time")
<< "\t Current global time : " << G4BestUnit(track.GetGlobalTime(), "Time")
<< " track.GetMomentumDirection() : " << track.GetMomentumDirection() << G4endl;
}
//if(GetMolecule(track)->GetName() == "e_aq^-1")
{
G4cout << "G4DNABrownianTransportation::AlongStepDoIt() : IsLeadingStep " << " trackID : "
<< track.GetTrackID()
<< "position : "<<track.GetPosition()
<< " Molecule name: "
<< GetMolecule(track)->GetName()<< "State(fTransportEndPosition) : "<<State(fTransportEndPosition) << " State(theInteractionTimeLeft) : "
<< G4BestUnit(State(theInteractionTimeLeft), "Time")
<< " Diffusion length : " << G4BestUnit(step.GetStepLength(), "Length")
<< " within time step : " << G4BestUnit(step.GetDeltaTime(), "Time")
<< "\t Current global time : " << G4BestUnit(track.GetGlobalTime(), "Time")
<< " track.GetMomentumDirection() : " << track.GetMomentumDirection()<<" GetIT(track)->GetTrackingInfo()->IsLeadingStep() : "<<GetIT(track)->GetTrackingInfo()->IsLeadingStep() << G4endl;
//throw;
}
}
G4ITTransportation::AlongStepDoIt(track, step);
@@ -353,7 +358,7 @@ G4double G4ChemReboundTransportation::calculateNextCoordinate(G4double nextPos,
G4double G4ChemReboundTransportation::calculateDistanceFromTimeStep(MolConf mol, G4double timeStep)
{
G4double diffuCoeff = mol->GetDiffusionCoefficient();
if (mol->GetDiffusionCoefficient() <= 0) {
if (mol->GetDiffusionCoefficient() < 0) {
G4ExceptionDescription exceptionDescription;
exceptionDescription << "GetDiffusionCoefficient is negative";
G4Exception("ChemReboundTransportation::calculateDistanceFromTimeStep",
@@ -36,6 +36,7 @@
// -------------------------------------------------------------------
#include "G4DNAElectronSolvation.hh"
#include "G4SystemOfUnits.hh"
#include "G4Electron.hh"
#include "G4DNAWaterExcitationStructure.hh"
#include "G4LowEnergyEmProcessSubType.hh"
@@ -616,12 +616,13 @@ G4DNAMolecularReactionTable::GetReactionData(Reactant* pReactant1,
if (it1 == fReactionData.end())
{
G4String errMsg =
"No reaction table was implemented for this molecule Definition : " + pReactant1
->GetName();
G4Exception("G4MolecularInteractionTable::GetReactionData", "",
FatalErrorInArgument, errMsg);
// Though the above is Fatal and will terminate program, put return in to quieten Coverity
if (fVerbose) {
G4ExceptionDescription errMsg;
errMsg << "No reaction table was implemented for this molecule Definition : "
+ pReactant1->GetName();
G4Exception(G4String("G4MolecularInteractionTable::GetReactionData"),
"", JustWarning, errMsg);
}
return nullptr;
}
@@ -629,10 +630,9 @@ G4DNAMolecularReactionTable::GetReactionData(Reactant* pReactant1,
if (it2 == it1->second.end())
{
G4cout << "Name : " << pReactant2->GetName() << G4endl;
G4String errMsg = "No reaction table was implemented for this molecule : "
+ pReactant2->GetName();
G4Exception("G4MolecularInteractionTable::GetReactionData", "", FatalErrorInArgument, errMsg);
//no reactant should return nullptr reaction data (not an exception).
//This helps UI chemistry
return nullptr;
}
return (it2->second);
@@ -751,10 +751,13 @@ G4DNAMolecularReactionTable::GetReactionData(const G4MolecularConfiguration* mol
if (it == fReactionDataMV.end())
{
G4String errMsg = "No reaction table was implemented for this molecule Definition : "
+ molecule->GetName();
G4Exception("G4MolecularInteractionTable::GetReactionData", "", FatalErrorInArgument, errMsg);
// Though the above is Fatal and will terminate program, put return in to quieten Coverity
if (fVerbose) {
G4ExceptionDescription errMsg;
errMsg << "No reaction table was implemented for this molecule Definition : "
+ molecule->GetName();
G4Exception(G4String("G4MolecularInteractionTable::GetReactionData"),
"", JustWarning, errMsg);
}
return nullptr;
}