Import Geant4 11.1.0.beta source tree

This commit is contained in:
Gabriele Cosmo
2022-07-01 10:44:02 +02:00
parent b3bf75a2a1
commit c07cea1fe0
2172 changed files with 183300 additions and 123938 deletions
+71 -3
View File
@@ -1,13 +1,11 @@
# - G4processes category build
# Add (private) allocation export symbol for the EM category
add_definitions(-DG4EM_ALLOC_EXPORT)
# Add (private) allocation export symbol for the hadronic category
add_definitions(-DG4HADRONIC_ALLOC_EXPORT)
geant4_global_library_target(NAME G4processes
COMPONENTS
foreach(modfile
biasing/management/sources.cmake
biasing/generic/sources.cmake
biasing/importance/sources.cmake
@@ -74,4 +72,74 @@ geant4_global_library_target(NAME G4processes
parameterisation/sources.cmake
scoring/sources.cmake
transportation/sources.cmake)
include(${modfile})
endforeach()
geant4_add_category(G4processes
MODULES
G4biasing_mgt
G4biasing_gen
G4biasing_imp
G4cuts
G4decay
G4emadjoint
G4emdna-processes
G4emdna-models
G4emdna-utils
G4emdna-man
G4emdna-molman
G4emdna-moltypes
G4emhighenergy
G4emlowenergy
G4muons
G4empii
G4empolar
G4emstandard
G4emutils
G4xrays
G4hadronic_xsect
G4hadronic_mgt
G4hadronic_abla
G4hadronic_abrasion
G4hadronic_binary
G4hadronic_bert_cascade
G4hadronic_coherent_elastic
G4hadronic_ablation
G4hadronic_deex_evaporation
G4hadronic_deex_fermi_breakup
G4hadronic_deex_fission
G4hadronic_deex_gem_evaporation
G4hadronic_deex_handler
G4hadronic_deex_management
G4hadronic_deex_multifragmentation
G4hadronic_deex_photon_evaporation
G4hadronic_deex_util
G4hadronic_em_dissociation
G4had_fission
G4had_im_r_matrix
G4hadronic_inclxx_utils
G4hadronic_inclxx_physics
G4hadronic_inclxx_interface
G4had_gamma_nuclear
G4had_lend
G4had_lept_nuclear
G4had_par_hp
G4had_string_diff
G4had_string_frag
G4had_string_man
G4hadronic_qgstring
G4had_preequ_exciton
G4hadronic_qmd
G4hadronic_quasi_elastic
G4hadronic_radioactivedecay
G4had_theo_max
G4hadronic_proc
G4hadronic_stop
G4hadronic_util
G4procman
G4optical
G4solidstate_phonon
G4solidstate_channeling
G4parameterisation
G4scoring
G4transportation )
+13 -14
View File
@@ -1,20 +1,19 @@
-------------------------------------------------------------------
# Category processes History
=========================================================
Geant4 - an Object-Oriented Toolkit for Simulation in HEP
=========================================================
See `CONTRIBUTING.rst` for details of **required** info/format for each entry,
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!
Category History file
---------------------
This file should be used by G4 developers and category coordinators
to briefly summarize all major modifications introduced in the code
and keep track of all category-tags.
It DOES NOT substitute the CVS log-message one should put at every
committal in the CVS repository !
## 2022-01-28 Ben Morgan (processes-V11-00-01)
- Replace `geant4_global_library_target` with direct file inclusion and
call to `geant4_add_category` to define library build from source modules.
----------------------------------------------------------
* Reverse chronological order (last date on top), please *
----------------------------------------------------------
## 2021-12-10 Ben Morgan (processes-V11-00-00)
- Change to new Markdown History format
---
# History entries prior to 11.0
October 25, 2021 (processes-V10-07-05)
- Use G4StrUtil functions replacing deprecated G4String member functions
+10 -14
View File
@@ -1,20 +1,16 @@
-------------------------------------------------------------------
# Category procbiasing History
=========================================================
Geant4 - an Object-Oriented Toolkit for Simulation in HEP
=========================================================
See `CONTRIBUTING.rst` for details of **required** info/format for each entry,
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!
Category History file
---------------------
This file should be used by G4 developers and category coordinators
to briefly summarize all major modifications introduced in the code
and keep track of all category-tags.
It DOES NOT substitute the CVS log-message one should put at every
committal in the CVS repository !
----------------------------------------------------------
* Reverse chronological order (last date on top), please *
----------------------------------------------------------
## 2021-12-10 Ben Morgan (procbiasing-V11-00-00)
- Change to new Markdown History format
---
# History entries prior to 11.0
April 16th, 2021 Ben Morgan (procbiasing-V10-07-00)
- Migrate build to modular CMake API
+10 -14
View File
@@ -1,20 +1,16 @@
-------------------------------------------------------------------
# Category proc-biasgen History
=========================================================
Geant4 - an Object-Oriented Toolkit for Simulation in HEP
=========================================================
See `CONTRIBUTING.rst` for details of **required** info/format for each entry,
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!
Category History file
---------------------
This file should be used by G4 developers and category coordinators
to briefly summarize all major modifications introduced in the code
and keep track of all category-tags.
It DOES NOT substitute the CVS log-message one should put at every
committal in the CVS repository !
----------------------------------------------------------
* Reverse chronological order (last date on top), please *
----------------------------------------------------------
## 2021-12-10 Ben Morgan (proc-biasgen-V11-00-00)
- Change to new Markdown History format
---
# History entries prior to 11.0
August 4, 2021 A. Ribon
- G4BOptrForceCollision : migrated to the new version of G4PhysicsModelCatalog
+10 -14
View File
@@ -1,20 +1,16 @@
-------------------------------------------------------------------
# Category proc-biasimp History
=========================================================
Geant4 - an Object-Oriented Toolkit for Simulation in HEP
=========================================================
See `CONTRIBUTING.rst` for details of **required** info/format for each entry,
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!
Category History file
---------------------
This file should be used by G4 developers and category coordinators
to briefly summarize all major modifications introduced in the code
and keep track of all category-tags.
It DOES NOT substitute the CVS log-message one should put at every
committal in the CVS repository !
----------------------------------------------------------
* Reverse chronological order (last date on top), please *
----------------------------------------------------------
## 2021-12-10 Ben Morgan (proc-biasimp-V11-00-00)
- Change to new Markdown History format
---
# History entries prior to 11.0
April 16th, 2021 B. Morgan
- Migrate build to modular CMake API
+10 -14
View File
@@ -1,20 +1,16 @@
-------------------------------------------------------------------
# Category proc-biasmng History
=========================================================
Geant4 - an Object-Oriented Toolkit for Simulation in HEP
=========================================================
See `CONTRIBUTING.rst` for details of **required** info/format for each entry,
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!
Category History file
---------------------
This file should be used by G4 developers and category coordinators
to briefly summarize all major modifications introduced in the code
and keep track of all category-tags.
It DOES NOT substitute the CVS log-message one should put at every
committal in the CVS repository !
----------------------------------------------------------
* Reverse chronological order (last date on top), please *
----------------------------------------------------------
## 2021-12-10 Ben Morgan (proc-biasmng-V11-00-00)
- Change to new Markdown History format
---
# History entries prior to 11.0
April 16th, 2021 B. Morgan
- Migrate build to modular CMake API
+21 -16
View File
@@ -1,29 +1,34 @@
-------------------------------------------------------------------
# Category proccuts History
=========================================================
Geant4 - an Object-Oriented Toolkit for Simulation in HEP
=========================================================
See `CONTRIBUTING.rst` for details of **required** info/format for each entry,
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!
Category History file
---------------------
This file should be used by G4 developers and category coordinators
to briefly summarize all major modifications introduced in the code
and keep track of all category-tags.
It DOES NOT substitute the CVS log-message one should put at every
committal in the CVS repository !
## 2022-06-13 Sergio Losilla (proccuts-V11-00-04)
- Added warning when trying to set cuts for particles other than
gamma, e-, e+ or proton.
----------------------------------------------------------
* Reverse chronological order (last date on top), please *
----------------------------------------------------------
## 2022-05-07 Vladimir Ivantchenko (proccuts-V11-00-03)
- G4VRangeToEnergyConverter - fixed static methods to provide
initialisation of energy limits independently on order of
calls in user code; use G4Autoloack to simplify the code;
use "s" prefix for static class members
March. 14th, 2022 - I. Hrivnacova (proccuts-V10-07-07)
## 2022-03-14 Ivana Hrivnacova (proccuts-V11-00-02)
- G4VRangeToEnergyConverter - fixed clearing of static data
in destructor
January. 19th, 2022 - V.Ivantchenko (proccuts-V10-07-06)
## 2022-01-19 Vladimir Ivantchenko (proccuts-V11-00-01)
- G4VRangeToEnergyConverter - fixed construction/destruction of
static data (initial problem identified by I. Hrivnacova)
## 2021-12-10 Ben Morgan (proccuts-V11-00-00)
- Change to new Markdown History format
---
# History entries prior to 11.0
October. 12th, 2021 - V.Ivanchenko (proccuts-V10-07-05)
- G4PhysicsTableHelper - fixed Coverity warning due to index type,
removed G4ThreadLocal variable, substitute old cerr by
@@ -72,11 +72,15 @@ class G4ProductionCuts
G4bool operator!=(const G4ProductionCuts& right) const;
// Equality operators
void SetProductionCut(G4double cut, G4int index = -1);
void SetProductionCut(G4double cut, G4int index);
void SetProductionCut(G4double cut, G4ParticleDefinition* ptcl);
void SetProductionCut(G4double cut, const G4String& pName);
// Set the production cut in range with an index to particle type.
// If index is omitted, the value is applied to all particles
// Set the production cut in range for a specific particle from
// and index, G4ParticleDefinition* or particle name. If the
// particle is not a photon, e-, e+ or proton, the function has
// no effect.
void SetProductionCut(G4double cut);
// Set the production cut in range for photons, e-, e+ and protons.
G4double GetProductionCut(G4int index) const;
// Get the production cut in range with an index to particle type
@@ -113,79 +117,4 @@ class G4ProductionCuts
static G4ThreadLocal G4ParticleDefinition* protonDef; // for proton
};
// ------------------
// Inline methods
// ------------------
inline
void G4ProductionCuts::SetProductionCut(G4double cut, G4int index)
{
if (index<0)
{
for(G4int i = 0; i < NumberOfG4CutIndex; ++i)
{
fRangeCuts[i] = cut;
}
isModified = true;
}
else if (index < NumberOfG4CutIndex)
{
fRangeCuts[index] = cut;
isModified = true;
}
}
inline
void G4ProductionCuts::SetProductionCut(G4double cut,
G4ParticleDefinition* ptcl)
{
G4int idx = -1;
if(ptcl) idx = GetIndex(ptcl);
if(idx>=0) SetProductionCut(cut,idx);
}
inline
void G4ProductionCuts::SetProductionCut(G4double cut, const G4String& pName)
{
G4int idx = GetIndex(pName);
if(idx>=0) SetProductionCut(cut,idx);
}
inline
G4double G4ProductionCuts::GetProductionCut(G4int index) const
{
G4double cut=-1.0;
if ( (index>=0) && (index<NumberOfG4CutIndex) )
{
cut = fRangeCuts[index];
}
return cut;
}
inline
G4double G4ProductionCuts::GetProductionCut(const G4String& name) const
{
return GetProductionCut(GetIndex(name));
}
inline
const std::vector<G4double>& G4ProductionCuts::GetProductionCuts() const
{
return fRangeCuts;
}
inline
G4bool G4ProductionCuts::IsModified() const
{
return isModified;
}
inline
void G4ProductionCuts::PhysicsTableUpdated()
{
isModified = false;
}
#endif
@@ -41,7 +41,6 @@
#include "globals.hh"
#include "G4ParticleDefinition.hh"
#include "G4Material.hh"
#include "G4Threading.hh"
class G4VRangeToEnergyConverter
{
@@ -103,19 +102,17 @@ private:
protected:
#ifdef G4MULTITHREADED
static G4Mutex theMutex;
#endif
static G4double Emin;
static G4double Emax;
static std::vector<G4double>* Energy;
static G4int NbinPerDecade;
static G4int Nbin;
const G4ParticleDefinition* theParticle = nullptr;
G4int fPDG = 0;
private:
static G4double sEmin;
static G4double sEmax;
static std::vector<G4double>* sEnergy;
static G4int sNbinPerDecade;
static G4int sNbin;
G4int verboseLevel = 1;
G4bool isFirstInstance = false;
};
+68 -1
View File
@@ -31,7 +31,7 @@
#include "G4ProductionCuts.hh"
#include "G4ProductionCutsTable.hh"
#include <iomanip>
#include <sstream>
G4ThreadLocal G4ParticleDefinition* G4ProductionCuts::gammaDef = nullptr;
G4ThreadLocal G4ParticleDefinition* G4ProductionCuts::electDef = nullptr;
@@ -83,6 +83,73 @@ G4bool G4ProductionCuts::operator!=(const G4ProductionCuts& right) const
return (this != &right);
}
void G4ProductionCuts::SetProductionCut(G4double cut, G4int index)
{
if(index >= 0 && index < NumberOfG4CutIndex)
{
fRangeCuts[index] = cut;
isModified = true;
}
else
{
std::ostringstream os;
os << "Setting cuts for particles other than photon, e-, e+ or proton has "
"no effect.";
G4Exception("G4ProductionCuts::SetProductionCut", "ProcCuts110",
JustWarning, os.str().c_str());
}
}
void G4ProductionCuts::SetProductionCut(G4double cut)
{
for(G4int i = 0; i < NumberOfG4CutIndex; ++i)
{
fRangeCuts[i] = cut;
}
isModified = true;
}
void G4ProductionCuts::SetProductionCut(G4double cut, G4ParticleDefinition* ptcl)
{
SetProductionCut(cut,GetIndex(ptcl));
}
void G4ProductionCuts::SetProductionCut(G4double cut, const G4String& pName)
{
SetProductionCut(cut,GetIndex(pName));
}
G4double G4ProductionCuts::GetProductionCut(G4int index) const
{
G4double cut=-1.0;
if ( (index>=0) && (index<NumberOfG4CutIndex) )
{
cut = fRangeCuts[index];
}
return cut;
}
G4double G4ProductionCuts::GetProductionCut(const G4String& name) const
{
return GetProductionCut(GetIndex(name));
}
const std::vector<G4double>& G4ProductionCuts::GetProductionCuts() const
{
return fRangeCuts;
}
G4bool G4ProductionCuts::IsModified() const
{
return isModified;
}
void G4ProductionCuts::PhysicsTableUpdated()
{
isModified = false;
}
G4int G4ProductionCuts::GetIndex(const G4String& name)
{
static const G4String gamma ("gamma");
@@ -34,35 +34,32 @@
#include "G4SystemOfUnits.hh"
#include "G4Log.hh"
#include "G4Exp.hh"
#include "G4AutoLock.hh"
#ifdef G4MULTITHREADED
G4Mutex G4VRangeToEnergyConverter::theMutex = G4MUTEX_INITIALIZER;
#endif
namespace
{
G4Mutex theREMutex = G4MUTEX_INITIALIZER;
}
G4double G4VRangeToEnergyConverter::Emin = 0.0;
G4double G4VRangeToEnergyConverter::Emax = 0.0;
G4double G4VRangeToEnergyConverter::sEmin = 0.0;
G4double G4VRangeToEnergyConverter::sEmax = 10000;
std::vector<G4double>* G4VRangeToEnergyConverter::Energy = nullptr;
std::vector<G4double>* G4VRangeToEnergyConverter::sEnergy = nullptr;
G4int G4VRangeToEnergyConverter::NbinPerDecade = 50;
G4int G4VRangeToEnergyConverter::Nbin = 350;
G4int G4VRangeToEnergyConverter::sNbinPerDecade = 50;
G4int G4VRangeToEnergyConverter::sNbin = 350;
// --------------------------------------------------------------------
G4VRangeToEnergyConverter::G4VRangeToEnergyConverter()
{
if(nullptr == Energy)
if(nullptr == sEnergy)
{
#ifdef G4MULTITHREADED
G4MUTEXLOCK(&theMutex);
if(nullptr == Energy)
G4AutoLock l(&theREMutex);
if(nullptr == sEnergy)
{
#endif
isFirstInstance = true;
Energy = new std::vector<G4double>(Nbin + 1);
#ifdef G4MULTITHREADED
}
G4MUTEXUNLOCK(&theMutex);
#endif
l.unlock();
}
// this method defines lock itself
if(isFirstInstance)
@@ -76,10 +73,10 @@ G4VRangeToEnergyConverter::~G4VRangeToEnergyConverter()
{
if(isFirstInstance)
{
delete Energy;
Energy = nullptr;
Emin = 0.;
Emax = 0.;
delete sEnergy;
sEnergy = nullptr;
sEmin = 0.;
sEmax = 10000.;
}
}
@@ -114,7 +111,7 @@ G4double G4VRangeToEnergyConverter::Convert(const G4double rangeCut,
}
}
cut = std::max(Emin, std::min(cut, Emax));
cut = std::max(sEmin, std::min(cut, sEmax));
return cut;
}
@@ -122,7 +119,7 @@ G4double G4VRangeToEnergyConverter::Convert(const G4double rangeCut,
void G4VRangeToEnergyConverter::SetEnergyRange(const G4double lowedge,
const G4double highedge)
{
G4double ehigh = std::min(Emax, highedge);
G4double ehigh = std::min(10.*CLHEP::GeV, highedge);
if(ehigh > lowedge)
{
FillEnergyVector(lowedge, ehigh);
@@ -132,28 +129,29 @@ void G4VRangeToEnergyConverter::SetEnergyRange(const G4double lowedge,
// --------------------------------------------------------------------
G4double G4VRangeToEnergyConverter::GetLowEdgeEnergy()
{
return Emin;
return sEmin;
}
// --------------------------------------------------------------------
G4double G4VRangeToEnergyConverter::GetHighEdgeEnergy()
{
return Emax;
return sEmax;
}
// --------------------------------------------------------------------
G4double G4VRangeToEnergyConverter::GetMaxEnergyCut()
{
return Emax;
return sEmax;
}
// --------------------------------------------------------------------
void G4VRangeToEnergyConverter::SetMaxEnergyCut(const G4double value)
{
if(value > Emin)
G4double ehigh = std::min(10.*CLHEP::GeV, value);
if(ehigh > sEmin)
{
FillEnergyVector(Emin, value);
FillEnergyVector(sEmin, ehigh);
}
}
@@ -161,25 +159,22 @@ void G4VRangeToEnergyConverter::SetMaxEnergyCut(const G4double value)
void G4VRangeToEnergyConverter::FillEnergyVector(const G4double emin,
const G4double emax)
{
if(emin != Emin || emax != Emax)
if(emin != sEmin || emax != sEmax || nullptr == sEnergy)
{
#ifdef G4MULTITHREADED
G4MUTEXLOCK(&theMutex);
if(emin != Emin || emax != Emax)
{
#endif
Emin = emin;
Emax = emax;
Nbin = NbinPerDecade*static_cast<G4int>(std::log10(emax/emin));
Energy->resize(Nbin + 1);
(*Energy)[0] = emin;
(*Energy)[Nbin] = emax;
G4double fact = G4Log(emax/emin)/Nbin;
for(G4int i=1; i<Nbin; ++i) { (*Energy)[i] = emin*G4Exp(i * fact); }
#ifdef G4MULTITHREADED
G4AutoLock l(&theREMutex);
if(emin != sEmin || emax != sEmax || nullptr == sEnergy)
{
sEmin = emin;
sEmax = emax;
sNbin = sNbinPerDecade*static_cast<G4int>(std::log10(emax/emin));
if(nullptr == sEnergy) { sEnergy = new std::vector<G4double>; }
sEnergy->resize(sNbin + 1);
(*sEnergy)[0] = emin;
(*sEnergy)[sNbin] = emax;
G4double fact = G4Log(emax/emin)/sNbin;
for(G4int i=1; i<sNbin; ++i) { (*sEnergy)[i] = emin*G4Exp(i * fact); }
}
G4MUTEXUNLOCK(&theMutex);
#endif
l.unlock();
}
}
@@ -197,9 +192,9 @@ G4VRangeToEnergyConverter::ConvertForGamma(const G4double rangeCut,
G4double range2 = 0.0;
G4double e1 = 0.0;
G4double e2 = 0.0;
for (G4int i=0; i<Nbin; ++i)
for (G4int i=0; i<sNbin; ++i)
{
e2 = (*Energy)[i];
e2 = (*sEnergy)[i];
G4double sig = 0.;
for (G4int j=0; j<nelm; ++j)
@@ -237,9 +232,9 @@ G4VRangeToEnergyConverter::ConvertForElectron(const G4double rangeCut,
G4double e1 = 0.0;
G4double e2 = 0.0;
G4double range = 0.;
for (G4int i=0; i<Nbin; ++i)
for (G4int i=0; i<sNbin; ++i)
{
e2 = (*Energy)[i];
e2 = (*sEnergy)[i];
dedx2 = 0.0;
for (G4int j=0; j<nelm; ++j)
{
+10 -14
View File
@@ -1,20 +1,16 @@
-------------------------------------------------------------------
# Category decay History
=========================================================
Geant4 - an Object-Oriented Toolkit for Simulation in HEP
=========================================================
See `CONTRIBUTING.rst` for details of **required** info/format for each entry,
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!
Category History file
---------------------
This file should be used by G4 developers and category coordinators
to briefly summarize all major modifications introduced in the code
and keep track of all category-tags.
It DOES NOT substitute the CVS log-message one should put at every
committal in the CVS repository !
----------------------------------------------------------
* Reverse chronological order (last date on top), please *
----------------------------------------------------------
## 2021-12-10 Ben Morgan (decay-V11-00-00)
- Change to new Markdown History format
---
# History entries prior to 11.0
- 16 April 2021 B. Morgan (decay-V10-07-00)
- Migrate build to modular CMake API
+12 -14
View File
@@ -1,20 +1,18 @@
-------------------------------------------------------------------
# Category em History
=========================================================
Geant4 - an Object-Oriented Toolkit for Simulation in HEP
=========================================================
See `CONTRIBUTING.rst` for details of **required** info/format for each entry,
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!
Category History file
---------------------
This file should be used by G4 developers and category coordinators
to briefly summarize all major modifications introduced in the code
and keep track of all category-tags.
It DOES NOT substitute the CVS log-message one should put at every
committal in the CVS repository !
## 2022-05-16 Guilherme Amadio (em-V11-00-01)
- Replace getenv() calls for data variables with G4FindDataDir()
----------------------------------------------------------
* Reverse chronological order (last date on top), please *
----------------------------------------------------------
## 2021-12-10 Ben Morgan (em-V11-00-00)
- Change to new Markdown History format
---
# History entries prior to 11.0
16 April 2021 B. Morgan (em-V10-07-00)
- Migrate build to modular CMake API
@@ -1,20 +1,23 @@
-------------------------------------------------------------------
# Category emadjoint History
=========================================================
Geant4 - an Object-Oriented Toolkit for Simulation in HEP
=========================================================
See `CONTRIBUTING.rst` for details of **required** info/format for each entry,
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!
Category History file
---------------------
This file should be used by G4 developers and category coordinators
to briefly summarize all major modifications introduced in the code
and keep track of all category-tags.
It DOES NOT substitute the CVS log-message one should put at every
committal in the CVS repository !
----------------------------------------------------------
* Reverse chronological order (last date on top), please *
---------------------------------------------------------
## 2022-03-07 Vladimir Ivanchenko (emadjoint-V11-00-02)
- G4AdjointComptonModel, G4AdjointCSManager - used updated interface
to cross section from G4VEmProcess
## 2022-03-07 Vladimir Ivanchenko (emadjoint-V11-00-01)
- G4AdjointBremsstrahlungModel - use updated interface to G4EmModelManager
## 2021-12-10 Ben Morgan (emadjoint-V11-00-00)
- Change to new Markdown History format
---
# History entries prior to 11.0
29 October 2021: L. Desorgher (emadjoint-V10-07-07)
- G4AdjointForcedInteractionForGamma : Improve the forced interaction for
@@ -293,7 +293,7 @@ G4double G4AdjointBremsstrahlungModel::DiffCrossSectionPerVolumePrimToSecond(
{
if(!fIsDirectModelInitialised)
{
fEmModelManagerForFwdModels->Initialise(fElectron, fGamma, 1., 0);
fEmModelManagerForFwdModels->Initialise(fElectron, fGamma, 0);
fIsDirectModelInitialised = true;
}
return G4VEmAdjointModel::DiffCrossSectionPerVolumePrimToSecond(
@@ -309,7 +309,7 @@ G4double G4AdjointBremsstrahlungModel::AdjointCrossSection(
// 2.78.. == std::exp(1.)
if(!fIsDirectModelInitialised)
{
fEmModelManagerForFwdModels->Initialise(fElectron, fGamma, 1., 0);
fEmModelManagerForFwdModels->Initialise(fElectron, fGamma, 0);
fIsDirectModelInitialised = true;
}
if(fUseMatrix)
@@ -363,7 +363,7 @@ void G4AdjointCSManager::BuildTotalSigmaTables()
G4double e = aVector->Energy(l);
for(size_t k = 0; k < fForwardProcesses[i]->size(); ++k)
{
totCS += (*fForwardProcesses[i])[k]->GetLambda(e, couple);
totCS += (*fForwardProcesses[i])[k]->GetCrossSection(e, couple);
}
for(size_t k = 0; k < fForwardLossProcesses[i]->size(); ++k)
{
@@ -196,7 +196,7 @@ void G4AdjointComptonModel::RapidSampleSecondaries(
if(diffCS > 0.)
diffCS /= fDirectCS; // here we have the normalised diffCS
// And we remultiply by the lambda of the forward process
diffCS *= fDirectProcess->GetLambda(gammaE1, fCurrentCouple);
diffCS *= fDirectProcess->GetCrossSection(gammaE1, fCurrentCouple);
w_corr *= diffCS / diffCSUsed;
+110 -14
View File
@@ -1,22 +1,118 @@
=========================================================
Geant4 - an Object-Oriented Toolkit for Simulation in HEP
=========================================================
# Category emdna History
Category History file
---------------------
This file should be used by G4 developers and category coordinators
to briefly summarize all major modifications introduced in the code
and keep track of all category-tags.
It DOES NOT substitute the CVS log-message one should put at every
committal in the CVS repository !
See `CONTRIBUTING.rst` for details of **required** info/format for each entry,
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!
----------------------------------------------------------
* Reverse chronological order (last date on top), please *
----------------------------------------------------------*
-------------------------------------------------------------------------------
18-05-2022, G. Cosmo, emdna-V10-07-16
## 2022-06-21 Igor Semeniouk (emdna-V11-00-23)
- G4DNABornIonisationModel1.cc, G4DNACPA100ElasticModel.cc,
G4DNACPA100IonisationModel.cc, G4DNAChampionElasticModel.cc,
G4DNAELSEPAElasticModel.cc, G4DNAEmfietzoglouIonisationModel.cc,
G4DNAIonElasticModel.cc, G4DNAQuinnPlasmonExcitationModel.cc,
G4DNARPWBAIonisationModel.cc, G4DNARelativisticIonisationModel.cc,
G4DNASancheExcitationModel.cc :
use G4FindDataDir("G4LEDATA") to find dataset path on place of getenv.
## 2022-06-03 Hoang Tran (emdna-V11-00-22)
- correct DNA ion definitions in G4DNARuddIonisationExtendedModel.
## 2022-06-01 Hoang Tran (emdna-V11-00-21)
- G4Octree : fixed Coverity warning.
## 2022-05-24 Hoang Tran (emdna-V11-00-20)
- update data structure to improve performance of the mesoscopic model.
## 2022-05-18 Gabriele Cosmo (emdna-V11-00-19)
- G4ITTransportation: fixed misuse of bitwise '|' operator instead of logical.
## 2022-05-12 Sergio Losilla (emdna-V11-00-18)
- Added missing headers.
## 2022-05-11 Hoang Tran (emdna-V11-00-17)
- change the scavenging filter of the IRT beyond 1 us proposed by Naoki and Jose
## 2022-05-02 Hoang Tran (emdna-V11-00-16)
- Add localthread for fUse of G4VMoleculeCounter
## 2022-04-27 Miguel A. Cortes-Giraldo and Hoang Tran (emdna-V11-00-15)
- Incorporation of model based on RPWBA to transport protons at 100-300 MeV.
- Added G4DNARPWBAExcitationModel, G4DNARPWBAIonisationModel.
## 2022-04-25 Hoang Tran (emdna-V11-00-14)
- add UserBrownianAction in G4DNABrownianTransportation and
G4DNAMolecularDissociation
- replace G4int by int64_t for width integer types
- add fResetScavenger in G4SchedulerMessenger
## 2022-04-14 Paolo Dondero (emdna-V11-00-13)
- save local instances for recurrent access to particle definition in
G4DNAMillerGreenExcitationModel, G4DNARuddIonisationExtendedModel and
G4DNARuddIonisationModel
- use G4Pow and G4Log instead of std::pow and std::log
- inside G4DNARuddIonisationExtendedModel commented out ions that are not
inside G4DNAGenericIonsManager
## 2022-04-14 Hoang Tran (emdna-V11-00-12)
- Debug the report #2235 which might be related to KDtree algorithm
- Clean code
- Delete G4ITFinder.cc
## 2022-04-04 Paolo Dondero (emdna-V11-00-11)
- save local instances for recurrent access to particle definition in
G4DNADingfelderChargeDecreaseModel and G4DNADingfelderChargeIncreaseModel
- use G4Pow and G4Log instead of std::pow and std::log
## 2022-03-18 SI (emdna-V11-00-10)
- add protection in G4DNACPA100IonisationModel for cum. xs interpolation
## 2022-03-15 Hoang Tran (emdna-V11-00-09)
- remove macro commands to control the chemistry models in G4SchedulerMessenger
(creating models in G4SchedulerMessenger can make circular dependency problems)
- add flag OctreeFinder in IRT_syn's Initialize()
## 2022-03-04 Hoang Tran (emdna-V11-00-08)
- add macro commands to control the chemistry models,
parameters including the chemical molecules and reaction list involved in the radiolysis
## 2022-02-18 Hoang Tran (emdna-V11-00-07)
- optimize IRT-syn model, use reaction radius and reaction type from the reaction table
- delete G4VReactionType, G4DNAReactionTypeManager, G4DNATotallyDiffusionControlled,
G4DNAPartiallyDiffusionControlled
- delete G4DNAIRT_geomtries
## 2022-02-17 Jonas Hahnfeld (emdna-V11-00-06)
- `G4ITTransportation`: Make `PrepareState` more function-like, expect semicolon
- `G4DNAPolyNucleotideReactionProcess`:
- Move `PrepareState` and `State` macros into `.cc` file
- Make `PrepareState` more function-like, expect semicolon
- Move variable `pMoleculeA` under `G4VERBOSE`
## 2022-02-10 Hoang Tran (emdna-V11-00-05)
- add the condition of water material for the OUTSIDE_OF_MOTHER_VOLUME
warning in G4DNAMolecularDissociation::DecayIt()
## 2022-02-3 Hoang Tran (emdna-V11-00-04)
- modify the macro in G4Molecule.cc and G4ITType.hh for linker problems on Windows
## 2022-01-18 Jonas Hahnfeld (emdna-V11-00-03)
- Prefer pointer to `const G4Material` if possible
## 2022-01-17 Jonas Hahnfeld (emdna-V11-00-02)
- Remove useless `const_cast` of `G4VSensitiveDetector`
## 2021-12-23 Hoang Tran (emdna-V11-00-01)
- add G4DNAPolyNucleotideReactionProcess, G4VDNAHitModel
files for DNA damage applications
## 2021-12-10 Ben Morgan (emdna-V11-00-00)
- Change to new Markdown History format
---
# History entries prior to 11.0
8-11-2021, H. Tran, emdna-V10-07-15
- corrected Circular dependencies for mesoscopic model
- corrected the problem in IRT
@@ -1,66 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
#ifndef G4DNAReactionTypeManager_hh
#define G4DNAReactionTypeManager_hh 1
#include <map>
#include "G4VReactionType.hh"
using ReactionTypeTable = std::map<G4int , G4VReactionType*>;
using ReactionID = G4int;
class G4VReactionTypeManager
{
public:
G4VReactionTypeManager() = default;
virtual ~G4VReactionTypeManager() = default;
virtual void SetReactionTypeTable(G4VReactionType*) = 0;
virtual const ReactionTypeTable* GetReactionTypeTable() const = 0;
virtual void SetTypeTableByID(std::map<ReactionID, ReactionType> byIDMap) = 0;
};
class G4DNAReactionTypeManager: public G4VReactionTypeManager
{
public:
G4DNAReactionTypeManager();
~G4DNAReactionTypeManager() override;
void SetReactionTypeTable(G4VReactionType* process) override;
const ReactionTypeTable* GetReactionTypeTable() const override;
void SetTypeTableByID(std::map<ReactionID, ReactionType> byIDMap) override;
ReactionType GetReactionTypeByID(ReactionID iD);
private:
ReactionTypeTable fReactionTypeTable;
std::map<ReactionID, ReactionType> fReactionTypeByID;
protected:
void Clear();
};
#endif
@@ -57,15 +57,15 @@
class G4VITFinder
{
public:
G4VITFinder();
virtual ~G4VITFinder(){;}
virtual void Clear() = 0;
virtual void SetVerboseLevel(G4int level) = 0;
virtual G4int GetVerboseLevel() = 0;
virtual void Push(G4Track* track) = 0;
virtual G4ITType GetITType() = 0;
virtual void UpdatePositionMap() = 0;
public:
G4VITFinder() = default;
virtual ~G4VITFinder() = default;
virtual void Clear() = 0;
virtual void Push(G4Track* track) = 0;
virtual G4ITType GetITType() = 0;
virtual void UpdatePositionMap() = 0;
protected:
G4int fVerbose = 0;
};
/**
@@ -73,61 +73,42 @@ public:
* For now, G4KDTree is used
*/
template<class T>//, class SearcherT = G4KDTree>
class G4ITFinder: public G4VITFinder
template <class T> //, class SearcherT = G4KDTree>
class G4ITFinder : public G4VITFinder
{
static G4ThreadLocal G4ITFinder * fInstance;
G4ITFinder();
typedef std::map<int, G4KDTree*> TreeMap;
TreeMap fTree;
int fVerbose;
public:
static G4ITFinder * Instance();
virtual ~G4ITFinder();
virtual void Clear();
virtual void SetVerboseLevel(G4int level)
{
fVerbose = level;
}
virtual G4int GetVerboseLevel()
{
return fVerbose;
}
virtual void Push(G4Track* track);
virtual G4ITType GetITType()
{
return T::ITType();
}
virtual void UpdatePositionMap();
static void iUpdatePositionMap();
public:
static G4ITFinder* Instance();
~G4ITFinder() override;
void Clear() override;
void SetVerboseLevel(G4int level) { fVerbose = level; }
G4int GetVerboseLevel() { return fVerbose; }
void Push(G4Track* track) override;
G4ITType GetITType() override { return T::ITType(); }
void UpdatePositionMap() override;
G4KDTreeResultHandle FindNearestInRange(const T* point /*from this point*/,
int key /*for this type*/,
G4int key /*for this type*/,
G4double /*range*/);
G4KDTreeResultHandle FindNearest(const G4ThreeVector&,
int key /*for this type*/);
G4int key /*for this type*/);
G4KDTreeResultHandle FindNearest(const T* /*from this point*/,
int key /*for this type*/);
G4KDTreeResultHandle FindNearestInRange(const G4ThreeVector& /*from this point*/,
int key /*for this type*/,
G4double /*range*/);
G4int key /*for this type*/);
G4KDTreeResultHandle FindNearestInRange(
const G4ThreeVector& /*from this point*/, G4int key /*for this type*/,
G4double /*range*/);
G4KDTreeResultHandle FindNearest(const T* /*from this point*/,
const T* /*for this type*/);
private:
static G4ThreadLocal G4ITFinder* fInstance;
G4ITFinder();
using TreeMap = std::map<G4int, G4KDTree*> ;
TreeMap fTree;
};
#ifdef TEMPLATE
#undef TEMPLATE
# undef TEMPLATE
#endif
#define TEMPLATE template<class T>
#define TEMPLATE template <class T>
#define G4ITMANAGER G4ITFinder<T>
#include "G4ITFinder.icc"
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// Author: Mathieu Karamitros (kara (AT) cenbg . in2p3 . fr)
// Author: Mathieu Karamitros (kara (AT) cenbg . in2p3 . fr)
//
// WARNING : This class is released as a prototype.
// It might strongly evolve or even disapear in the next releases.
@@ -36,48 +36,42 @@
// -------------------------------------------------------------------
TEMPLATE
G4ThreadLocal G4ITMANAGER * G4ITMANAGER::fInstance = 0;
G4ThreadLocal G4ITMANAGER* G4ITMANAGER::fInstance = nullptr;
TEMPLATE
G4ITMANAGER * G4ITMANAGER::Instance()
G4ITMANAGER* G4ITMANAGER::Instance()
{
if (!fInstance) fInstance = new G4ITFinder();
if(!fInstance)
{
fInstance = new G4ITFinder();
}
return fInstance;
}
TEMPLATE G4ITMANAGER::G4ITFinder() : G4VITFinder()
TEMPLATE G4ITMANAGER::G4ITFinder()
: G4VITFinder()
{
fVerbose = 0;
G4AllITFinder::Instance()->RegisterManager(this);
}
TEMPLATE G4ITMANAGER::~G4ITFinder()
{
Clear();
fInstance = 0;
for(auto it : fTree)
{
delete it.second;
}
fTree.clear();
fInstance = nullptr;
}
TEMPLATE
void G4ITMANAGER::Clear()
{
for(auto it : fTree)
{
TreeMap::iterator it;
for (it = fTree.begin(); it != fTree.end(); it++)
{
if (it->second) delete it->second;
}
fTree.clear();
delete it.second;
}
}
TEMPLATE
void G4ITMANAGER::iUpdatePositionMap()
{
fInstance->UpdatePositionMap();
fTree.clear();
}
TEMPLATE
@@ -91,15 +85,15 @@ void G4ITMANAGER::Push(G4Track* track)
T* aIT = T::GetMolecule(track);
aIT->RecordCurrentPositionNTime();
int key = aIT->GetMoleculeID();
G4int key = aIT->GetMoleculeID();
if (!(aIT->GetNode()))
if(!(aIT->GetNode()))
{
G4KDNode_Base* node = 0;
G4KDNode_Base* node;
TreeMap::iterator it_fTree = fTree.find(key);
auto it_fTree = fTree.find(key);
if (it_fTree != fTree.end())
if(it_fTree != fTree.end())
{
node = it_fTree->second->Insert(aIT);
}
@@ -109,281 +103,199 @@ void G4ITMANAGER::Push(G4Track* track)
fTree.insert(std::make_pair(key, aTree));
node = aTree->Insert(aIT);
}
aIT->SetNode(node);
}
}
TEMPLATE
G4KDTreeResultHandle G4ITMANAGER::FindNearest(const G4ThreeVector& position,
int key)
G4int key)
{
TreeMap::iterator it = fTree.find(key);
if (it != fTree.end()) return it->second->Nearest(position);
auto it = fTree.find(key);
if(it != fTree.end())
{
return it->second->Nearest(position);
}
else
{
return 0;
return nullptr;
}
return 0;
}
TEMPLATE
G4KDTreeResultHandle G4ITMANAGER::FindNearest(const T* point0,
int key)
G4KDTreeResultHandle G4ITMANAGER::FindNearest(const T* point0, G4int key)
{
if (int(*point0) == key)
if(G4int(*point0) == key)
{
// DEBUG
// G4cout << "Equal keys !"<< G4endl;
G4KDNode_Base* node0 = point0->GetNode();
if (node0 == 0)
if(node0 == nullptr)
{
G4ExceptionDescription exceptionDescription(
"Bad request : no node found in the IT you are searching "
"closest neighbourg for");
"Bad request : no node found in the IT you are searching "
"closest neighbourg for");
G4Exception("G4ITManager::FindNearest", "ITManager002",
FatalErrorInArgument, exceptionDescription);
return 0; // coverity
FatalErrorInArgument, exceptionDescription);
return nullptr; // coverity
}
TreeMap::iterator it = fTree.find(key);
if (it != fTree.end())
auto it = fTree.find(key);
if(it != fTree.end())
{
G4KDTreeResultHandle output(it->second->Nearest(node0));
if (!output)
if(!output)
{
/*
* G4cout << "NO OUTPUT "
* << point0->GetName()
* << " " << key -> GetName()
* << G4endl;
*/
return 0;
return nullptr;
}
// G4cout << "OUTPUT" << G4endl;
return output;
}
else
{
// DEBUG
// G4cout << "Pas trouve dans la map"<< key->GetName() << G4endl;
return 0;
return nullptr;
}
}
else
{
// DEBUG
// G4cout << "Not equal keys !"<< G4endl;
// const G4ThreeVector& position = point0->GetTrack()->GetPosition() ;
TreeMap::iterator it = fTree.find(key);
if (it != fTree.end())
auto it = fTree.find(key);
if(it != fTree.end())
{
G4KDTreeResultHandle output(it->second->Nearest(*point0));
if (!output)
if(!output)
{
// G4cout << "NO OUTPUT" << G4endl;
return 0;
return nullptr;
}
// G4cout << "OUTPUT" << G4endl;
return output;
}
else
{
// DEBUG
// G4cout << "Pas trouve dans la map : "<< key->GetName() << G4endl;
return 0;
return nullptr;
}
}
return 0;
}
TEMPLATE
G4KDTreeResultHandle
G4ITMANAGER::FindNearest(const T* source,
const T* type)
G4KDTreeResultHandle G4ITMANAGER::FindNearest(const T* source, const T* type)
{
return FindNearest(source,
int(*type));
return FindNearest(source, G4int(*type));
}
TEMPLATE
G4KDTreeResultHandle
G4ITMANAGER::FindNearestInRange(const G4ThreeVector& position,
int key,
G4double R)
G4KDTreeResultHandle G4ITMANAGER::FindNearestInRange(
const G4ThreeVector& position, G4int key, G4double R)
{
TreeMap::iterator it = fTree.find(key);
if (it != fTree.end()) return it->second->NearestInRange(position, R);
auto it = fTree.find(key);
if(it != fTree.end())
{
return it->second->NearestInRange(position, R);
}
else
{
return 0;
return nullptr;
}
return 0;
}
TEMPLATE
G4KDTreeResultHandle G4ITMANAGER::FindNearestInRange(const T* point0,
int key,
G4KDTreeResultHandle G4ITMANAGER::FindNearestInRange(const T* point0, G4int key,
G4double R)
{
if (point0->GetMoleculeID() == key)
if(point0->GetMoleculeID() == key)
{
G4KDNode_Base* node0 = point0->GetNode();
TreeMap::iterator it = fTree.find(key);
if (it != fTree.end()) return it->second->NearestInRange(node0, R);
auto it = fTree.find(key);
if(it != fTree.end())
return it->second->NearestInRange(node0, R);
else
{
return 0;
return nullptr;
}
}
else
{
TreeMap::iterator it = fTree.find(key);
if (it != fTree.end()) return it->second->NearestInRange(*point0, R);
auto it = fTree.find(key);
if(it != fTree.end())
return it->second->NearestInRange(*point0, R);
else
{
return 0;
return nullptr;
}
}
return 0;
}
//#define DEBUG_MEM
#ifdef DEBUG_MEM
#include "G4MemStat.hh"
# include "G4MemStat.hh"
using namespace G4MemStat;
#endif
TEMPLATE
void G4ITMANAGER::UpdatePositionMap()
{
G4KDTree* currentTree = 0;
G4IT* currentIT = 0;
G4KDNode_Base* currentNode = 0;
#if defined (DEBUG_MEM)
#if defined(DEBUG_MEM)
MemStat mem_first, mem_second, mem_diff;
#endif
#if defined (DEBUG_MEM)
#if defined(DEBUG_MEM)
mem_first = MemoryUsage();
#endif
Clear();
const std::map<G4int, PriorityList*>& listMap =
G4ITTrackHolder::Instance()->GetLists();
auto it = listMap.begin();
auto end = listMap.end();
std::map<int,PriorityList*>& listMap = G4ITTrackHolder::Instance()->GetLists();
std::map<int,PriorityList*>::iterator it = listMap.begin();
std::map<int,PriorityList*>::iterator end = listMap.end();
TreeMap::iterator it_Tree;
for (; it!= end; it++)
for(; it != end; it++)
{
currentTree = 0;
int key = it->first;
it_Tree = fTree.find(key);
// G4cout << "Box : " << it_Box->first.GetName() << G4endl;
// G4cout << "N tracks : " << currentBox->GetNTrack() << G4endl;
// G4cout << "Will update : " << it_Box->first.GetName() <<G4endl;
if (it_Tree != fTree.end())
G4int key = it->first;
PriorityList* listUnion = it->second;
if(listUnion == nullptr || listUnion->GetMainList() == nullptr ||
listUnion->GetMainList()->empty())
{
currentTree = it_Tree->second;
if (currentTree)
{
currentTree->Clear();
//delete currentTree;
//currentTree = 0;
#if defined (DEBUG_MEM)
mem_second = MemoryUsage();
mem_diff = mem_second-mem_first;
G4cout << "\t || MEM || G4ITMANAGER::UpdatePositionMap || "
"after currentTree->Clear(), diff is : " << mem_diff << G4endl;
#endif
}
}
PriorityList* listUnion=it->second;
if(listUnion == 0 || listUnion->GetMainList() == 0
|| listUnion->GetMainList()->empty() )
{
#if defined (DEBUG_MEM)
#if defined(DEBUG_MEM)
mem_second = MemoryUsage();
mem_diff = mem_second-mem_first;
mem_diff = mem_second - mem_first;
G4cout << "\t || MEM || G4ITMANAGER::UpdatePositionMap || "
"In if(currentBox->Empty()), diff is : " << mem_diff << G4endl;
"In if(currentBox->Empty()), diff is : "
<< mem_diff << G4endl;
#endif
continue;
}
else
{
if (currentTree == 0)
{
currentTree = new G4KDTree();
fTree[key] = currentTree;
// G4cout << "**** " << "Create new tree for : " << key.GetName()
// << G4endl;
#if defined (DEBUG_MEM)
mem_second = MemoryUsage();
mem_diff = mem_second-mem_first;
G4cout << "\t || MEM || G4ITMANAGER::UpdatePositionMap || "
"after creating tree, diff is : " << mem_diff << G4endl;
auto currentTree = new G4KDTree();
fTree[key] = currentTree;
#if defined(DEBUG_MEM)
mem_second = MemoryUsage();
mem_diff = mem_second - mem_first;
G4cout << "\t || MEM || G4ITMANAGER::UpdatePositionMap || "
"after creating tree, diff is : "
<< mem_diff << G4endl;
#endif
}
G4TrackList* trackList = listUnion->GetMainList();
G4TrackList::iterator __it = trackList->begin();
G4TrackList* trackList = listUnion->GetMainList();
G4TrackList::iterator __it = trackList->begin();
G4TrackList::iterator __end = trackList->end();
// int i = 0;
// G4cout << "Box : " << key.GetName() << G4endl;
// G4cout << "N tracks : " << currentBox->GetNTrack() << G4endl;
for (; __it != __end; __it++)//, i++)
for(; __it != __end; __it++)
{
// G4cout << i << G4endl;
// G4cout << "track "
// << currentIT->GetTrack()->GetTrackID()
// << G4endl;
currentIT = GetIT(*__it);
currentNode = currentTree->Insert(currentIT);
/*G4KDNode_Base* */
// currentNode = currentTree->InsertMap(currentIT);
// if(currentIT->GetNode())
// {
// delete currentIT->GetNode();
// No need: deleted when tree is cleared
// }
G4IT* currentIT = GetIT(*__it);
G4KDNode_Base* currentNode = currentTree->Insert(currentIT);
currentIT->SetNode(currentNode);
#if defined (DEBUG_MEM)
#if defined(DEBUG_MEM)
mem_second = MemoryUsage();
mem_diff = mem_second-mem_first;
mem_diff = mem_second - mem_first;
G4cout << "\t || MEM || G4ITMANAGER::UpdatePositionMap || "
"after currentIT->SetNode(currentNode), diff is : "
<< mem_diff << G4endl;
"after currentIT->SetNode(currentNode), diff is : "
<< mem_diff << G4endl;
#endif
}
#if defined (DEBUG_MEM)
#if defined(DEBUG_MEM)
mem_second = MemoryUsage();
mem_diff = mem_second-mem_first;
mem_diff = mem_second - mem_first;
G4cout << "\t || MEM || G4ITMANAGER::UpdatePositionMap || "
"In else{...}, diff is : " << mem_diff << G4endl;
"In else{...}, diff is : "
<< mem_diff << G4endl;
#endif
}
// currentTree->Build();
}
}
@@ -76,6 +76,10 @@ public:
// time2 to the end of simulation
void RegisterModel(G4VITStepModel* pModel, G4double globalTime);
void Reset();
void Finalize();
std::vector<G4VITStepModel*> GetActiveModels(G4double globalTime) const;
bool GetTimeStepComputerFlag();
@@ -88,4 +92,5 @@ protected:
G4bool fTimeStepComputerFlag; // Set true if a time stepper is registered
G4bool fReactionProcessFlag; // Set true if a reaction process is registered
G4bool fFinalize = false;
};
@@ -112,7 +112,7 @@ public :
#define ITDef(T)\
public:\
static G4ITType fType;\
inline static G4ITType fType= G4ITTypeManager::Instance()->NewType();\
static const G4ITType ITType()\
{\
return fType;\
@@ -132,7 +132,4 @@ virtual G4bool diff(const G4IT &right) const\
return (this->operator<(right_mol));\
}
#define ITImp(T) \
G4ITType T::fType = G4ITTypeManager::Instance()->NewType();
#endif // G4ITTYPE_HH
@@ -31,8 +31,8 @@
// We would be very happy hearing from you, send us your feedback! :)
//
// In order for Geant4-DNA to be maintained and still open-source,
// article citations are crucial.
// If you use Geant4-DNA chemistry and you publish papers about your software,
// article citations are crucial.
// If you use Geant4-DNA chemistry and you publish papers about your software,
// in addition to the general paper on Geant4-DNA:
//
// Int. J. Model. Simul. Sci. Comput. 1 (2010) 157178
@@ -41,7 +41,7 @@
// reference papers on chemistry:
//
// J. Comput. Phys. 274 (2014) 841-882
// Prog. Nucl. Sci. Tec. 2 (2011) 503-508
// Prog. Nucl. Sci. Tec. 2 (2011) 503-508
#ifndef G4KDTREE_HH
#define G4KDTREE_HH 1
@@ -51,26 +51,26 @@
#include "G4KDTreeResult.hh"
class G4KDMap;
template<typename PointT> class G4KDNode;
template <typename PointT>
class G4KDNode;
//__________________________________
// Methods to act on kdnode
// Methods defined in G4KDNode.cc :
void InactiveNode(G4KDNode_Base*);
void Free(G4KDNode_Base*&);
//void* GetData(G4KDNode*);
//const double* GetNodePosition(G4KDNode_Base*);
//__________________________________
/**
* G4KDTree is used by the ITManager to locate the neareast neighbours.
* A kdtree sorts out node in such a way that it reduces the number of node check.
* The results of this search can be retrieved by G4KDTreeResultHandle.
* A kdtree sorts out node in such a way that it reduces the number of node
* check. The results of this search can be retrieved by G4KDTreeResultHandle.
*/
class G4KDTree
{
friend class G4KDNode_Base;
public:
public:
G4KDTree(size_t dim = 3);
~G4KDTree();
void Clear();
@@ -80,36 +80,33 @@ public:
void NoticeNodeDeactivation()
{
fNbActiveNodes--;
if (fNbActiveNodes <= 0) Clear();
if(fNbActiveNodes <= 0)
{
Clear();
}
}
size_t GetDim() const
{
return fDim;
}
int GetNbNodes() const
{
return fNbNodes;
}
G4KDNode_Base* GetRoot()
{
return fRoot;
}
size_t GetDim() const { return fDim; }
G4int GetNbNodes() const { return fNbNodes; }
G4KDNode_Base* GetRoot() { return fRoot; }
template<typename PointT>
G4KDNode_Base* InsertMap(PointT* pos);
template <typename PointT>
G4KDNode_Base* InsertMap(PointT* pos);
// Insert and attache the data to a node at the specified position
// In return, it gives you the corresponding node
template<typename PointT> G4KDNode_Base* Insert(PointT* pos); // 3D
template <typename PointT>
G4KDNode_Base* Insert(PointT* pos); // 3D
template<typename PointT> G4KDNode_Base* Insert(const PointT& pos); // 3D
template <typename PointT>
G4KDNode_Base* Insert(const PointT& pos); // 3D
/* Find one of the nearest nodes from the specified point.
*
* This function returns a pointer to a result set with at most one element.
*/
template<typename Position> G4KDTreeResultHandle Nearest(const Position& pos);
template <typename Position>
G4KDTreeResultHandle Nearest(const Position& pos);
G4KDTreeResultHandle Nearest(G4KDNode_Base* node);
/* Find any nearest nodes from the specified point within a range.
@@ -119,36 +116,33 @@ public:
* The returned pointer can be null as an indication of an error. Otherwise
* a valid result set is always returned which may contain 0 or more elements.
*/
template<typename Position>
G4KDTreeResultHandle NearestInRange(const Position& pos,
const double& range);
G4KDTreeResultHandle NearestInRange(G4KDNode_Base* node, const double& range);
template <typename Position>
G4KDTreeResultHandle NearestInRange(const Position& pos, const G4double& range);
G4KDTreeResultHandle NearestInRange(G4KDNode_Base* node, const G4double& range);
void *operator new(size_t);
void operator delete(void *);
protected:
void* operator new(size_t);
void operator delete(void*);
protected:
//______________________________________________________________________
class HyperRect
{
public:
public:
HyperRect(size_t dim)
{
fDim = dim;
fMin = new double[fDim];
fMax = new double[fDim];
}
: fDim(dim)
, fMin(new double[fDim])
, fMax(new double[fDim])
{}
template<typename Position>
void SetMinMax(const Position& min, const Position& max)
template <typename Position>
void SetMinMax(const Position& min, const Position& max)
{
for(size_t i = 0; i < fDim; i++)
{
for (size_t i = 0; i < fDim; i++)
{
fMin[i] = min[i];
fMax[i] = max[i];
}
fMin[i] = min[i];
fMax[i] = max[i];
}
}
~HyperRect()
{
@@ -159,72 +153,65 @@ protected:
HyperRect(const HyperRect& rect)
{
fDim = rect.fDim;
fMin = new double[fDim];
fMax = new double[fDim];
fMin = new G4double[fDim];
fMax = new G4double[fDim];
for (size_t i = 0; i < fDim; i++)
for(size_t i = 0; i < fDim; i++)
{
fMin[i] = rect.fMin[i];
fMax[i] = rect.fMax[i];
}
}
template<typename Position>
void Extend(const Position& pos)
template <typename Position>
void Extend(const Position& pos)
{
for(size_t i = 0; i < fDim; i++)
{
for (size_t i = 0; i < fDim; i++)
if(pos[i] < fMin[i])
{
if (pos[i] < fMin[i])
{
fMin[i] = pos[i];
}
if (pos[i] > fMax[i])
{
fMax[i] = pos[i];
}
fMin[i] = pos[i];
}
if(pos[i] > fMax[i])
{
fMax[i] = pos[i];
}
}
}
template <typename Position>
bool CompareDistSqr(const Position& pos, const G4double* bestmatch)
{
G4double result = 0;
for(size_t i = 0; i < fDim; i++)
{
if(pos[i] < fMin[i])
{
result += sqr(fMin[i] - pos[i]);
}
else if(pos[i] > fMax[i])
{
result += sqr(fMax[i] - pos[i]);
}
if(result >= *bestmatch){
return false;
}
}
template<typename Position>
bool CompareDistSqr(const Position& pos, const double* bestmatch)
{
double result = 0;
for (size_t i = 0; i < fDim; i++)
{
if (pos[i] < fMin[i])
{
result += sqr(fMin[i] - pos[i]);
}
else if (pos[i] > fMax[i])
{
result += sqr(fMax[i] - pos[i]);
}
if (result >= *bestmatch) return false;
}
return true;
}
size_t GetDim()
{
return fDim;
}
double* GetMin()
{
return fMin;
}
double* GetMax()
{
return fMax;
return true;
}
protected:
size_t GetDim() { return fDim; }
G4double* GetMin() { return fMin; }
G4double* GetMax() { return fMax; }
protected:
size_t fDim;
double *fMin, *fMax; /* minimum/maximum coords */
G4double *fMin, *fMax; /* minimum/maximum coords */
private:
private:
// should not be used
HyperRect& operator=(const HyperRect& rhs)
{
@@ -233,46 +220,36 @@ protected:
}
};
protected:
void __InsertMap(G4KDNode_Base *node);
void __Clear_Rec(G4KDNode_Base *node);
protected:
void __InsertMap(G4KDNode_Base* node);
void __Clear_Rec(G4KDNode_Base* node);
template<typename Position>
int __NearestInRange(G4KDNode_Base *node,
const Position& pos,
const double& range_sq,
const double& range,
G4KDTreeResult& list,
int ordered,
G4KDNode_Base *source_node = 0);
template <typename Position>
G4int __NearestInRange(G4KDNode_Base* node, const Position& pos,
const G4double& range_sq, const G4double& range,
G4KDTreeResult& list, G4int ordered,
G4KDNode_Base* source_node = nullptr);
template<typename Position>
void __NearestToPosition(G4KDNode_Base *node,
const Position& pos,
G4KDNode_Base *&result,
double *result_dist_sq,
HyperRect* fRect);
template <typename Position>
void __NearestToPosition(G4KDNode_Base* node, const Position& pos,
G4KDNode_Base*& result, double* result_dist_sq,
HyperRect* fRect);
template<typename Position>
void __NearestToNode(G4KDNode_Base *source_node,
G4KDNode_Base *node,
const Position& pos,
std::vector<G4KDNode_Base*>& result,
double *result_dist_sq,
HyperRect* fRect,
int& nbresult);
template <typename Position>
void __NearestToNode(G4KDNode_Base* source_node, G4KDNode_Base* node,
const Position& pos, std::vector<G4KDNode_Base*>& result,
G4double* result_dist_sq, HyperRect* fRect, G4int& nbresult);
protected:
HyperRect *fRect;
G4KDNode_Base *fRoot;
protected:
HyperRect* fRect = nullptr;
G4KDNode_Base* fRoot = nullptr;
size_t fDim;
int fNbNodes;
int fNbActiveNodes;
G4int fNbNodes = 0;
G4int fNbActiveNodes = 0;
G4KDMap* fKDMap;
static G4Allocator<G4KDTree>*& fgAllocator();
};
#include "G4KDTree.icc"
#endif // G4KDTREE_HH
#endif // G4KDTREE_HH
@@ -116,7 +116,6 @@ private:
void* fpValue;
G4DNABoundingBox fBigVolume;
NodeTypes fNodeType;
G4bool fIsActivated;
void init_max_depth_leaf(const NodeVector& input_values);
void init_leaf(const NodeVector& input_values);
@@ -207,7 +207,7 @@ void OCTREE::Node::init_internal(
{
std::array<NodeVector, 8> childVectors;
std::array<G4DNABoundingBox, 8> boxes = fBigVolume.partition();
std::array<Node*, 8> children;
std::array<Node*, 8> children{};
for (size_t child = 0; child < 8; ++child)
{
NodeVector& childVector = childVectors[child];
@@ -36,8 +36,8 @@
// We would be very happy hearing from you, send us your feedback! :)
//
// In order for Geant4-DNA to be maintained and still open-source,
// article citations are crucial.
// If you use Geant4-DNA chemistry and you publish papers about your software,
// article citations are crucial.
// If you use Geant4-DNA chemistry and you publish papers about your software,
// in addition to the general paper on Geant4-DNA:
//
// Int. J. Model. Simul. Sci. Comput. 1 (2010) 157178
@@ -46,7 +46,7 @@
// reference papers on chemistry:
//
// J. Comput. Phys. 274 (2014) 841-882
// Prog. Nucl. Sci. Tec. 2 (2011) 503-508
// Prog. Nucl. Sci. Tec. 2 (2011) 503-508
#ifndef G4ITSTEPPINGMESSENGER_H
#define G4ITSTEPPINGMESSENGER_H
@@ -58,35 +58,33 @@ class G4UIcmdWithAnInteger;
class G4UIcommand;
class G4UIcmdWithADoubleAndUnit;
class G4UIcmdWithABool;
class G4UIcmdWithAString;
#include "G4UImessenger.hh"
#include "globals.hh"
class G4SchedulerMessenger: public G4UImessenger
class G4SchedulerMessenger : public G4UImessenger
{
public:
G4SchedulerMessenger(G4Scheduler* runMgr);
~G4SchedulerMessenger();
public:
explicit G4SchedulerMessenger(G4Scheduler* runMgr);
~G4SchedulerMessenger();
void SetNewValue(G4UIcommand* command, G4String newValues);
G4String GetCurrentValue(G4UIcommand* command);
public:
void SetNewValue(G4UIcommand * command,G4String newValues);
G4String GetCurrentValue(G4UIcommand * command);
private:
G4Scheduler* fScheduler;
private:
G4Scheduler * fScheduler;
private: //commands
G4UIdirectory* fITDirectory;
G4UIcmdWithADoubleAndUnit* fEndTime;
G4UIcmdWithADoubleAndUnit* fTimeTolerance;
G4UIcmdWithAnInteger* fVerboseCmd;
G4UIcmdWithAnInteger* fMaxStepNumber;
G4UIcmdWithoutParameter* fInitCmd;
G4UIcmdWithoutParameter* fProcessCmd;
G4UIcmdWithAnInteger* fMaxNULLTimeSteps;
G4UIcmdWithoutParameter* fWhyDoYouStop;
G4UIcmdWithABool* fUseDefaultTimeSteps;
private: // commands
std::unique_ptr<G4UIdirectory> fITDirectory;
std::unique_ptr<G4UIcmdWithADoubleAndUnit> fEndTime;
std::unique_ptr<G4UIcmdWithADoubleAndUnit> fTimeTolerance;
std::unique_ptr<G4UIcmdWithAnInteger> fVerboseCmd;
std::unique_ptr<G4UIcmdWithAnInteger> fMaxStepNumber;
std::unique_ptr<G4UIcmdWithoutParameter> fInitCmd;
std::unique_ptr<G4UIcmdWithoutParameter> fProcessCmd;
std::unique_ptr<G4UIcmdWithAnInteger> fMaxNULLTimeSteps;
std::unique_ptr<G4UIcmdWithoutParameter> fWhyDoYouStop;
std::unique_ptr<G4UIcmdWithABool> fUseDefaultTimeSteps;
std::unique_ptr<G4UIcmdWithABool> fResetScavenger;
};
#endif // G4ITSTEPPINGMESSENGER_H
#endif // G4ITSTEPPINGMESSENGER_H
@@ -0,0 +1,47 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
#ifndef _G4VUSERBROWNIANACTION_HH
#define _G4VUSERBROWNIANACTION_HH
#include "G4Types.hh"
#include "G4Track.hh"
// experimental
class G4VUserBrownianAction
{
public:
G4VUserBrownianAction() = default;
virtual ~G4VUserBrownianAction() = default;
// virtual G4double GetDiffusionCoefficient(G4Material*,
// G4Molecule*) { return 0;}
// If returns true: track is killed
virtual void Transport(G4ThreeVector&, G4Track* pTrack = nullptr) = 0;
virtual G4double GetDistanceToBoundary(const G4Track&) = 0;
};
#endif
@@ -74,16 +74,14 @@ geant4_add_module(G4emdna-man
G4OctreeFinder.icc
G4DNABoundingBox.hh
G4ChemicalMoleculeFinder.hh
G4DNAReactionTypeManager.hh
G4VReactionType.hh
G4UserMeshAction.hh
G4VScavengerMaterial.hh
G4VUserBrownianAction.hh
SOURCES
G4AllITFinder.cc
G4ITBox.cc
G4IT.cc
G4ITGun.cc
G4ITFinder.cc
G4ITLeadingTracks.cc
G4ITModelHandler.cc
G4ITModelManager.cc
@@ -127,8 +125,7 @@ geant4_add_module(G4emdna-man
G4VITTimeStepComputer.cc
G4VITTrackHolder.cc
G4VScheduler.cc
G4DNABoundingBox.cc
G4DNAReactionTypeManager.cc)
G4DNABoundingBox.cc)
geant4_module_link_libraries(G4emdna-man
PUBLIC
@@ -55,6 +55,10 @@ void G4ITModelHandler::Initialize()
void G4ITModelHandler::RegisterModel(G4VITStepModel* pModel,
G4double startingTime)
{
if(fFinalize)
{
return;
}
assert(pModel != nullptr);
G4ITType type1;
@@ -106,4 +110,14 @@ bool G4ITModelHandler::GetTimeStepComputerFlag()
bool G4ITModelHandler::GetReactionProcessFlag()
{
return fReactionProcessFlag;
}
void G4ITModelHandler::Reset()
{
fpModelManager.reset();
}
void G4ITModelHandler::Finalize()
{
fFinalize = true;
}
@@ -76,7 +76,8 @@
class G4VSensitiveDetector;
#ifndef PrepareState
#define PrepareState() G4ITTransportationState* __state = this->GetState<G4ITTransportationState>();
# define PrepareState() \
G4ITTransportationState* __state = this->GetState<G4ITTransportationState>()
#endif
#ifndef State
@@ -256,7 +257,7 @@ AlongStepGetPhysicalInteractionLength(const G4Track& track,
G4double& currentSafety,
G4GPILSelection* selection)
{
PrepareState()
PrepareState();
G4double geometryStepLength(-1.0), newSafety(-1.0);
State(fParticleIsLooping) = false;
@@ -650,7 +651,7 @@ void G4ITTransportation::ComputeStep(const G4Track& track,
const double timeStep,
double& oPhysicalStep)
{
PrepareState()
PrepareState();
const G4DynamicParticle* pParticle = track.GetDynamicParticle();
G4ThreeVector startMomentumDir = pParticle->GetMomentumDirection();
G4ThreeVector startPosition = track.GetPosition();
@@ -698,8 +699,8 @@ G4VParticleChange* G4ITTransportation::AlongStepDoIt(const G4Track& track,
mem_first = MemoryUsage();
#endif
PrepareState()
PrepareState();
// G4cout << "G4ITTransportation::AlongStepDoIt" << G4endl;
// set pdefOpticalPhoton
// Andrea Dotti: the following statement should be in a single line:
@@ -872,8 +873,8 @@ G4VParticleChange* G4ITTransportation::PostStepDoIt(const G4Track& track,
const G4Step&)
{
// G4cout << "G4ITTransportation::PostStepDoIt" << G4endl;
PrepareState()
PrepareState();
G4TouchableHandle retCurrentTouchable; // The one to return
G4bool isLastStep = false;
@@ -943,7 +944,7 @@ G4VParticleChange* G4ITTransportation::PostStepDoIt(const G4Track& track,
// Update the Step flag which identifies the Last Step in a volume
isLastStep = fLinearNavigator->ExitedMotherVolume()
|| fLinearNavigator->EnteredDaughterVolume();
|| fLinearNavigator->EnteredDaughterVolume();
#ifdef G4DEBUG_TRANSPORT
// Checking first implementation of flagging Last Step in Volume
@@ -990,7 +991,7 @@ G4VParticleChange* G4ITTransportation::PostStepDoIt(const G4Track& track,
const G4VPhysicalVolume* pNewVol = retCurrentTouchable->GetVolume();
const G4Material* pNewMaterial = 0;
const G4VSensitiveDetector* pNewSensitiveDetector = 0;
G4VSensitiveDetector* pNewSensitiveDetector = 0;
if (pNewVol != 0)
{
@@ -999,11 +1000,9 @@ G4VParticleChange* G4ITTransportation::PostStepDoIt(const G4Track& track,
}
// ( <const_cast> pNewMaterial ) ;
// ( <const_cast> pNewSensitiveDetector) ;
fParticleChange.SetMaterialInTouchable((G4Material *) pNewMaterial);
fParticleChange.SetSensitiveDetectorInTouchable(
(G4VSensitiveDetector *) pNewSensitiveDetector);
fParticleChange.SetSensitiveDetectorInTouchable(pNewSensitiveDetector);
const G4MaterialCutsCouple* pNewMaterialCutsCouple = 0;
if (pNewVol != 0)
@@ -1085,7 +1084,7 @@ void G4ITTransportation::StartTracking(G4Track* track)
// Update the current touchable handle (from the track's)
//
PrepareState()
PrepareState();
State(fCurrentTouchableHandle) = track->GetTouchableHandle();
G4VITProcess::StartTracking(track);
@@ -31,8 +31,7 @@
*/
#include "globals.hh"
#include <stdio.h>
#include <stdlib.h>
#include <cstdio>
#include <cmath>
#include "G4KDTree.hh"
#include "G4KDMap.hh"
@@ -45,79 +44,88 @@ using namespace std;
G4Allocator<G4KDTree>*& G4KDTree::fgAllocator()
{
G4ThreadLocalStatic G4Allocator<G4KDTree>* _instance = nullptr;
return _instance;
G4ThreadLocalStatic G4Allocator<G4KDTree>* _instance = nullptr;
return _instance;
}
//______________________________________________________________________
// KDTree methods
G4KDTree::G4KDTree(size_t k) :
fKDMap(new G4KDMap(k))
{
fDim = k;
fRoot = 0;
fRect = 0;
fNbNodes = 0;
fNbActiveNodes = 0;
}
G4KDTree::G4KDTree(size_t k)
: fDim(k)
,fKDMap(new G4KDMap(k))
{}
G4KDTree::~G4KDTree()
{
if (fRoot) __Clear_Rec(fRoot);
fRoot = 0;
if (fRect)
{
delete fRect;
fRect = 0;
if(fRoot){
__Clear_Rec(fRoot);
fRoot = nullptr;
}
if (fKDMap) delete fKDMap;
if(fRect){
delete fRect;
fRect = nullptr;
}
if(fKDMap){
delete fKDMap;
fKDMap = nullptr;
}
}
void* G4KDTree::operator new(size_t)
{
if (!fgAllocator()) fgAllocator() = new G4Allocator<G4KDTree>;
return (void *) fgAllocator()->MallocSingle();
if(!fgAllocator()){
fgAllocator() = new G4Allocator<G4KDTree>;
}
return (void*) fgAllocator()->MallocSingle();
}
void G4KDTree::operator delete(void *aNode)
void G4KDTree::operator delete(void* aNode)
{
fgAllocator()->FreeSingle((G4KDTree*) aNode);
}
void G4KDTree::Print(std::ostream& out) const
{
if (fRoot) fRoot->Print(out);
if(fRoot){
fRoot->Print(out);
}
}
void G4KDTree::Clear()
{
__Clear_Rec(fRoot);
fRoot = 0;
fRoot = nullptr;
fNbNodes = 0;
if (fRect)
if(fRect)
{
delete fRect;
fRect = 0;
fRect = nullptr;
}
}
void G4KDTree::__Clear_Rec(G4KDNode_Base* node)
{
if (!node) return;
if(!node)
{
return;
}
if (node->GetLeft()) __Clear_Rec(node->GetLeft());
if (node->GetRight()) __Clear_Rec(node->GetRight());
if(node->GetLeft())
{
__Clear_Rec(node->GetLeft());
}
if(node->GetRight())
{
__Clear_Rec(node->GetRight());
}
delete node;
}
void G4KDTree::__InsertMap(G4KDNode_Base *node)
{
fKDMap->Insert(node);
}
void G4KDTree::__InsertMap(G4KDNode_Base* node) { fKDMap->Insert(node); }
void G4KDTree::Build()
{
@@ -129,7 +137,10 @@ void G4KDTree::Build()
G4KDNode_Base* root = fKDMap->PopOutMiddle(0);
if(root == 0) return;
if(root == nullptr)
{
return;
}
fRoot = root;
fNbActiveNodes++;
@@ -140,12 +151,12 @@ void G4KDTree::Build()
G4KDNode_Base* parent = fRoot;
for (size_t n = 0; n < Nnodes; n += fDim)
for(size_t n = 0; n < Nnodes; n += fDim)
{
for (size_t dim = 0; dim < fDim; dim++)
for(size_t dim = 0; dim < fDim; dim++)
{
G4KDNode_Base* node = fKDMap->PopOutMiddle(dim);
if (node)
if(node)
{
parent->Insert(node);
fNbActiveNodes++;
@@ -158,21 +169,19 @@ void G4KDTree::Build()
G4KDTreeResultHandle G4KDTree::Nearest(G4KDNode_Base* node)
{
// G4cout << "Nearest(node)" << G4endl ;
if (!fRect)
if(!fRect)
{
G4cout << "Tree empty" << G4endl;
return 0;
return nullptr;
}
std::vector<G4KDNode_Base* > result;
double dist_sq = DBL_MAX;
std::vector<G4KDNode_Base*> result;
G4double dist_sq = DBL_MAX;
/* Duplicate the bounding hyperrectangle, we will work on the copy */
HyperRect *newrect = new HyperRect(*fRect);
auto newrect = new HyperRect(*fRect);
/* Search for the nearest neighbour recursively */
int nbresult = 0;
G4int nbresult = 0;
__NearestToNode(node, fRoot, *node, result, &dist_sq, newrect, nbresult);
@@ -180,11 +189,11 @@ G4KDTreeResultHandle G4KDTree::Nearest(G4KDNode_Base* node)
delete newrect;
/* Store the result */
if (!result.empty())
if(!result.empty())
{
G4KDTreeResultHandle rset(new G4KDTreeResult(this));
int j = 0;
while (j<nbresult)
G4int j = 0;
while(j < nbresult)
{
rset->Insert(dist_sq, result[j]);
j++;
@@ -195,24 +204,28 @@ G4KDTreeResultHandle G4KDTree::Nearest(G4KDNode_Base* node)
}
else
{
return 0;
return nullptr;
}
}
G4KDTreeResultHandle G4KDTree::NearestInRange(G4KDNode_Base* node,
const double& range)
const G4double& range)
{
if (!node) return 0;
int ret(-1);
if(!node)
{
return nullptr;
}
G4int ret(-1);
G4KDTreeResult *rset = new G4KDTreeResult(this);
auto* rset = new G4KDTreeResult(this);
const double range_sq = sqr(range);
const G4double range_sq = sqr(range);
if ((ret = __NearestInRange(fRoot, *node, range_sq, range, *rset, 0, node)) == -1)
if((ret = __NearestInRange(fRoot, *node, range_sq, range, *rset, 0, node)) ==
-1)
{
delete rset;
return 0;
return nullptr;
}
rset->Sort();
rset->Rewind();
@@ -32,26 +32,25 @@
// -------------------------------------------------------------------
#include <G4Scheduler.hh>
#include <G4SchedulerMessenger.hh>
#include "G4UIdirectory.hh"
#include "G4UIcmdWithoutParameter.hh"
#include "G4UIcmdWithAnInteger.hh"
#include "G4UIcmdWithADoubleAndUnit.hh"
#include "G4UIcmdWithABool.hh"
#include "G4UIcmdWithAString.hh"
#include "G4UIcommand.hh"
#include "G4UIparameter.hh"
#include "G4UImanager.hh"
#include "G4ios.hh"
G4SchedulerMessenger::G4SchedulerMessenger(G4Scheduler * stepMgr) :
fScheduler(stepMgr)
G4SchedulerMessenger::G4SchedulerMessenger(G4Scheduler* stepMgr)
: fScheduler(stepMgr)
{
fITDirectory = new G4UIdirectory("/scheduler/");
fITDirectory = std::make_unique<G4UIdirectory>("/scheduler/");
fITDirectory->SetGuidance("Control commands for the time scheduler "
"(dna chemistry applications).");
"(dna chemistry applications).");
// Set end time
fEndTime = new G4UIcmdWithADoubleAndUnit("/scheduler/endTime", this);
fEndTime = std::make_unique<G4UIcmdWithADoubleAndUnit>("/scheduler/endTime", this);
fEndTime->SetGuidance("Set time at which the simulation must stop.");
fEndTime->AvailableForStates(G4State_PreInit, G4State_Idle);
fEndTime->SetUnitCategory("Time");
@@ -59,156 +58,153 @@ G4SchedulerMessenger::G4SchedulerMessenger(G4Scheduler * stepMgr) :
fEndTime->SetDefaultValue(1);
// Set time tolerance
fTimeTolerance = new G4UIcmdWithADoubleAndUnit("/scheduler/timeTolerance",
this);
fTimeTolerance->SetGuidance("This command aims at resolving issues related to"
" floating points. If two time events are separated by less than the "
"selected tolerance, they are assumed to belong to the same time step.");
fTimeTolerance = std::make_unique<G4UIcmdWithADoubleAndUnit>("/scheduler/timeTolerance", this);
fTimeTolerance->SetGuidance(
"This command aims at resolving issues related to"
" floating points. If two time events are separated by less than the "
"selected tolerance, they are assumed to belong to the same time step.");
fTimeTolerance->AvailableForStates(G4State_PreInit, G4State_Idle);
fTimeTolerance->SetUnitCategory("Time");
fTimeTolerance->SetDefaultUnit("picosecond");
fTimeTolerance->SetDefaultValue(1);
// Initialize
fInitCmd = new G4UIcmdWithoutParameter("/scheduler/initialize", this);
fInitCmd = std::make_unique<G4UIcmdWithoutParameter>("/scheduler/initialize", this);
fInitCmd->SetGuidance("Initialize G4Scheduler. This is done "
"for standalone application only (no physics).");
"for standalone application only (no physics).");
fInitCmd->AvailableForStates(G4State_PreInit, G4State_Idle);
// Set Max Null time Step
fMaxNULLTimeSteps = new G4UIcmdWithAnInteger("/scheduler/maxNullTimeSteps",
this);
fMaxNULLTimeSteps->SetGuidance("Set maximum allowed zero time steps. After this "
"threshold, the simulation is stopped.");
fMaxNULLTimeSteps = std::make_unique<G4UIcmdWithAnInteger>("/scheduler/maxNullTimeSteps", this);
fMaxNULLTimeSteps->SetGuidance(
"Set maximum allowed zero time steps. After this "
"threshold, the simulation is stopped.");
fMaxNULLTimeSteps->SetParameterName("numberOfNullTimeSteps", true);
fMaxNULLTimeSteps->SetDefaultValue(10000);
fMaxNULLTimeSteps->SetRange("numberOfNullTimeSteps >=0 ");
fMaxStepNumber = new G4UIcmdWithAnInteger("/scheduler/maxStepNumber", this);
fMaxStepNumber->SetGuidance("Set the maximum number of time steps. After this "
"threshold, the simulation is stopped.");
fMaxStepNumber = std::make_unique<G4UIcmdWithAnInteger>("/scheduler/maxStepNumber", this);
fMaxStepNumber->SetGuidance(
"Set the maximum number of time steps. After this "
"threshold, the simulation is stopped.");
fMaxStepNumber->SetParameterName("maximumNumberOfSteps", true);
fMaxStepNumber->SetDefaultValue(-1);
// Beam On
fProcessCmd = new G4UIcmdWithoutParameter("/scheduler/process", this);
fProcessCmd->SetGuidance("Process stacked tracks in G4Scheduler. This is done "
"for standalone application only (no physics).");
fProcessCmd = std::make_unique<G4UIcmdWithoutParameter>("/scheduler/process", this);
fProcessCmd->SetGuidance(
"Process stacked tracks in G4Scheduler. This is done "
"for standalone application only (no physics).");
fProcessCmd->AvailableForStates(G4State_PreInit, G4State_Idle);
// Verbose
fVerboseCmd = new G4UIcmdWithAnInteger("/scheduler/verbose", this);
fVerboseCmd = std::make_unique<G4UIcmdWithAnInteger>("/scheduler/verbose", this);
fVerboseCmd->SetGuidance("Set the Verbose level of G4Scheduler.");
fVerboseCmd->SetGuidance(" 0 : Silent (default)");
fVerboseCmd->SetGuidance(" 1 : Display reactions");
fVerboseCmd->SetGuidance(" 2 ");
fVerboseCmd->SetParameterName("level", true);
fVerboseCmd->SetDefaultValue(1);
// fVerboseCmd->SetRange("level >=0 && level <=4");
fWhyDoYouStop = new G4UIcmdWithoutParameter("/scheduler/whyDoYouStop",this);
fWhyDoYouStop = std::make_unique<G4UIcmdWithoutParameter>("/scheduler/whyDoYouStop", this);
fWhyDoYouStop->SetGuidance("Will print information on why the scheduler is "
"stopping the process");
"stopping the process");
fUseDefaultTimeSteps = std::make_unique<G4UIcmdWithABool>("/scheduler/useDefaultTimeSteps", this);
fUseDefaultTimeSteps->SetGuidance(
"Let the G4 processes decided for the next "
"time step interval. This command would be interesting if no reaction has "
"been set and if one will want to track down Brownian objects. "
"NB: This command gets in conflicts with the declaration of time steps.");
fResetScavenger = std::make_unique<G4UIcmdWithABool>("/scheduler/ResetScavengerForEachBeamOn", this);
fResetScavenger->SetGuidance(
"Reset Scavenger information apres each BeamOn.");
fResetScavenger->SetDefaultValue(true);
fUseDefaultTimeSteps = new G4UIcmdWithABool("/scheduler/useDefaultTimeSteps",
this);
fUseDefaultTimeSteps->SetGuidance("Let the G4 processes decided for the next "
"time step interval. This command would be interesting if no reaction has "
"been set and if one will want to track down Brownian objects. "
"NB: This command gets in conflicts with the declaration of time steps.");
}
G4SchedulerMessenger::~G4SchedulerMessenger()
{
delete fTimeTolerance;
delete fITDirectory;
delete fInitCmd;
delete fEndTime;
delete fMaxNULLTimeSteps;
delete fMaxStepNumber;
delete fProcessCmd;
delete fVerboseCmd;
delete fWhyDoYouStop;
delete fUseDefaultTimeSteps;
}
G4SchedulerMessenger::~G4SchedulerMessenger() = default;
void G4SchedulerMessenger::SetNewValue(G4UIcommand * command,
G4String newValue)
void G4SchedulerMessenger::SetNewValue(G4UIcommand* command, G4String newValue)
{
if (command == fProcessCmd)
if(command == fProcessCmd.get())
{
fScheduler->Process();
}
else if (command == fEndTime)
else if(command == fEndTime.get())
{
fScheduler->SetEndTime(fEndTime->GetNewDoubleValue(newValue));
}
else if (command == fTimeTolerance)
else if(command == fTimeTolerance.get())
{
fScheduler->SetTimeTolerance(
fTimeTolerance->GetNewDoubleValue(newValue));
fScheduler->SetTimeTolerance(fTimeTolerance->GetNewDoubleValue(newValue));
}
else if (command == fVerboseCmd)
else if(command == fVerboseCmd.get())
{
fScheduler->SetVerbose(fVerboseCmd->GetNewIntValue(newValue));
}
else if (command == fInitCmd)
else if(command == fInitCmd.get())
{
fScheduler->Initialize();
}
else if (command == fMaxNULLTimeSteps)
else if(command == fMaxNULLTimeSteps.get())
{
fScheduler->SetMaxZeroTimeAllowed(
fMaxNULLTimeSteps->GetNewIntValue(newValue));
fMaxNULLTimeSteps->GetNewIntValue(newValue));
}
else if (command == fMaxStepNumber)
else if(command == fMaxStepNumber.get())
{
fScheduler->SetMaxNbSteps(fMaxStepNumber->GetNewIntValue(newValue));
}
else if (command == fWhyDoYouStop)
else if(command == fWhyDoYouStop.get())
{
fScheduler->WhyDoYouStop();
}
else if (command == fUseDefaultTimeSteps)
else if(command == fUseDefaultTimeSteps.get())
{
fScheduler->UseDefaultTimeSteps(fUseDefaultTimeSteps->GetNewBoolValue(newValue));
fScheduler->UseDefaultTimeSteps(
fUseDefaultTimeSteps->GetNewBoolValue(newValue));
}
else if(command == fResetScavenger.get())
{
fScheduler->ResetScavenger(fResetScavenger->GetNewBoolValue(newValue));
}
}
G4String G4SchedulerMessenger::GetCurrentValue(G4UIcommand * command)
G4String G4SchedulerMessenger::GetCurrentValue(G4UIcommand* command)
{
G4String cv;
if (command == fVerboseCmd)
if(command == fVerboseCmd.get())
{
cv = fVerboseCmd->ConvertToString(fScheduler->GetVerbose());
}
else if (command == fEndTime)
else if(command == fEndTime.get())
{
cv = fEndTime->ConvertToString(fScheduler->GetEndTime());
}
else if (command == fTimeTolerance)
else if(command == fTimeTolerance.get())
{
cv = fTimeTolerance->ConvertToString(fScheduler->GetTimeTolerance());
}
else if (command == fInitCmd)
else if(command == fInitCmd.get())
{
cv = fInitCmd->ConvertToString(fScheduler->IsInitialized());
}
else if (command == fMaxNULLTimeSteps)
else if(command == fMaxNULLTimeSteps.get())
{
cv = fMaxNULLTimeSteps->ConvertToString(
fScheduler->GetMaxZeroTimeAllowed());
cv =
fMaxNULLTimeSteps->ConvertToString(fScheduler->GetMaxZeroTimeAllowed());
}
else if (command == fMaxStepNumber)
else if(command == fMaxStepNumber.get())
{
cv = fMaxStepNumber->ConvertToString(fScheduler->GetMaxNbSteps());
}
else if (command == fUseDefaultTimeSteps)
else if(command == fUseDefaultTimeSteps.get())
{
cv = fUseDefaultTimeSteps->ConvertToString(fScheduler->AreDefaultTimeStepsUsed());
cv = fUseDefaultTimeSteps->ConvertToString(
fScheduler->AreDefaultTimeStepsUsed());
}
return cv;
}
@@ -114,6 +114,13 @@ private:
G4DNADingfelderChargeDecreaseModel & operator=(const G4DNADingfelderChargeDecreaseModel &right);
G4DNADingfelderChargeDecreaseModel(const G4DNADingfelderChargeDecreaseModel&);
// Reusable particle definitions
G4ParticleDefinition* protonDef;
G4ParticleDefinition* alphaPlusPlusDef;
G4ParticleDefinition* alphaPlusDef;
G4ParticleDefinition* hydrogenDef;
G4ParticleDefinition* heliumDef;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -115,6 +115,12 @@ private:
G4DNADingfelderChargeIncreaseModel & operator=(const G4DNADingfelderChargeIncreaseModel &right);
G4DNADingfelderChargeIncreaseModel(const G4DNADingfelderChargeIncreaseModel&);
// Reusable particle definitions
G4ParticleDefinition* hydrogenDef;
G4ParticleDefinition* alphaPlusPlusDef;
G4ParticleDefinition* alphaPlusDef;
G4ParticleDefinition* heliumDef;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -39,6 +39,8 @@
#include "G4ITReaction.hh"
#include "G4DNAEventSet.hh"
#include "G4DNAUpdateSystemModel.hh"
#include "G4H2O2.hh"
#include <CLHEP/Units/SystemOfUnits.h>
class G4VITStepModel;
class G4DNAGillespieDirectMethod;
class G4UserMeshAction;
@@ -66,8 +68,8 @@ class G4DNAEventScheduler : public IEventScheduler
void SetEndTime(const G4double&);
G4double GetStartTime() const;
G4double GetEndTime() const;
[[maybe_unused]] G4double GetTimeStep() const;
[[maybe_unused]] void SetStartTime(G4double time);
G4double GetTimeStep() const;
void SetStartTime(G4double time);
inline void SetVerbose(G4int verbose) { fVerbose = verbose; }
inline G4int GetVerbose() const;
@@ -79,13 +81,13 @@ class G4DNAEventScheduler : public IEventScheduler
void RunInMesh();
void Run();
[[maybe_unused]] void AddTimeToRecord(const G4double& time);
void AddTimeToRecord(const G4double& time);
void RecordTime();
void ClearAndReChargeCounter();
void PrintRecordTime();
void Stop();
[[maybe_unused]] void SetMaxNbSteps(G4int);
void SetMaxNbSteps(G4int);
std::map<G4double /*time*/, MapCounter> GetCounterMap() const;
G4DNAMesh* GetMesh() const;
G4int GetPixels() const;
@@ -93,22 +95,25 @@ class G4DNAEventScheduler : public IEventScheduler
static G4bool CheckingReactionRadius(G4double resolution);
private:
G4int fVerbose;
G4bool fInitialized;
G4double fStartTime;
G4double fEndTime;
G4int fStepNumber;
G4int fMaxStep;
G4bool fRunning;
G4double fTimeStep;
G4double fGlobalTime;
G4double fJumpingNumber;
G4double fReactionNumber;
G4int fVerbose = 0;
G4bool fInitialized = false;
G4double fStartTime = 1 * CLHEP::picosecond;
G4double fEndTime = 10000 * CLHEP::second;
G4int fStepNumber = 0;
G4int fMaxStep = INT_MAX;
G4bool fRunning = true;
G4double fTimeStep = DBL_MAX;
G4double fGlobalTime = 1 * CLHEP::picosecond;
G4double fJumpingNumber = 0;
G4double fReactionNumber = 0;
G4int fPixel;
G4bool fIsChangeMesh;
G4bool fSetChangeMesh;
G4int fStepNumberInMesh;
G4bool fIsChangeMesh = false;
G4bool fSetChangeMesh = true;
G4int fStepNumberInMesh = 0;
G4double fInitialPixels;
G4double fTransferTime = 0.;
const G4double C = 20;
const G4double D = G4H2O2::Definition()->GetDiffusionCoefficient(); // this is the biggest D
std::unique_ptr<G4DNAMesh> fpMesh;
std::unique_ptr<G4DNAGillespieDirectMethod> fpGillespieReaction;
@@ -116,7 +121,6 @@ class G4DNAEventScheduler : public IEventScheduler
std::unique_ptr<G4DNAUpdateSystemModel> fpUpdateSystem;
std::unique_ptr<G4UserMeshAction> fpUserMeshAction;
// an aternative Counter
std::map<G4double /*time*/, MapCounter> fCounterMap;
std::set<G4double> fTimeToRecord;
std::set<G4double>::iterator fLastRecoredTime;
@@ -34,43 +34,42 @@
#include "G4MoleculeTable.hh"
#include "G4ITTrackHolder.hh"
#include "G4DNAEventSet.hh"
class G4DNAMolecularReactionTable;
class G4DNAMolecularReactionData;
class G4DNAScavengerMaterial;
class G4MolecularConfiguration;
class G4DNAGillespieDirectMethod
{
public:
G4DNAGillespieDirectMethod();
~G4DNAGillespieDirectMethod();
using MolType = const G4MolecularConfiguration*;
using Key = unsigned int;
using Index = G4Voxel::Index;
using Index = G4VDNAMesh::Index;
using Voxel = G4DNAMesh::Voxel;
using JumpingData = std::pair<MolType, Index>;
using ReactionData = const G4DNAMolecularReactionData;
using EventIt = G4DNAEventSet::EventSet::iterator;
G4double PropensityFunction(const Index& index, ReactionData* data);
G4double PropensityFunction(const Index& index, MolType moleType);
G4double PropensityFunction(const Voxel& voxel, ReactionData* data);
G4double PropensityFunction(const Voxel& voxel, MolType moleType);
inline void SetVoxelMesh(G4DNAMesh& mesh) { fpMesh = &mesh; }
void SetTimeStep(const G4double& stepTime);
G4double Reaction(const Index& index);
G4double DiffusiveJumping(const Index& index);
G4double ComputeNumberInNode(const Index& index, MolType type);
G4double VolumeOfNode(const Index& index);
void Initialize();
void CreateEvent(unsigned int key);
void CreateEvent(const Index& index);
void SetEventSet(G4DNAEventSet*);
private:
G4double Reaction(const Voxel& voxel);
G4double DiffusiveJumping(const Voxel& voxel);
G4double ComputeNumberInNode(const Voxel& voxel, MolType type);
G4double VolumeOfNode(const Voxel& voxel);
G4DNAMolecularReactionTable* fMolecularReactions;
G4DNAMesh* fpMesh;
G4DNAMesh* fpMesh = nullptr;
G4double fTimeStep;
G4DNAEventSet* fpEventSet;
G4double fVerbose;
G4DNAEventSet* fpEventSet = nullptr;
G4double fVerbose = 0;
std::map<G4double /*Propensity*/, ReactionData*> fReactionDataMap;
std::map<G4double /*Propensity*/, JumpingData> fJumpingDataMap;
G4bool FindScavenging(const Index& index, MolType, G4double&);
G4DNAScavengerMaterial* fpScavengerMaterial;
G4bool FindScavenging(const Voxel& voxel, MolType, G4double&);
G4DNAScavengerMaterial* fpScavengerMaterial = nullptr;
};
#endif
@@ -1,118 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
/*
* G4DNAIRT_geometries.hh
*
* Created on: Jul 23, 2019
* Author: W. G. Shin
* J. Ramos-Mendez and B. Faddegon
*/
#ifndef G4DNAIRT_geometries_HH_
#define G4DNAIRT_geometries_HH_
#include "globals.hh"
#include "G4ThreeVector.hh"
#include "G4DNAMolecularReaction.hh"
#include "G4DNAMolecularReactionTable.hh"
#include "G4MoleculeTable.hh"
#include "G4VDNAReactionModel.hh"
#include "G4VITReactionProcess.hh"
#include "G4ITReactionTable.hh"
#include "G4ITTrackHolder.hh"
#include "G4ITReaction.hh"
#include "G4Molecule.hh"
#include "G4VITReactionProcess.hh"
#include "G4ParticleChange.hh"
#include "G4VDNAMolecularGeometry.hh"
#include "AddClone_def.hh"
#include <vector>
#include <map>
class G4DNAMolecularReactionTable;
class G4VDNAReactionModel;
class G4ErrorFunction;
class G4DNAIRT_geometries : public G4VITReactionProcess
{
public:
G4DNAIRT_geometries();
explicit G4DNAIRT_geometries(G4VDNAReactionModel*);
~G4DNAIRT_geometries() override;
G4DNAIRT_geometries(const G4DNAIRT_geometries& other) = delete;
G4DNAIRT_geometries& operator=(const G4DNAIRT_geometries& other) = delete;
G4bool TestReactibility(const G4Track&,
const G4Track&,
G4double ,
G4bool ) override;
std::vector<std::unique_ptr<G4ITReactionChange>> FindReaction(G4ITReactionSet*, const G4double, const G4double, const G4bool) override;
std::unique_ptr<G4ITReactionChange> MakeReaction(const G4Track&, const G4Track&) override;
void SetReactionModel(G4VDNAReactionModel*);
void Initialize() override;
void SpaceBinning();
void IRTSampling();
void Sampling(G4Track*);
G4double GetIndependentReactionTime(const G4MolecularConfiguration*, const G4MolecularConfiguration*, G4double);
G4int FindBin(G4int, G4double, G4double, G4double);
G4double SamplePDC(G4double , G4double );
protected:
const G4DNAMolecularReactionTable*& fMolReactionTable;
G4VDNAReactionModel* fpReactionModel;
private:
G4ITTrackHolder* fTrackHolder;
G4ITReactionSet* fReactionSet;
G4ErrorFunction* erfc;
std::map<G4int,std::map<G4int,std::map<G4int,std::vector<G4Track*>>>> spaceBinned;
std::vector<std::pair<G4ThreeVector,G4Track*>> positionMap;
G4double fRCutOff;
G4double timeMin;
G4double timeMax;
G4double fXMin, fYMin, fZMin;
G4double fXMax, fYMax, fZMax;
G4int fNx, fNy, fNz;
G4int xiniIndex, yiniIndex, ziniIndex;
G4int xendIndex, yendIndex, zendIndex;
G4VDNAMolecularGeometry* fGeometry;
};
#endif /* G4DNAIRT_geometries_HH_ */
@@ -30,34 +30,29 @@
#define G4DNAIndependentReactionTimeModel_hh 1
#include "G4String.hh"
#include "G4VITStepModel.hh"
#include <G4ReferenceCast.hh>
class G4DNAMolecularReactionTable;
class G4VDNAReactionModel;
class G4VReactionTypeManager;
class G4DNAIndependentReactionTimeModel
: public G4VITStepModel
class G4DNAIndependentReactionTimeModel : public G4VITStepModel
{
public:
explicit G4DNAIndependentReactionTimeModel(const G4String& name = "DNAIndependentReactionTimeModel");
G4DNAIndependentReactionTimeModel(const G4String& name,
std::unique_ptr<G4VITTimeStepComputer> pTimeStepper,
std::unique_ptr<G4VITReactionProcess> pReactionProcess);
G4DNAIndependentReactionTimeModel(const G4DNAIndependentReactionTimeModel&) = delete;
~G4DNAIndependentReactionTimeModel() override;
public:
explicit G4DNAIndependentReactionTimeModel(
const G4String& name = "DNAIndependentReactionTimeModel");
G4DNAIndependentReactionTimeModel(
const G4String& name, std::unique_ptr<G4VITTimeStepComputer> pTimeStepper,
std::unique_ptr<G4VITReactionProcess> pReactionProcess);
G4DNAIndependentReactionTimeModel(const G4DNAIndependentReactionTimeModel&) =
delete;
~G4DNAIndependentReactionTimeModel() override;
void PrintInfo() override;
void Initialize() override;
void SetReactionModel(G4VDNAReactionModel*);
G4VDNAReactionModel* GetReactionModel();
void PrintInfo() override;
void Initialize() override;
void SetReactionModel(G4VDNAReactionModel*);
G4VDNAReactionModel* GetReactionModel();
void SetReactionTypeManager(G4VReactionTypeManager* pReactionProcessManager);
protected:
const G4DNAMolecularReactionTable*& fMolecularReactionTable;
std::unique_ptr<G4VDNAReactionModel> fpReactionModel;
std::unique_ptr<G4VReactionTypeManager> fReactionTypeManager;
protected:
const G4DNAMolecularReactionTable*& fMolecularReactionTable =
reference_cast<const G4DNAMolecularReactionTable*>(fpReactionTable);
std::unique_ptr<G4VDNAReactionModel> fpReactionModel;
};
#endif
@@ -33,15 +33,15 @@
#include "G4VITTimeStepComputer.hh"
#include "G4KDTreeResult.hh"
#include "G4IRTUtils.hh"
#include "G4VReactionType.hh"
#include <memory>
#include <set>
#include "G4ITTrackHolder.hh"
#include "G4ITReaction.hh"
#include "G4ReferenceCast.hh"
class G4VReactionTypeManager;
class G4VDNAReactionModel;
class G4DNAMolecularReactionTable;
class G4MolecularConfiguration;
class G4DNAReactionTypeManager;
class G4Molecule;
class G4ITReactionSet;
class G4ITReactionChange;
@@ -50,61 +50,56 @@ class G4ITTrackHolder;
class G4DNAIndependentReactionTimeStepper : public G4VITTimeStepComputer
{
public:
G4DNAIndependentReactionTimeStepper();
~G4DNAIndependentReactionTimeStepper() override = default;
G4DNAIndependentReactionTimeStepper(const G4DNAIndependentReactionTimeStepper&) = delete;
G4DNAIndependentReactionTimeStepper& operator=(const G4DNAIndependentReactionTimeStepper&) = delete;
public:
G4DNAIndependentReactionTimeStepper();
~G4DNAIndependentReactionTimeStepper() override = default;
G4DNAIndependentReactionTimeStepper(
const G4DNAIndependentReactionTimeStepper&) = delete;
G4DNAIndependentReactionTimeStepper& operator =(
const G4DNAIndependentReactionTimeStepper&) = delete;
void Prepare() override;
G4double CalculateStep(const G4Track&, const G4double&) override;
G4double CalculateMinTimeStep(G4double, G4double) override;
void Prepare() override;
G4double CalculateStep(const G4Track&, const G4double&) override;
G4double CalculateMinTimeStep(G4double, G4double) override;
void SetReactionModel(G4VDNAReactionModel*);
G4VDNAReactionModel* GetReactionModel();
void SetReactionModel(G4VDNAReactionModel*);
G4VDNAReactionModel* GetReactionModel();
std::unique_ptr<G4ITReactionChange>
FindReaction(G4ITReactionSet* pReactionSet,
const G4double& currentStepTime = 0,
const G4double& previousStepTime = 0,
const G4bool& reachedUserStepTimeLimit = false);
std::unique_ptr<G4ITReactionChange> FindReaction(
G4ITReactionSet* pReactionSet, const G4double& currentStepTime = 0,
const G4double& previousStepTime = 0,
const G4bool& reachedUserStepTimeLimit = false);
void SetReactionProcess(G4VITReactionProcess* pReactionProcess);
void SetVerbose(G4int);
void SetReactionProcess(G4VITReactionProcess* pReactionProcess);
private:
void InitializeForNewTrack();
class Utils;
void CheckAndRecordResults(const Utils& utils);
void SetReactionTypeManager(G4VReactionTypeManager* typeManager);
void SetVerbose(G4int);
private:
void InitializeForNewTrack();
ReactionType GetReactionType(const G4Track& trackA, const G4Track& trackB);
G4double GetTimeToEncounter(const G4Track& trackA, const G4Track& trackB);
class Utils;
G4bool fHasAlreadyReachedNullTime = false;
const G4DNAMolecularReactionTable*& fMolecularReactionTable =
reference_cast<const G4DNAMolecularReactionTable*>(fpReactionTable);
G4VDNAReactionModel* fReactionModel = nullptr;
G4ITTrackHolder* fpTrackContainer = G4ITTrackHolder::Instance();
G4ITReactionSet* fReactionSet = G4ITReactionSet::Instance();
G4int fVerbose = 0;
G4double fRCutOff = G4IRTUtils::GetRCutOff();
G4VITReactionProcess* fpReactionProcess = nullptr;
std::map<G4int, G4ThreeVector> fSampledPositions;
std::set<G4int> fCheckedTracks;
void CheckAndRecordResults(const Utils& utils);
G4double GetTimeToEncounter(const G4Track& trackA,
const G4Track& trackB);
G4bool fHasAlreadyReachedNullTime;
const G4DNAMolecularReactionTable*& fMolecularReactionTable;
G4VDNAReactionModel* fReactionModel;
G4ITTrackHolder* fpTrackContainer;
G4ITReactionSet* fReactionSet;
G4int fVerbose;
G4double fRCutOff;
G4DNAReactionTypeManager* fReactionTypeManager;
G4VITReactionProcess* fpReactionProcess;
std::map<G4int,G4ThreeVector> fSampledPositions;
class Utils
{
public:
Utils(const G4Track& tA, const G4Track& tB);
~Utils() = default;
const G4Track& fTrackA;
const G4Track& fTrackB;
const G4Molecule* fpMoleculeA;
const G4Molecule* fpMoleculeB;
};
class Utils
{
public:
Utils(const G4Track& tA, const G4Track& tB);
~Utils() = default;
const G4Track& fTrackA;
const G4Track& fTrackB;
const G4Molecule* fpMoleculeA;
const G4Molecule* fpMoleculeB;
};
};
#endif
@@ -131,6 +131,13 @@ private:
G4DNAMillerGreenExcitationModel & operator=(const G4DNAMillerGreenExcitationModel &right);
G4DNAMillerGreenExcitationModel(const G4DNAMillerGreenExcitationModel&);
// Reusable particle definitions
G4ParticleDefinition* protonDef;
G4ParticleDefinition* hydrogenDef;
G4ParticleDefinition* alphaPlusPlusDef;
G4ParticleDefinition* alphaPlusDef;
G4ParticleDefinition* heliumDef;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -0,0 +1,105 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// Created on 2022/03/03
//
// Authors: A.D. Dominguez-Munoz, M.I. Gallardo, M.C. Bordage,
// Z. Francis, S. Incerti, M.A. Cortes-Giraldo
//
// Contact: M.A. Cortes-Giraldo (miancortes -at- us.es)
//
//
#ifndef G4DNARPWBAExcitationModel_h
#define G4DNARPWBAExcitationModel_h 1
#include "G4VEmModel.hh"
#include "G4ParticleChangeForGamma.hh"
#include "G4ProductionCutsTable.hh"
#include "G4DNACrossSectionDataSet.hh"
#include "G4LogLogInterpolation.hh"
#include "G4Electron.hh"
#include "G4Proton.hh"
#include "G4DNAWaterExcitationStructure.hh"
#include "G4NistManager.hh"
class G4DNARPWBAExcitationModel : public G4VEmModel
{
public:
explicit G4DNARPWBAExcitationModel(
const G4ParticleDefinition* p = nullptr,
const G4String& nam = "DNARPWBAExcitationModel");
~G4DNARPWBAExcitationModel() override;
G4DNARPWBAExcitationModel& operator=(const G4DNARPWBAExcitationModel& right) =
delete;
G4DNARPWBAExcitationModel(const G4DNARPWBAExcitationModel&) = delete;
void Initialise(const G4ParticleDefinition*,
const G4DataVector& = *(new G4DataVector())) override;
G4double CrossSectionPerVolume(const G4Material* material,
const G4ParticleDefinition* p, G4double ekin,
G4double emin, G4double emax) override;
G4double GetPartialCrossSection(const G4Material*, G4int level,
const G4ParticleDefinition*,
G4double kineticEnergy) override;
void SampleSecondaries(std::vector<G4DynamicParticle*>*,
const G4MaterialCutsCouple*, const G4DynamicParticle*,
G4double tmin, G4double maxEnergy) override;
inline void SelectStationary(const G4bool& input);
protected:
G4ParticleChangeForGamma* fParticleChangeForGamma = nullptr;
private:
// Partial cross section
G4int RandomSelect(G4double energy);
G4DNAWaterExcitationStructure waterStructure;
G4bool statCode = false;
// Water density table
const std::vector<G4double>* fpMolWaterDensity = nullptr;
G4bool isInitialised = false;
G4int verboseLevel = 0;
const G4ParticleDefinition* fParticleDefinition = G4Proton::ProtonDefinition();
G4double fLowEnergy = 0;
G4double fHighEnergy = 0;
G4String fTableFile;
std::unique_ptr<G4DNACrossSectionDataSet> fTableData;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4DNARPWBAExcitationModel::SelectStationary(const G4bool& input)
{
statCode = input;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#endif
@@ -0,0 +1,151 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// Created on 2022/03/03
//
// Authors: A.D. Dominguez-Munoz, M.I. Gallardo, M.C. Bordage,
// Z. Francis, S. Incerti, M.A. Cortes-Giraldo
//
// Contact: M.A. Cortes-Giraldo (miancortes -at- us.es)
//
//
#ifndef G4DNARPWBAIonisationModel_h
#define G4DNARPWBAIonisationModel_h 1
#include "G4VEmModel.hh"
#include "G4ParticleChangeForGamma.hh"
#include "G4ProductionCutsTable.hh"
#include "G4DNACrossSectionDataSet.hh"
#include "G4Electron.hh"
#include "G4Proton.hh"
#include "G4DNAGenericIonsManager.hh"
#include "G4LogLogInterpolation.hh"
#include "G4DNAWaterIonisationStructure.hh"
#include "G4VAtomDeexcitation.hh"
#include "G4NistManager.hh"
class G4DNARPWBAIonisationModel : public G4VEmModel
{
public:
G4DNARPWBAIonisationModel(const G4ParticleDefinition* p = nullptr,
const G4String& nam = "DNARPWBAIonisationModel");
~G4DNARPWBAIonisationModel() override;
G4DNARPWBAIonisationModel& operator=(const G4DNARPWBAIonisationModel& right) =
delete;
G4DNARPWBAIonisationModel(const G4DNARPWBAIonisationModel&) = delete;
void Initialise(const G4ParticleDefinition*,
const G4DataVector& = *(new G4DataVector())) override;
G4double CrossSectionPerVolume(const G4Material* material,
const G4ParticleDefinition* p, G4double ekin,
G4double emin, G4double emax) override;
void SampleSecondaries(std::vector<G4DynamicParticle*>*,
const G4MaterialCutsCouple*, const G4DynamicParticle*,
G4double tmin, G4double maxEnergy) override;
G4double GetPartialCrossSection(const G4Material*, G4int /*level*/,
const G4ParticleDefinition*,
G4double /*kineticEnergy*/) override;
G4double DifferentialCrossSection(const G4double& k, const G4double& energyTransfer,
const G4int& shell);
G4double TransferedEnergy(G4double incomingParticleEnergy, G4int shell,
const G4double& random);
inline void SelectFasterComputation(const G4bool& input);
inline void SelectStationary(const G4bool& input);
inline void SelectSPScaling(const G4bool& input);
protected:
G4ParticleChangeForGamma* fParticleChangeForGamma = nullptr;
private:
using MapData = std::map<G4String, std::unique_ptr<G4DNACrossSectionDataSet>,
std::less<G4String>>;
using TriDimensionMap = std::map<G4double, std::map<G4double, G4double>>;
using VecMap = std::map<G4double, std::vector<G4double>>;
// methods
G4double RandomizeEjectedElectronEnergy(const G4double&, const G4int& );
G4double RandomizeEjectedElectronEnergyFromCumulatedDcs(const G4double& incomingParticleEnergy,
const G4int& shell);
G4double Interpolate(const G4double& e1, const G4double& e2, const G4double& e, const G4double& xs1,
const G4double& xs2);
G4double QuadInterpolator(const G4double& e11, const G4double& e12, const G4double& e21,
const G4double& e22, const G4double& x11, const G4double& x12,
const G4double& x21, const G4double& x22, const G4double& t1,
const G4double& t2, const G4double& t, const G4double& e);
//shoud change to array ?
G4int RandomSelect(G4double energy);
void InitialiseForProton(const G4ParticleDefinition*);
G4bool InEnergyLimit(const G4double&);
//members
G4bool fasterCode = false;
G4bool statCode = false;
G4bool spScaling = true;
// Water density table
const std::vector<G4double>* fpMolWaterDensity = nullptr;
// Deexcitation manager to produce fluo photons and e-
G4VAtomDeexcitation* fAtomDeexcitation = nullptr;
G4double lowEnergyLimit = 0;
G4double highEnergyLimit = 0;
G4bool isInitialised = false;
G4int verboseLevel = 0;
// Cross section
std::unique_ptr<G4DNACrossSectionDataSet> fpTotalCrossSection;
// Final state
G4DNAWaterIonisationStructure waterStructure;
TriDimensionMap eDiffCrossSectionData[6];
TriDimensionMap eNrjTransfData[6]; // for cumulated dcs
TriDimensionMap pDiffCrossSectionData[6];
TriDimensionMap pNrjTransfData[6]; // for cumulated dcs
std::vector<G4double> eTdummyVec;
std::vector<G4double> pTdummyVec;
VecMap eVecm;
VecMap pVecm;
VecMap eProbaShellMap[6]; // for cumulated dcs
VecMap pProbaShellMap[6]; // for cumulated dcs
const G4ParticleDefinition* fProtonDef = G4Proton::ProtonDefinition();
};
inline void G4DNARPWBAIonisationModel::SelectFasterComputation(
const G4bool& input)
{
fasterCode = input;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4DNARPWBAIonisationModel::SelectStationary(const G4bool& input)
{
statCode = input;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4DNARPWBAIonisationModel::SelectSPScaling(const G4bool& input)
{
spScaling = input;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#endif
@@ -158,12 +158,30 @@ private:
G4double Sum(G4double energy, const G4String& particle);
G4int RandomSelect(G4double energy,const G4String& particle );
G4ParticleDefinition* GetDNAIonParticleDefinition(const G4ParticleDefinition* particleDefinition);
//
G4DNARuddIonisationExtendedModel & operator=(const G4DNARuddIonisationExtendedModel &right);
G4DNARuddIonisationExtendedModel(const G4DNARuddIonisationExtendedModel&);
// Reusable particle definitions
G4ParticleDefinition* protonDef;
G4ParticleDefinition* hydrogenDef;
G4ParticleDefinition* alphaPlusPlusDef;
G4ParticleDefinition* alphaPlusDef;
G4ParticleDefinition* heliumDef;
//G4ParticleDefinition* lithiumDef;
//G4ParticleDefinition* berylliumDef;
//G4ParticleDefinition* boronDef;
G4ParticleDefinition* carbonDef;
G4ParticleDefinition* nitrogenDef;
G4ParticleDefinition* oxygenDef;
G4ParticleDefinition* siliconDef;
G4ParticleDefinition* ironDef;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -155,6 +155,13 @@ private:
G4DNARuddIonisationModel & operator=(const G4DNARuddIonisationModel &right);
G4DNARuddIonisationModel(const G4DNARuddIonisationModel&);
// Reusable particle definitions
G4ParticleDefinition* protonDef;
G4ParticleDefinition* hydrogenDef;
G4ParticleDefinition* alphaPlusPlusDef;
G4ParticleDefinition* alphaPlusDef;
G4ParticleDefinition* heliumDef;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -73,7 +73,7 @@ public :
virtual void InitialiseToPrint(const G4MolecularConfiguration*) ;
virtual G4double GetReactionRadius(const G4MolecularConfiguration*,
const G4MolecularConfiguration*);
virtual G4double GetReactionRadius(const G4int);
virtual G4double GetReactionRadius(const G4int&);
virtual G4bool FindReaction(const G4Track&,
const G4Track&,
@@ -1,58 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// 20/2/2019
// Author : HoangTRAN
#ifndef G4DNATotallyDiffusionControlled_h
#define G4DNATotallyDiffusionControlled_h 1
#include "G4DNAReactionTypeManager.hh"
#include "G4VReactionType.hh"
class G4MolecularConfiguration;
class G4DNAMolecularReactionTable;
class G4VDNAReactionModel;
class G4DNATotallyDiffusionControlled
: public G4VReactionType
{
public:
G4DNATotallyDiffusionControlled();
~G4DNATotallyDiffusionControlled() override;
G4DNATotallyDiffusionControlled(const G4DNATotallyDiffusionControlled& other) = delete;
G4DNATotallyDiffusionControlled& operator=(const G4DNATotallyDiffusionControlled& other) = delete;
G4double GetTimeToEncounter(const G4Track& trackA,
const G4Track& trackB) override;
G4bool GeminateRecombinationProbability(const G4MolecularConfiguration* pConfMolA,
const G4MolecularConfiguration* pConfMolB) override;
private:
G4double GetDiffusionCoefficient(const G4MolecularConfiguration* pMA,
const G4MolecularConfiguration* pMB);
};
#endif
@@ -36,7 +36,7 @@ class G4DNAMolecularReactionData;
class G4DNAUpdateSystemModel : public G4VUpdateSystemModel
{
public:
using Index = G4Voxel::Index;
using Index = G4VDNAMesh::Index;
using MolType = const G4MolecularConfiguration*;
using JumpingData = std::pair<MolType, Index>;
using ReactionData = const G4DNAMolecularReactionData;
@@ -45,21 +45,18 @@ class G4DNAUpdateSystemModel : public G4VUpdateSystemModel
~G4DNAUpdateSystemModel() override = default;
void UpdateSystem(const Index& index, const ReactionData& data);
void UpdateSystem(const Index& index, const JumpingData& data);
void KillMolecule(const Index& index, MolType type);
void CreateMolecule(const Index& index, MolType);
void JumpTo(const Index& index, MolType type);
void JumpIn(const Index& index, MolType);
void SetMesh(G4DNAMesh*);
void SetGlobalTime(const G4double& globalTime) { fGlobalTime = globalTime; }
void SetVerbose(G4int verbose) { fVerbose = verbose; }
private:
G4DNAMesh* fpMesh;
G4int fVerbose;
G4double fGlobalTime;
void KillMolecule(const Index& index, MolType type);
void CreateMolecule(const Index& index, MolType);
void JumpTo(const Index& index, MolType type);
void JumpIn(const Index& index, MolType);
G4DNAMesh* fpMesh = nullptr;
G4int fVerbose = 0;
G4double fGlobalTime = DBL_MAX;
};
#endif // G4DNAUPDATESYSTEMMODEL_HH
@@ -32,35 +32,34 @@
#include "G4VDNAReactionModel.hh"
#include <vector>
class G4DNAMolecularReactionData;
class G4VReactionTypeManager;
class G4DNAReactionTypeManager;
class G4DiffusionControlledReactionModel : public G4VDNAReactionModel
{
public :
G4DiffusionControlledReactionModel();
~G4DiffusionControlledReactionModel() override;
public:
G4DiffusionControlledReactionModel();
~G4DiffusionControlledReactionModel() override;
G4DiffusionControlledReactionModel(const G4DiffusionControlledReactionModel&) = delete;
G4DiffusionControlledReactionModel& operator=(const G4DiffusionControlledReactionModel&) = delete;
G4DiffusionControlledReactionModel(
const G4DiffusionControlledReactionModel&) = delete;
G4DiffusionControlledReactionModel& operator =(
const G4DiffusionControlledReactionModel&) = delete;
void Initialise(const G4MolecularConfiguration*, const G4Track&) override;
void InitialiseToPrint(const G4MolecularConfiguration*) override;
G4double GetReactionRadius(const G4MolecularConfiguration*,
const G4MolecularConfiguration*) override;
G4double GetReactionRadius(G4int) override;
void Initialise(const G4MolecularConfiguration*, const G4Track&) override;
void InitialiseToPrint(const G4MolecularConfiguration*) override;
G4double GetReactionRadius(const G4MolecularConfiguration*,
const G4MolecularConfiguration*) override;
G4double GetReactionRadius(const G4int&) override;
G4bool FindReaction(const G4Track&,
const G4Track&,
G4double /*reactionRadius*/,
G4double& /*separationDistance*/,
G4bool /*alongStepInteraction*/) override
{return true;}
void SetReactionTypeManager(G4VReactionTypeManager* typeManager);
private :
const std::vector<const G4DNAMolecularReactionData*>* fpReactionData ;
G4DNAReactionTypeManager* fReactionTypeManager;
G4bool FindReaction(const G4Track&, const G4Track&,
G4double /*reactionRadius*/,
G4double& /*separationDistance*/,
G4bool /*alongStepInteraction*/) override
{
return true;
}
G4double GetTimeToEncounter(const G4Track& trackA, const G4Track& trackB);
private:
const std::vector<const G4DNAMolecularReactionData*>* fpReactionData =
nullptr;
};
#endif
@@ -0,0 +1,54 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
#ifndef G4VDNAHitModel_hh
#define G4VDNAHitModel_hh
#include "globals.hh"
#include <vector>
#include <variant>
class G4DNAComponentNode;
class G4VPhysicalVolume;
class G4Track;
class G4VDNAHitModel
{
using DNANode =
std::variant<const G4DNAComponentNode*, /*for dnadamage chain*/
const G4VPhysicalVolume* /*for molecularDNA chain*/>;
public:
explicit G4VDNAHitModel(const G4String& name);
virtual ~G4VDNAHitModel() = default;
// delete assignment operator
G4VDNAHitModel& operator=(const G4VDNAHitModel& right) = delete;
G4VDNAHitModel(const G4VDNAHitModel&) = delete;
virtual G4double CalculateReactionTime(const G4Track& trackA, DNANode&) = 0;
virtual G4bool DoReaction(const G4Track& track, const G4double&,
const DNANode&) = 0;
private:
const G4String fName;
};
#endif
@@ -23,7 +23,6 @@ geant4_add_module(G4emdna-models
G4DNAELSEPAElasticModel.hh
G4DNAIonElasticModel.hh
G4DNAIRT.hh
G4DNAIRT_geometries.hh
G4DNAIRTMoleculeEncounterStepper.hh
G4DNAMeltonAttachmentModel.hh
G4DNAMillerGreenExcitationModel.hh
@@ -67,13 +66,14 @@ geant4_add_module(G4emdna-models
G4DNAIndependentReactionTimeModel.hh
G4DNAIndependentReactionTimeStepper.hh
G4DNAMakeReaction.hh
G4DNAPartiallyDiffusionControlled.hh
G4DNATotallyDiffusionControlled.hh
G4DNAUpdateSystemModel.hh
G4DNAGillespieDirectMethod.hh
G4VUpdateSystemModel.hh
G4DNAUpdateSystemModel.hh
G4DNAEventScheduler.hh
G4DNARPWBAExcitationModel.hh
G4DNARPWBAIonisationModel.hh
G4VDNAHitModel.hh
SOURCES
G4DNABornAngle.cc
G4DNABornExcitationModel1.cc
@@ -93,7 +93,6 @@ geant4_add_module(G4emdna-models
G4DNAEmfietzoglouIonisationModel.cc
G4DNAIonElasticModel.cc
G4DNAIRT.cc
G4DNAIRT_geometries.cc
G4DNAIRTMoleculeEncounterStepper.cc
G4DNAMeltonAttachmentModel.cc
G4DNAMillerGreenExcitationModel.cc
@@ -136,12 +135,13 @@ geant4_add_module(G4emdna-models
G4DNAIndependentReactionTimeModel.cc
G4DNAIndependentReactionTimeStepper.cc
G4DNAMakeReaction.cc
G4DNAPartiallyDiffusionControlled.cc
G4DNATotallyDiffusionControlled.cc
G4DNAUpdateSystemModel.cc
G4DNAGillespieDirectMethod.cc
G4DNAUpdateSystemModel.cc
G4DNAEventScheduler.cc)
G4DNAEventScheduler.cc
G4DNARPWBAExcitationModel.cc
G4DNARPWBAIonisationModel.cc
G4VDNAHitModel.cc)
geant4_module_link_libraries(G4emdna-models
PUBLIC
@@ -100,7 +100,7 @@ void G4DNABornExcitationModel2::Initialise(const G4ParticleDefinition* particle,
fParticleDefinition = particle;
std::ostringstream fullFileName;
char *path = std::getenv("G4LEDATA");
const char* path = G4FindDataDir("G4LEDATA");
if(G4String(path) == "")
{
@@ -124,7 +124,7 @@ void G4DNABornIonisationModel1::Initialise(const G4ParticleDefinition* particle,
G4double scaleFactor = (1.e-22 / 3.343) * m*m;
char *path = getenv("G4LEDATA");
const char *path = G4FindDataDir("G4LEDATA");
// *** ELECTRON
@@ -128,7 +128,7 @@ void G4DNABornIonisationModel2::Initialise(const G4ParticleDefinition* particle,
fParticleDef = particle;
// Energy limits
char *path = std::getenv("G4LEDATA");
const char* path = G4FindDataDir("G4LEDATA");
// ***
@@ -173,7 +173,7 @@ void G4DNACPA100ElasticModel::Initialise(const G4ParticleDefinition*
// For final state
char *path = getenv("G4LEDATA");
const char *path = G4FindDataDir("G4LEDATA");
if (!path)
{
@@ -136,7 +136,7 @@ void G4DNACPA100IonisationModel::Initialise(const G4ParticleDefinition* particle
G4double scaleFactor = 1.e-20 * m*m;
char *path = getenv("G4LEDATA");
const char *path = G4FindDataDir("G4LEDATA");
// *** ELECTRON
@@ -952,8 +952,16 @@ G4double G4DNACPA100IonisationModel::RandomTransferedEnergy
<< nrjTransf12 << " " << nrjTransf21 << " " <<nrjTransf22 << G4endl;
*/
}
// Avoids cases where cum xs is 1 in last bin only and zero everywhere else
if (valuePROB11==0. && valuePROB12==1.)
{
G4double interpolatedvalue2 = Interpolate(valuePROB21, valuePROB22, random, nrjTransf21, nrjTransf22);
G4double valueNrjTransf = Interpolate(valueK1, valueK2, k, 0., interpolatedvalue2);
return valueNrjTransf;
}
}
// Avoids cases where cum xs is zero for k1 and is not for k2 (with always k1<k2)
@@ -137,7 +137,7 @@ void G4DNAChampionElasticModel::Initialise(const G4ParticleDefinition* particle,
// For final state
char *path = getenv("G4LEDATA");
const char *path = G4FindDataDir("G4LEDATA");
if (!path)
{
@@ -30,6 +30,12 @@
#include "G4SystemOfUnits.hh"
#include "G4DNAMolecularMaterial.hh"
#include "G4DNAChemistryManager.hh"
#include "G4Log.hh"
#include "G4Pow.hh"
#include "G4Alpha.hh"
static G4Pow * gpow = G4Pow::GetInstance();
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -87,9 +93,11 @@ void G4DNADingfelderChargeDecreaseModel::Initialise(const G4ParticleDefinition*
G4DNAGenericIonsManager *instance;
instance = G4DNAGenericIonsManager::Instance();
G4ParticleDefinition* protonDef = G4Proton::ProtonDefinition();
G4ParticleDefinition* alphaPlusPlusDef = instance->GetIon("alpha++");
G4ParticleDefinition* alphaPlusDef = instance->GetIon("alpha+");
protonDef = G4Proton::ProtonDefinition();
alphaPlusPlusDef = G4Alpha::Alpha();
alphaPlusDef = instance->GetIon("alpha+");
hydrogenDef = instance->GetIon("hydrogen");
heliumDef = instance->GetIon("helium");
G4String proton;
G4String alphaPlusPlus;
@@ -220,16 +228,12 @@ G4double G4DNADingfelderChargeDecreaseModel::CrossSectionPerVolume(const G4Mater
}
// Calculate total cross section for model
G4DNAGenericIonsManager *instance;
instance = G4DNAGenericIonsManager::Instance();
if (
particleDefinition != G4Proton::ProtonDefinition()
particleDefinition != protonDef
&&
particleDefinition != instance->GetIon("alpha++")
particleDefinition != alphaPlusPlusDef
&&
particleDefinition != instance->GetIon("alpha+")
particleDefinition != alphaPlusDef
)
return 0;
@@ -365,17 +369,14 @@ G4int G4DNADingfelderChargeDecreaseModel::NumberOfFinalStates(G4ParticleDefiniti
if (particleDefinition == G4Proton::Proton())
return 1;
G4DNAGenericIonsManager*instance;
instance = G4DNAGenericIonsManager::Instance();
if (particleDefinition == instance->GetIon("alpha++"))
if (particleDefinition == alphaPlusPlusDef)
{
if (finalStateIndex == 0)
return 1;
return 2;
}
if (particleDefinition == instance->GetIon("alpha+"))
if (particleDefinition == alphaPlusDef)
return 1;
return 0;
@@ -386,20 +387,18 @@ G4int G4DNADingfelderChargeDecreaseModel::NumberOfFinalStates(G4ParticleDefiniti
G4ParticleDefinition* G4DNADingfelderChargeDecreaseModel::OutgoingParticleDefinition(G4ParticleDefinition* particleDefinition,
G4int finalStateIndex)
{
G4DNAGenericIonsManager * instance(G4DNAGenericIonsManager::Instance());
if (particleDefinition == G4Proton::Proton())
return instance->GetIon("hydrogen");
return hydrogenDef;
if (particleDefinition == instance->GetIon("alpha++"))
if (particleDefinition == alphaPlusPlusDef)
{
if (finalStateIndex == 0)
return instance->GetIon("alpha+");
return instance->GetIon("helium");
return alphaPlusDef;
return heliumDef;
}
if (particleDefinition == instance->GetIon("alpha+"))
return instance->GetIon("helium");
if (particleDefinition == alphaPlusDef)
return heliumDef;
return 0;
}
@@ -413,12 +412,10 @@ G4double G4DNADingfelderChargeDecreaseModel::WaterBindingEnergyConstant(G4Partic
// Rad. Phys. Chem. 59 p.267 by Dingf. et al.
// W + 10.79 eV -> W+ + e-
G4DNAGenericIonsManager * instance(G4DNAGenericIonsManager::Instance());
if (particleDefinition == G4Proton::Proton())
return 10.79 * eV;
if (particleDefinition == instance->GetIon("alpha++"))
if (particleDefinition == alphaPlusPlusDef)
{
// Binding energy for W+ -> W++ + e- 10.79 eV
// Binding energy for W -> W+ + e- 10.79 eV
@@ -432,7 +429,7 @@ G4double G4DNADingfelderChargeDecreaseModel::WaterBindingEnergyConstant(G4Partic
return 10.79 * 2 * eV;
}
if (particleDefinition == instance->GetIon("alpha+"))
if (particleDefinition == alphaPlusDef)
{
// Binding energy for W+ -> W++ + e- 10.79 eV
// Binding energy for W -> W+ + e- 10.79 eV
@@ -451,12 +448,10 @@ G4double G4DNADingfelderChargeDecreaseModel::WaterBindingEnergyConstant(G4Partic
G4double G4DNADingfelderChargeDecreaseModel::OutgoingParticleBindingEnergyConstant(G4ParticleDefinition* particleDefinition,
G4int finalStateIndex)
{
G4DNAGenericIonsManager * instance(G4DNAGenericIonsManager::Instance());
if (particleDefinition == G4Proton::Proton())
return 13.6 * eV;
if (particleDefinition == instance->GetIon("alpha++"))
if (particleDefinition == alphaPlusPlusDef)
{
// Binding energy for He+ -> He++ + e- 54.509 eV
// Binding energy for He -> He+ + e- 24.587 eV
@@ -467,7 +462,7 @@ G4double G4DNADingfelderChargeDecreaseModel::OutgoingParticleBindingEnergyConsta
return (54.509 + 24.587) * eV;
}
if (particleDefinition == instance->GetIon("alpha+"))
if (particleDefinition == alphaPlusDef)
{
// Binding energy for He+ -> He++ + e- 54.509 eV
// Binding energy for He -> He+ + e- 24.587 eV
@@ -485,16 +480,14 @@ G4double G4DNADingfelderChargeDecreaseModel::PartialCrossSection(G4double k,
const G4ParticleDefinition* particleDefinition)
{
G4int particleTypeIndex = 0;
G4DNAGenericIonsManager* instance;
instance = G4DNAGenericIonsManager::Instance();
if (particleDefinition == G4Proton::ProtonDefinition())
if (particleDefinition == protonDef)
particleTypeIndex = 0;
if (particleDefinition == instance->GetIon("alpha++"))
if (particleDefinition == alphaPlusPlusDef)
particleTypeIndex = 1;
if (particleDefinition == instance->GetIon("alpha+"))
if (particleDefinition == alphaPlusDef)
particleTypeIndex = 2;
//
@@ -526,7 +519,7 @@ G4double G4DNADingfelderChargeDecreaseModel::PartialCrossSection(G4double k,
//
x1[index][particleTypeIndex] = x0[index][particleTypeIndex]
+ std::pow((a0[index][particleTypeIndex] - a1[index][particleTypeIndex])
+ gpow->powA((a0[index][particleTypeIndex] - a1[index][particleTypeIndex])
/ (c0[index][particleTypeIndex]
* d0[index][particleTypeIndex]),
1. / (d0[index][particleTypeIndex] - 1.));
@@ -534,12 +527,12 @@ G4double G4DNADingfelderChargeDecreaseModel::PartialCrossSection(G4double k,
- a1[index][particleTypeIndex]) * x1[index][particleTypeIndex]
+ b0[index][particleTypeIndex]
- c0[index][particleTypeIndex]
* std::pow(x1[index][particleTypeIndex]
* gpow->powA(x1[index][particleTypeIndex]
- x0[index][particleTypeIndex],
d0[index][particleTypeIndex]);
}
G4double x(std::log10(k / eV));
G4double x(G4Log(k / eV)/gpow->logZ(10));
G4double y;
if (x < x0[index][particleTypeIndex])
@@ -547,12 +540,12 @@ G4double G4DNADingfelderChargeDecreaseModel::PartialCrossSection(G4double k,
else if (x < x1[index][particleTypeIndex])
y = a0[index][particleTypeIndex] * x + b0[index][particleTypeIndex]
- c0[index][particleTypeIndex]
* std::pow(x - x0[index][particleTypeIndex],
* gpow->powA(x - x0[index][particleTypeIndex],
d0[index][particleTypeIndex]);
else
y = a1[index][particleTypeIndex] * x + b1[index][particleTypeIndex];
return f0[index][particleTypeIndex] * std::pow(10., y) * m * m;
return f0[index][particleTypeIndex] * gpow->powA(10., y) * m * m;
}
@@ -560,16 +553,14 @@ G4int G4DNADingfelderChargeDecreaseModel::RandomSelect(G4double k,
const G4ParticleDefinition* particleDefinition)
{
G4int particleTypeIndex = 0;
G4DNAGenericIonsManager *instance;
instance = G4DNAGenericIonsManager::Instance();
if (particleDefinition == G4Proton::ProtonDefinition())
if (particleDefinition == protonDef)
particleTypeIndex = 0;
if (particleDefinition == instance->GetIon("alpha++"))
if (particleDefinition == alphaPlusPlusDef)
particleTypeIndex = 1;
if (particleDefinition == instance->GetIon("alpha+"))
if (particleDefinition == alphaPlusDef)
particleTypeIndex = 2;
const G4int n = numberOfPartialCrossSections[particleTypeIndex];
@@ -608,16 +599,14 @@ G4double G4DNADingfelderChargeDecreaseModel::Sum(G4double k,
const G4ParticleDefinition* particleDefinition)
{
G4int particleTypeIndex = 0;
G4DNAGenericIonsManager* instance;
instance = G4DNAGenericIonsManager::Instance();
if (particleDefinition == G4Proton::ProtonDefinition())
if (particleDefinition == protonDef)
particleTypeIndex = 0;
if (particleDefinition == instance->GetIon("alpha++"))
if (particleDefinition == alphaPlusPlusDef)
particleTypeIndex = 1;
if (particleDefinition == instance->GetIon("alpha+"))
if (particleDefinition == alphaPlusDef)
particleTypeIndex = 2;
G4double totalCrossSection = 0.;
@@ -29,6 +29,11 @@
#include "G4PhysicalConstants.hh"
#include "G4SystemOfUnits.hh"
#include "G4DNAMolecularMaterial.hh"
#include "G4Log.hh"
#include "G4Pow.hh"
#include "G4Alpha.hh"
static G4Pow * gpow = G4Pow::GetInstance();
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -85,9 +90,10 @@ void G4DNADingfelderChargeIncreaseModel::Initialise(const G4ParticleDefinition*
G4DNAGenericIonsManager *instance;
instance = G4DNAGenericIonsManager::Instance();
G4ParticleDefinition* hydrogenDef = instance->GetIon("hydrogen");
G4ParticleDefinition* alphaPlusDef = instance->GetIon("alpha+");
G4ParticleDefinition* heliumDef = instance->GetIon("helium");
hydrogenDef = instance->GetIon("hydrogen");
alphaPlusPlusDef = G4Alpha::Alpha();
alphaPlusDef = instance->GetIon("alpha+");
heliumDef = instance->GetIon("helium");
G4String hydrogen;
G4String alphaPlus;
@@ -208,15 +214,12 @@ G4double G4DNADingfelderChargeIncreaseModel::CrossSectionPerVolume(const G4Mater
// Calculate total cross section for model
G4DNAGenericIonsManager *instance;
instance = G4DNAGenericIonsManager::Instance();
if (
particleDefinition != instance->GetIon("hydrogen")
particleDefinition != hydrogenDef
&&
particleDefinition != instance->GetIon("alpha+")
particleDefinition != alphaPlusDef
&&
particleDefinition != instance->GetIon("helium")
particleDefinition != heliumDef
)
return 0;
@@ -248,7 +251,7 @@ G4double G4DNADingfelderChargeIncreaseModel::CrossSectionPerVolume(const G4Mater
if (k >= lowLim && k <= highLim)
{
//HYDROGEN
if (particleDefinition == instance->GetIon("hydrogen"))
if (particleDefinition == hydrogenDef)
{
const G4double aa = 2.835;
const G4double bb = 0.310;
@@ -260,8 +263,8 @@ G4double G4DNADingfelderChargeIncreaseModel::CrossSectionPerVolume(const G4Mater
G4double t = k / (proton_mass_c2/electron_mass_c2);
G4double x = t / rr;
G4double temp = 4.0 * pi * Bohr_radius/nm * Bohr_radius/nm * fac;
G4double sigmal = temp * cc * (std::pow(x,dd));
G4double sigmah = temp * (aa * std::log(1.0 + x) + bb) / x;
G4double sigmal = temp * cc * (gpow->powA(x,dd));
G4double sigmah = temp * (aa * G4Log(1.0 + x) + bb) / x;
totalCrossSection = 1.0/(1.0/sigmal + 1.0/sigmah) *m*m;
}
else
@@ -327,11 +330,8 @@ void G4DNADingfelderChargeIncreaseModel::SampleSecondaries(std::vector<
fParticleChangeForGamma->ProposeTrackStatus(fStopAndKill);
G4DNAGenericIonsManager* instance;
instance = G4DNAGenericIonsManager::Instance();
G4double electronK;
if (definition == instance->GetIon("hydrogen")) electronK = inK*electron_mass_c2/proton_mass_c2;
if (definition == hydrogenDef) electronK = inK*electron_mass_c2/proton_mass_c2;
else electronK = inK*electron_mass_c2/(particleMass);
if (outK<0)
@@ -362,16 +362,14 @@ G4int G4DNADingfelderChargeIncreaseModel::NumberOfFinalStates(G4ParticleDefiniti
G4int finalStateIndex)
{
G4DNAGenericIonsManager* instance;
instance = G4DNAGenericIonsManager::Instance();
if (particleDefinition == instance->GetIon("hydrogen"))
if (particleDefinition == hydrogenDef)
return 2;
if (particleDefinition == instance->GetIon("alpha+"))
if (particleDefinition == alphaPlusDef)
return 2;
if (particleDefinition == instance->GetIon("helium"))
if (particleDefinition == heliumDef)
{
if (finalStateIndex == 0)
return 2;
@@ -386,19 +384,18 @@ G4int G4DNADingfelderChargeIncreaseModel::NumberOfFinalStates(G4ParticleDefiniti
G4ParticleDefinition* G4DNADingfelderChargeIncreaseModel::OutgoingParticleDefinition(G4ParticleDefinition* particleDefinition,
G4int finalStateIndex)
{
G4DNAGenericIonsManager * instance(G4DNAGenericIonsManager::Instance());
if (particleDefinition == instance->GetIon("hydrogen"))
if (particleDefinition == hydrogenDef)
return G4Proton::Proton();
if (particleDefinition == instance->GetIon("alpha+"))
return instance->GetIon("alpha++");
if (particleDefinition == alphaPlusDef)
return alphaPlusPlusDef;
if (particleDefinition == instance->GetIon("helium"))
if (particleDefinition == heliumDef)
{
if (finalStateIndex == 0)
return instance->GetIon("alpha+");
return instance->GetIon("alpha++");
return alphaPlusDef;
return alphaPlusPlusDef;
}
return 0;
@@ -409,19 +406,18 @@ G4ParticleDefinition* G4DNADingfelderChargeIncreaseModel::OutgoingParticleDefini
G4double G4DNADingfelderChargeIncreaseModel::IncomingParticleBindingEnergyConstant(G4ParticleDefinition* particleDefinition,
G4int finalStateIndex)
{
G4DNAGenericIonsManager * instance(G4DNAGenericIonsManager::Instance());
if (particleDefinition == instance->GetIon("hydrogen"))
if (particleDefinition == hydrogenDef)
return 13.6 * eV;
if (particleDefinition == instance->GetIon("alpha+"))
if (particleDefinition == alphaPlusDef)
{
// Binding energy for He+ -> He++ + e- 54.509 eV
// Binding energy for He -> He+ + e- 24.587 eV
return 54.509 * eV;
}
if (particleDefinition == instance->GetIon("helium"))
if (particleDefinition == heliumDef)
{
// Binding energy for He+ -> He++ + e- 54.509 eV
// Binding energy for He -> He+ + e- 24.587 eV
@@ -441,13 +437,11 @@ G4double G4DNADingfelderChargeIncreaseModel::PartialCrossSection(G4double k,
const G4ParticleDefinition* particleDefinition)
{
G4int particleTypeIndex = 0;
G4DNAGenericIonsManager *instance;
instance = G4DNAGenericIonsManager::Instance();
if (particleDefinition == instance->GetIon("alpha+"))
if (particleDefinition == alphaPlusDef)
particleTypeIndex = 0;
if (particleDefinition == instance->GetIon("helium"))
if (particleDefinition == heliumDef)
particleTypeIndex = 1;
//
@@ -481,7 +475,7 @@ G4double G4DNADingfelderChargeIncreaseModel::PartialCrossSection(G4double k,
//
x1[index][particleTypeIndex] = x0[index][particleTypeIndex]
+ std::pow((a0[index][particleTypeIndex] - a1[index][particleTypeIndex])
+ gpow->powA((a0[index][particleTypeIndex] - a1[index][particleTypeIndex])
/ (c0[index][particleTypeIndex]
* d0[index][particleTypeIndex]),
1. / (d0[index][particleTypeIndex] - 1.));
@@ -489,12 +483,12 @@ G4double G4DNADingfelderChargeIncreaseModel::PartialCrossSection(G4double k,
- a1[index][particleTypeIndex]) * x1[index][particleTypeIndex]
+ b0[index][particleTypeIndex]
- c0[index][particleTypeIndex]
* std::pow(x1[index][particleTypeIndex]
* gpow->powA(x1[index][particleTypeIndex]
- x0[index][particleTypeIndex],
d0[index][particleTypeIndex]);
}
G4double x(std::log10(k / eV));
G4double x(G4Log(k / eV)/gpow->logZ(10));
G4double y;
if (x < x0[index][particleTypeIndex])
@@ -502,12 +496,12 @@ G4double G4DNADingfelderChargeIncreaseModel::PartialCrossSection(G4double k,
else if (x < x1[index][particleTypeIndex])
y = a0[index][particleTypeIndex] * x + b0[index][particleTypeIndex]
- c0[index][particleTypeIndex]
* std::pow(x - x0[index][particleTypeIndex],
* gpow->powA(x - x0[index][particleTypeIndex],
d0[index][particleTypeIndex]);
else
y = a1[index][particleTypeIndex] * x + b1[index][particleTypeIndex];
return f0[index][particleTypeIndex] * std::pow(10., y) * m * m;
return f0[index][particleTypeIndex] * gpow->powA(10., y) * m * m;
}
@@ -517,16 +511,14 @@ G4int G4DNADingfelderChargeIncreaseModel::RandomSelect(G4double k,
const G4ParticleDefinition* particleDefinition)
{
G4int particleTypeIndex = 0;
G4DNAGenericIonsManager *instance;
instance = G4DNAGenericIonsManager::Instance();
if (particleDefinition == instance->GetIon("hydrogen"))
if (particleDefinition == hydrogenDef)
return 0;
if (particleDefinition == instance->GetIon("alpha+"))
if (particleDefinition == alphaPlusDef)
particleTypeIndex = 0;
if (particleDefinition == instance->GetIon("helium"))
if (particleDefinition == heliumDef)
particleTypeIndex = 1;
const G4int n = numberOfPartialCrossSections[particleTypeIndex];
@@ -565,13 +557,11 @@ G4double G4DNADingfelderChargeIncreaseModel::Sum(G4double k,
const G4ParticleDefinition* particleDefinition)
{
G4int particleTypeIndex = 0;
G4DNAGenericIonsManager *instance;
instance = G4DNAGenericIonsManager::Instance();
if (particleDefinition == instance->GetIon("alpha+"))
if (particleDefinition == alphaPlusDef)
particleTypeIndex = 0;
if (particleDefinition == instance->GetIon("helium"))
if (particleDefinition == heliumDef)
particleTypeIndex = 1;
G4double totalCrossSection = 0.;
@@ -212,7 +212,7 @@ const G4DataVector& )
fpData_Au->LoadData(fileZElectron);
std::ostringstream eFullFileNameZ;
char *path = getenv("G4LEDATA");
const char *path = G4FindDataDir("G4LEDATA");
if (!path)
{
G4Exception("G4DNAELSEPAElasticModel::Initialise","em0002",
@@ -306,7 +306,7 @@ const G4DataVector& )
std::ostringstream eFullFileNameZ;
char *path = getenv("G4LEDATA");
const char *path = G4FindDataDir("G4LEDATA");
if (!path)
{
G4Exception("G4DNAELSEPAElasticModel::Initialise","em0004",
@@ -127,7 +127,7 @@ void G4DNAEmfietzoglouIonisationModel::Initialise(const G4ParticleDefinition* pa
G4double scaleFactor = (1.e-22 / 3.343) * m*m;
char *path = getenv("G4LEDATA");
const char *path = G4FindDataDir("G4LEDATA");
// *** ELECTRON
@@ -36,31 +36,17 @@
#include "G4UserMeshAction.hh"
#include "G4MoleculeCounter.hh"
#include "G4DNAScavengerMaterial.hh"
#include "G4Molecule.hh"
G4DNAEventScheduler::G4DNAEventScheduler(const G4DNABoundingBox& boundingBox,
G4int pixel)
: IEventScheduler()
, fVerbose(0)
, fInitialized(false)
, fStartTime(1 * ps)
, fEndTime(10000 * s)
, fStepNumber(0)
, fMaxStep(INT_MAX)
, fRunning(true)
, fTimeStep(DBL_MAX)
, fGlobalTime(fStartTime)
, fJumpingNumber(0)
, fReactionNumber(0)
, fPixel(pixel)
, fIsChangeMesh(false)
, fSetChangeMesh(true)
, fStepNumberInMesh(0)
, fInitialPixels(fPixel)
, fpMesh(new G4DNAMesh(boundingBox, fPixel))
, fpGillespieReaction(new G4DNAGillespieDirectMethod())
, fpEventSet(new G4DNAEventSet())
, fpUpdateSystem(new G4DNAUpdateSystemModel())
, fpUserMeshAction(nullptr)
{
if(!CheckingReactionRadius(fpMesh->GetResolution()))
{
@@ -76,7 +62,9 @@ void G4DNAEventScheduler::ClearAndReChargeCounter()
fCounterMap.clear();
if(fTimeToRecord.empty())
{
G4cout << "fTimeToRecord is empty " << G4endl;
G4String WarMessage = "fTimeToRecord is empty ";
G4Exception("G4DNAEventScheduler::ClearAndReChargeCounter()",
"TimeToRecord is empty", JustWarning, WarMessage);
}
fLastRecoredTime = fTimeToRecord.begin();
@@ -114,12 +102,18 @@ void G4DNAEventScheduler::ClearAndReChargeCounter()
}
fCounterMap[time_mol][molecule] = n_mol;
}
fLastRecoredTime++;
}
G4MoleculeCounter::Instance()->ResetCounter(); // reset
G4MoleculeCounter::Instance()->Use(false); // no more used
}
else
{
G4ExceptionDescription exceptionDescription;
exceptionDescription << "G4VMoleculeCounter is not used";
G4Exception("G4DNAEventScheduler::ClearAndReChargeCounter()",
"G4DNAEventScheduler010", JustWarning, exceptionDescription);
}
}
[[maybe_unused]] void G4DNAEventScheduler::AddTimeToRecord(const G4double& time)
@@ -135,7 +129,7 @@ G4DNAEventScheduler::~G4DNAEventScheduler() = default;
void G4DNAEventScheduler::Voxelizing()
{
auto pMainList = G4ITTrackHolder::Instance()->GetMainList();
std::map<G4DNAMesh::Key, MapList> TrackKeyMap;
std::map<G4VDNAMesh::Index, MapList> TrackKeyMap;
for(auto track : *pMainList)
{
auto molType = GetMolecule(track)->GetMolecularConfiguration();
@@ -148,7 +142,7 @@ void G4DNAEventScheduler::Voxelizing()
continue;
}
auto key = fpMesh->GetKey(track->GetPosition());
auto key = fpMesh->GetIndex(track->GetPosition());
if(TrackKeyMap.find(key) != TrackKeyMap.end())
{
std::map<MolType, size_t>& TrackTypeMap = TrackKeyMap[key];
@@ -169,7 +163,7 @@ void G4DNAEventScheduler::Voxelizing()
for(auto& it : TrackKeyMap)
{
fpMesh->SetVoxelMapList(it.first, std::move(it.second));
fpMesh->InitializeVoxel(it.first, std::move(it.second));
}
}
@@ -180,29 +174,26 @@ void G4DNAEventScheduler::ReVoxelizing(G4int pixel)
auto begin = fpMesh->begin();
auto end = fpMesh->end();
std::map<G4DNAMesh::Key, MapList> TrackKeyMap;
std::map<G4VDNAMesh::Index, MapList> TrackKeyMap;
for(; begin != end; begin++)
{
auto index = fpMesh->GetIndex(begin->first);
auto newKey = newMesh->GetKey(fpMesh->GetIndex(index, fPixel));
auto node = begin->second;
// if (node == nullptr) continue;
if(TrackKeyMap.find(newKey) == TrackKeyMap.end())
auto index = std::get<0>(*begin);
auto newIndex = fpMesh->ConvertIndex(index, fPixel);
if(TrackKeyMap.find(newIndex) == TrackKeyMap.end())
{
TrackKeyMap[newKey] = node->GetMapList();
TrackKeyMap[newIndex] = std::get<2>(*begin);
}
else
{
for(const auto& it : node->GetMapList())
for(const auto& it : std::get<2>(*begin))
{
TrackKeyMap[newKey][it.first] += it.second;
TrackKeyMap[newIndex][it.first] += it.second;
}
if(fVerbose > 1)
{
G4cout << "key : " << begin->first << " index : " << index
<< " new index : " << fpMesh->GetIndex(index, fPixel)
<< " new key : " << newKey
<< " number: " << node->GetMapList().begin()->second << G4endl;
G4cout << " ReVoxelizing:: Old index : " << index
<< " new index : " << fpMesh->ConvertIndex(index, fPixel)
<< " number: " << std::get<2>(*begin).begin()->second << G4endl;
}
}
}
@@ -210,7 +201,7 @@ void G4DNAEventScheduler::ReVoxelizing(G4int pixel)
for(auto& it : TrackKeyMap)
{
fpMesh->SetVoxelMapList(it.first, std::move(it.second));
fpMesh->InitializeVoxel(it.first, std::move(it.second));
}
}
void G4DNAEventScheduler::Reset()
@@ -252,7 +243,7 @@ void G4DNAEventScheduler::Initialize()
G4Scheduler::Instance()->GetScavengerMaterial());
if(pScavengerMaterial == nullptr)
{
G4cout << "pScavengerMaterial == nullptr" << G4endl;
G4cout << "There is no scavenger" << G4endl;
}
else
{
@@ -319,22 +310,29 @@ G4double G4DNAEventScheduler::GetStartTime() const { return fStartTime; }
G4double G4DNAEventScheduler::GetEndTime() const { return fEndTime; }
[[maybe_unused]] G4double G4DNAEventScheduler::GetTimeStep() const { return fTimeStep; }
[[maybe_unused]] G4double G4DNAEventScheduler::GetTimeStep() const
{
return fTimeStep;
}
G4int G4DNAEventScheduler::GetVerbose() const { return fVerbose; }
[[maybe_unused]] void G4DNAEventScheduler::SetMaxNbSteps(G4int max) { fMaxStep = max; }
[[maybe_unused]] void G4DNAEventScheduler::SetMaxNbSteps(G4int max)
{
fMaxStep = max;
}
[[maybe_unused]] void G4DNAEventScheduler::SetStartTime(G4double time)
{
fStartTime = time;
fStartTime = time;
fGlobalTime = fStartTime;
}
void G4DNAEventScheduler::Stop() { fRunning = false; }
void G4DNAEventScheduler::Run()
{
G4Timer localtimer;
if(fVerbose > 0)
if(fVerbose > 2)
{
localtimer.Start();
G4cout << "***G4DNAEventScheduler::Run*** for Pixel : " << fPixel << G4endl;
@@ -343,7 +341,7 @@ void G4DNAEventScheduler::Run()
{
RunInMesh();
}
if(fVerbose > 0)
if(fVerbose > 2)
{
if(!fRunning)
{
@@ -360,7 +358,8 @@ void G4DNAEventScheduler::Run()
G4cout << "***G4DNAEventScheduler::Ending::"
<< G4BestUnit(fGlobalTime, "Time")
<< " Events left : " << fpEventSet->size() << G4endl;
if(fVerbose > 1) {
if(fVerbose > 1)
{
fpMesh->PrintMesh();
}
G4cout << " Computing Time : " << localtimer << G4endl;
@@ -374,18 +373,14 @@ void G4DNAEventScheduler::RunInMesh()
{
InitializeInMesh();
}
G4Timer localtimerInMesh;
// if (fVerbose > 0)
if(fVerbose > 0)
{
localtimerInMesh.Start();
G4double C = 20;
G4double D = G4MoleculeTable::Instance()
->GetConfiguration("H2O2")
->GetDiffusionCoefficient();
G4double transferTime = std::pow(fpMesh->GetResolution(), 2) * C / (6 * D);
G4cout << "***G4DNAEventScheduler::RunInMesh*** for Pixel : " << fPixel
<< " transferTime : " << G4BestUnit(transferTime, "Time") << G4endl;
G4cout << " resolution : " << G4BestUnit(fpMesh->GetResolution(), "Length")
G4double resolution = fpMesh->GetResolution();
G4cout << "At Time : " << std::setw(7) << G4BestUnit(fGlobalTime, "Time")
<< " the Mesh has " << fPixel << " x " << fPixel << " x " << fPixel
<< " voxels with Resolution " << G4BestUnit(resolution, "Length")
<< " during next "
<< G4BestUnit(resolution * resolution * C / (6 * D), "Time")
<< G4endl;
}
@@ -400,6 +395,7 @@ void G4DNAEventScheduler::RunInMesh()
}
// if diffusive jumping is avaiable, EventSet is never empty
while(!fpEventSet->Empty() && !fIsChangeMesh && fEndTime > fGlobalTime)
{
Stepping();
@@ -415,37 +411,31 @@ void G4DNAEventScheduler::RunInMesh()
G4cout << "fGlobalTime : " << G4BestUnit(fGlobalTime, "Time")
<< " fTimeStep : " << G4BestUnit(fTimeStep, "Time") << G4endl;
}
G4double C = 20;
G4double D = G4MoleculeTable::Instance()
->GetConfiguration("H2O2")
->GetDiffusionCoefficient();
if(D == 0)
G4double resolution = fpMesh->GetResolution();
fTransferTime = resolution * resolution * C / (6 * D);
if(fTransferTime == 0)
{
G4ExceptionDescription exceptionDescription;
exceptionDescription << "D == 0";
exceptionDescription << "fTransferTime == 0";
G4Exception("G4DNAEventScheduler::RunInMesh", "G4DNAEventScheduler001",
FatalErrorInArgument, exceptionDescription);
}
G4double transferTime = std::pow(fpMesh->GetResolution(), 2) * C / (6 * D);
// if(fStepNumberInMesh > 40000 && fPixel != 1)
if(transferTime < fTimeStep &&
fPixel != 1) // dont change Mesj if fPixel == 1
if(fTransferTime < fTimeStep &&
fPixel != 1) // dont change Mesh if fPixel == 1
{
if(fVerbose > 1)
{
G4cout << " Pixels : " << fPixel << " resolution : "
<< G4BestUnit(fpMesh->GetResolution(), "Length")
<< " fStepNumberInMesh : " << fStepNumberInMesh
<< " at fGlobalTime : " << G4BestUnit(fGlobalTime, "Time")
<< " at fTimeStep : " << G4BestUnit(fTimeStep, "Time")
<< " fReactionNumber : " << fReactionNumber
<< " transferTime : " << G4BestUnit(transferTime, "Time")
<< G4endl;
}
if(fSetChangeMesh)
{
if(fVerbose > 1)
{
G4cout << " Pixels : " << fPixel << " resolution : "
<< G4BestUnit(fpMesh->GetResolution(), "Length")
<< " fStepNumberInMesh : " << fStepNumberInMesh
<< " at fGlobalTime : " << G4BestUnit(fGlobalTime, "Time")
<< " at fTimeStep : " << G4BestUnit(fTimeStep, "Time")
<< " fReactionNumber : " << fReactionNumber
<< " transferTime : " << G4BestUnit(fTransferTime, "Time")
<< G4endl;
}
fIsChangeMesh = true;
}
}
@@ -453,11 +443,10 @@ void G4DNAEventScheduler::RunInMesh()
if(fVerbose > 1)
{
localtimerInMesh.Stop();
G4cout << "***G4DNAEventScheduler::Ending::"
<< G4BestUnit(fGlobalTime, "Time")
<< " Event left : " << fpEventSet->size() << G4endl;
G4cout << " Computing Time : " << localtimerInMesh << " Due to : ";
G4cout << " Due to : ";
if(fpEventSet->Empty())
{
G4cout << "EventSet is Empty" << G4endl;
@@ -492,18 +481,17 @@ void G4DNAEventScheduler::RunInMesh()
void G4DNAEventScheduler::Stepping() // this event loop
{
fStepNumber < fMaxStep ? fStepNumber++ : fRunning = false;
if(fpEventSet->size() > fpMesh->size())
{
G4ExceptionDescription exceptionDescription;
exceptionDescription << "fpEventSet->size() > fpMesh->size()";
exceptionDescription
<< "impossible that fpEventSet->size() > fpMesh->size()";
G4Exception("G4DNAEventScheduler::Stepping", "G4DNAEventScheduler002",
FatalErrorInArgument, exceptionDescription);
};
}
auto selected = fpEventSet->begin();
const auto& key = (*selected)->GetKey();
auto index = fpMesh->GetIndex(key);
auto selected = fpEventSet->begin();
auto index = (*selected)->GetIndex();
if(fVerbose > 1)
{
@@ -522,8 +510,31 @@ void G4DNAEventScheduler::Stepping() // this event loop
fpUpdateSystem->SetGlobalTime(fTimeStep +
fStartTime); // this is just for printing
if(pJumping == nullptr && pReaction == nullptr)
fpGillespieReaction->SetTimeStep(fTimeStep);
if(pJumping == nullptr && pReaction != nullptr)
{
fpUpdateSystem->UpdateSystem(index, *pReaction);
fpEventSet->RemoveEvent(selected);
// create new event
fpGillespieReaction->CreateEvent(index);
fReactionNumber++;
// recordTime in reaction
RecordTime();
}
else if(pJumping != nullptr && pReaction == nullptr)
{
// dont change this
fpUpdateSystem->UpdateSystem(index, *pJumping);
// save jumping Index before delete selected event
auto jumpingIndex = pJumping->second;
fpEventSet->RemoveEvent(selected);
// create new event
// should create Jumping before key
fpGillespieReaction->CreateEvent(jumpingIndex);
fpGillespieReaction->CreateEvent(index);
fJumpingNumber++;
}
else
{
G4ExceptionDescription exceptionDescription;
exceptionDescription << "pJumping == nullptr && pReaction == nullptr";
@@ -531,34 +542,6 @@ void G4DNAEventScheduler::Stepping() // this event loop
FatalErrorInArgument, exceptionDescription);
}
fpGillespieReaction->SetTimeStep(fTimeStep);
if(pJumping == nullptr)
{
fpUpdateSystem->UpdateSystem(index, *pReaction);
fpEventSet->RemoveEvent(selected);
// create new event
fpGillespieReaction->CreateEvent(key);
fReactionNumber++;
// recordTime in reaction
RecordTime();
}
else if(pReaction == nullptr)
{
// dont change this
fpUpdateSystem->UpdateSystem(index, *pJumping);
auto jumpingKey = fpMesh->GetKey(pJumping->second);
fpEventSet->RemoveEvent(selected);
// create new event
// should create Jumping before key
fpGillespieReaction->CreateEvent(jumpingKey);
fpGillespieReaction->CreateEvent(key);
fJumpingNumber++;
}
if(fVerbose > 1)
{
G4cout << "G4DNAEventScheduler::Stepping::end "
@@ -583,45 +566,23 @@ void G4DNAEventScheduler::RecordTime()
auto end = fpMesh->end();
for(; begin != end; begin++)
{
auto node = begin->second;
if(node == nullptr) {
const auto& mapData = std::get<2>(*begin);
if(mapData.empty())
{
continue;
}
for(const auto& it : node->GetMapList())
for(const auto& it : mapData)
{
fCounterMap[recordTime][it.first] += it.second;
}
}
fLastRecoredTime++;
#ifdef DEBUG
PrintRecordTime();
G4MoleculeTable* pMoleculeTable = G4MoleculeTable::Instance();
auto iter = pMoleculeTable->GetConfigurationIterator();
iter.reset();
while(iter())
{
auto conf = iter.value();
G4cout << "GlobalTime : " << G4BestUnit(fGlobalTime, "Time")
<< " recordTime : " << G4BestUnit(recordTime, "Time") << " "
<< conf->GetName()
<< " number : " << fCounterMap[recordTime][conf]
<< " MoleculeCounter : "
<< G4MoleculeCounter::Instance()->GetCurrentNumberOf(conf)
<< G4endl;
assert(G4MoleculeCounter::Instance()->GetCurrentNumberOf(conf) ==
fCounterMap[recordTime][conf]);
}
#endif
}
}
void G4DNAEventScheduler::PrintRecordTime()
{
G4cout << "fCounterMap.size : " << fCounterMap.size() << G4endl;
G4cout << "CounterMap.size : " << fCounterMap.size() << G4endl;
for(const auto& i : fCounterMap)
{
auto map = i.second;
@@ -23,7 +23,6 @@
// ********************************************************************
//
#include "G4DNAMolecularReactionTable.hh"
#include "G4DNAGillespieDirectMethod.hh"
#include "Randomize.hh"
#include "G4PhysicalConstants.hh"
@@ -33,15 +32,10 @@
#include "G4UnitsTable.hh"
#include "G4DNAScavengerMaterial.hh"
#include "G4Scheduler.hh"
#include <cassert>
#include "G4DNAMolecularReactionTable.hh"
G4DNAGillespieDirectMethod::G4DNAGillespieDirectMethod()
: fMolecularReactions(G4DNAMolecularReactionTable::Instance())
, fpMesh(nullptr)
, fTimeStep(0)
, fpEventSet(nullptr)
, fVerbose(0)
, fpScavengerMaterial(nullptr)
{}
G4DNAGillespieDirectMethod::~G4DNAGillespieDirectMethod() = default;
@@ -53,34 +47,40 @@ void G4DNAGillespieDirectMethod::SetEventSet(G4DNAEventSet* pEventSet)
//#define DEBUG 1
G4double G4DNAGillespieDirectMethod::VolumeOfNode(const Index& index)
G4double G4DNAGillespieDirectMethod::VolumeOfNode(const Voxel& voxel)
{
auto LengthY = fpMesh->GetBoundingBox(index).Getyhi() -
fpMesh->GetBoundingBox(index).Getylo();
auto LengthX = fpMesh->GetBoundingBox(index).Getxhi() -
fpMesh->GetBoundingBox(index).Getxlo();
auto LengthZ = fpMesh->GetBoundingBox(index).Getzhi() -
fpMesh->GetBoundingBox(index).Getzlo();
G4double V = LengthY * LengthX * LengthZ;
assert(V > 0);
auto box = std::get<1>(voxel);
auto LengthY = box.Getyhi() - box.Getylo();
auto LengthX = box.Getxhi() - box.Getxlo();
auto LengthZ = box.Getzhi() - box.Getzlo();
G4double V = LengthY * LengthX * LengthZ;
if(V <= 0)
{
G4ExceptionDescription exceptionDescription;
exceptionDescription << "V > 0 !! ";
G4Exception("G4DNAGillespieDirectMethod::VolumeOfNode",
"G4DNAGillespieDirectMethod03", FatalErrorInArgument,
exceptionDescription);
}
return V;
}
G4double G4DNAGillespieDirectMethod::PropensityFunction(const Index& index,
G4double G4DNAGillespieDirectMethod::PropensityFunction(const Voxel& voxel,
MolType moleType)
{
if(moleType->GetDiffusionCoefficient() == 0)
{
return 0.;
}
const auto& node = fpMesh->GetVoxelMapList(index);
G4double alpha = 0;
auto it = node.find(moleType);
const auto& node = std::get<2>(voxel);
const auto& box = std::get<1>(voxel);
G4double alpha = 0;
auto it = node.find(moleType);
if(it != node.end())
{
auto LengthY = fpMesh->GetBoundingBox(index).Getyhi() -
fpMesh->GetBoundingBox(index).Getylo();
G4double d = it->first->GetDiffusionCoefficient() / std::pow(LengthY, 2);
alpha = d * it->second;
auto LengthY = box.Getyhi() - box.Getylo();
G4double d = it->first->GetDiffusionCoefficient() / std::pow(LengthY, 2);
alpha = d * it->second;
#ifdef DEBUG
G4cout << it->first->GetName() << " " << it->second
@@ -92,20 +92,20 @@ G4double G4DNAGillespieDirectMethod::PropensityFunction(const Index& index,
return alpha;
}
G4double G4DNAGillespieDirectMethod::PropensityFunction(const Index& index,
G4double G4DNAGillespieDirectMethod::PropensityFunction(const Voxel& voxel,
ReactionData* data)
{
G4double value;
auto ConfA = data->GetReactant1();
auto ConfB = data->GetReactant2();
G4double scavengerNumber = 0;
auto typeANumber = FindScavenging(index, ConfA, scavengerNumber)
? scavengerNumber
: ComputeNumberInNode(index, ConfA);
auto typeANumber = FindScavenging(voxel, ConfA, scavengerNumber)
? scavengerNumber
: ComputeNumberInNode(voxel, ConfA);
auto typeBNumber = FindScavenging(index, ConfB, scavengerNumber)
auto typeBNumber = FindScavenging(voxel, ConfB, scavengerNumber)
? scavengerNumber
: ComputeNumberInNode(index, ConfB);
: ComputeNumberInNode(voxel, ConfB);
if(typeANumber == 0 || typeBNumber == 0)
{
@@ -113,7 +113,7 @@ G4double G4DNAGillespieDirectMethod::PropensityFunction(const Index& index,
}
auto k =
data->GetObservedReactionRateConstant() / (Avogadro * VolumeOfNode(index));
data->GetObservedReactionRateConstant() / (Avogadro * VolumeOfNode(voxel));
if(ConfA == ConfB)
{
value = typeANumber * (typeBNumber - 1) * k;
@@ -125,17 +125,19 @@ G4double G4DNAGillespieDirectMethod::PropensityFunction(const Index& index,
if(value < 0)
{
G4cout << "G4DNAGillespieDirectMethod::PropensityFunction for : "
<< ConfA->GetName() << "(" << typeANumber << ") + "
<< ConfB->GetName() << "(" << typeBNumber
<< ") : propensity : " << value
<< " GetObservedReactionRateConstant : "
<< data->GetObservedReactionRateConstant()
<< " GetEffectiveReactionRadius : "
<< G4BestUnit(data->GetEffectiveReactionRadius(), "Length")
<< " k : " << k << " volume : " << VolumeOfNode(index)
<< " Index : " << index << G4endl;
assert(false);
G4ExceptionDescription exceptionDescription;
exceptionDescription
<< "G4DNAGillespieDirectMethod::PropensityFunction for : "
<< ConfA->GetName() << "(" << typeANumber << ") + " << ConfB->GetName()
<< "(" << typeBNumber << ") : propensity : " << value
<< " GetObservedReactionRateConstant : "
<< data->GetObservedReactionRateConstant()
<< " GetEffectiveReactionRadius : "
<< G4BestUnit(data->GetEffectiveReactionRadius(), "Length")
<< " k : " << k << " volume : " << VolumeOfNode(voxel) << G4endl;
G4Exception("G4DNAGillespieDirectMethod::PropensityFunction",
"G4DNAGillespieDirectMethod013", FatalErrorInArgument,
exceptionDescription);
}
#ifdef DEBUG
@@ -161,11 +163,11 @@ void G4DNAGillespieDirectMethod::Initialize()
auto end = fpMesh->end();
for(; begin != end; begin++)
{
auto key = begin->first;
auto index = std::get<0>(*begin);
#ifdef DEBUG
fpMesh->PrintVoxel(fpMesh->GetIndex(key));
fpMesh->PrintVoxel(index);
#endif
CreateEvent(key);
CreateEvent(index);
}
}
@@ -173,13 +175,22 @@ void G4DNAGillespieDirectMethod::SetTimeStep(const G4double& stepTime)
{
fTimeStep = stepTime;
}
void G4DNAGillespieDirectMethod::CreateEvent(unsigned int key)
void G4DNAGillespieDirectMethod::CreateEvent(const Index& index)
{
const auto& voxel = fpMesh->GetVoxel(index);
if(std::get<2>(voxel).empty())
{
G4ExceptionDescription exceptionDescription;
exceptionDescription << "This voxel : " << index
<< " is not ready to make event" << G4endl;
G4Exception("G4DNAGillespieDirectMethod::CreateEvent",
"G4DNAGillespieDirectMethod05", FatalErrorInArgument,
exceptionDescription);
}
G4double r1 = G4UniformRand();
G4double r2 = G4UniformRand();
auto index = fpMesh->GetIndex(key);
G4double dAlpha0 = DiffusiveJumping(index);
G4double rAlpha0 = Reaction(index);
G4double dAlpha0 = DiffusiveJumping(voxel);
G4double rAlpha0 = Reaction(voxel);
G4double alphaTotal = dAlpha0 + rAlpha0;
if(alphaTotal == 0)
@@ -202,7 +213,7 @@ void G4DNAGillespieDirectMethod::CreateEvent(unsigned int key)
<< G4endl;
}
auto rSelectedIter = fReactionDataMap.upper_bound(r2 * alphaTotal);
fpEventSet->CreateEvent(timeStep, key, rSelectedIter->second);
fpEventSet->CreateEvent(timeStep, index, rSelectedIter->second);
}
else if(dAlpha0 > 0)
{
@@ -216,26 +227,31 @@ void G4DNAGillespieDirectMethod::CreateEvent(unsigned int key)
auto dSelectedIter = fJumpingDataMap.upper_bound(r2 * alphaTotal - rAlpha0);
auto pDSelected =
std::make_unique<std::pair<MolType, Index>>(dSelectedIter->second);
fpEventSet->CreateEvent(timeStep, key, std::move(pDSelected));
fpEventSet->CreateEvent(timeStep, index, std::move(pDSelected));
}
#ifdef DEBUG
G4cout << G4endl;
#endif
}
G4double G4DNAGillespieDirectMethod::Reaction(const Index& index)
G4double G4DNAGillespieDirectMethod::Reaction(const Voxel& voxel)
{
fReactionDataMap.clear();
G4double alpha0 = 0;
auto dataList = fMolecularReactions->GetVectorOfReactionData();
const auto& dataList =
fMolecularReactions->GetVectorOfReactionData(); // shoud make a member
if(dataList.empty())
{
G4cout << "MolecularReactionTable empty" << G4endl;
assert(false);
G4ExceptionDescription exceptionDescription;
exceptionDescription << "MolecularReactionTable empty" << G4endl;
G4Exception("G4DNAGillespieDirectMethod::Reaction",
"G4DNAGillespieDirectMethod01", FatalErrorInArgument,
exceptionDescription);
}
for(const auto& it : dataList)
{
auto propensity = PropensityFunction(index, it);
auto propensity = PropensityFunction(voxel, it);
if(propensity == 0)
{
continue;
@@ -249,10 +265,11 @@ G4double G4DNAGillespieDirectMethod::Reaction(const Index& index)
return alpha0;
}
G4double G4DNAGillespieDirectMethod::DiffusiveJumping(const Index& index)
G4double G4DNAGillespieDirectMethod::DiffusiveJumping(const Voxel& voxel)
{
fJumpingDataMap.clear();
G4double alpha0 = 0;
auto index = std::get<0>(voxel);
auto NeighboringVoxels = fpMesh->FindNeighboringVoxels(index);
if(NeighboringVoxels.empty())
{
@@ -261,8 +278,8 @@ G4double G4DNAGillespieDirectMethod::DiffusiveJumping(const Index& index)
auto iter = G4MoleculeTable::Instance()->GetConfigurationIterator();
while(iter())
{
const auto conf = iter.value();
auto propensity = PropensityFunction(index, conf);
const auto* conf = iter.value();
auto propensity = PropensityFunction(voxel, conf);
if(propensity == 0)
{
continue;
@@ -286,11 +303,11 @@ G4double G4DNAGillespieDirectMethod::DiffusiveJumping(const Index& index)
}
G4double G4DNAGillespieDirectMethod::ComputeNumberInNode(
const Index& index, MolType type) // depend node ?
const Voxel& voxel, MolType type) // depend node ?
{
if(type->GetDiffusionCoefficient() != 0)
{
const auto& node = fpMesh->GetVoxelMapList(index);
const auto& node = std::get<2>(voxel);
const auto& it = node.find(type);
return (it != node.end()) ? (it->second) : 0;
}
@@ -300,7 +317,7 @@ G4double G4DNAGillespieDirectMethod::ComputeNumberInNode(
}
}
G4bool G4DNAGillespieDirectMethod::FindScavenging(const Index& index,
G4bool G4DNAGillespieDirectMethod::FindScavenging(const Voxel& voxel,
MolType moletype,
G4double& numberOfScavenger)
{
@@ -309,7 +326,7 @@ G4bool G4DNAGillespieDirectMethod::FindScavenging(const Index& index,
{
return false;
}
auto volumeOfNode = VolumeOfNode(index);
auto volumeOfNode = VolumeOfNode(voxel);
if(G4MoleculeTable::Instance()->GetConfiguration("H2O") == moletype)
{
auto factor = Avogadro * volumeOfNode;
@@ -326,19 +343,12 @@ G4bool G4DNAGillespieDirectMethod::FindScavenging(const Index& index,
}
else
{
G4double numberInDouble =
volumeOfNode * std::floor(totalNumber) / fpMesh->GetBoundingBox().Volume();
auto numberInInterg = (int) (std::floor(numberInDouble));
G4double ram = G4UniformRand();
G4double change = numberInDouble - numberInInterg;
if(ram > change)
{
numberOfScavenger = numberInInterg;
}
else
{
numberOfScavenger = numberInInterg + 1;
}
G4double numberInDouble = volumeOfNode * std::floor(totalNumber) /
fpMesh->GetBoundingBox().Volume();
auto numberInInterg = (int64_t) (std::floor(numberInDouble));
G4double change = numberInDouble - numberInInterg;
G4UniformRand() > change ? numberOfScavenger = numberInInterg
: numberOfScavenger = numberInInterg + 1;
return true;
}
}
@@ -243,6 +243,12 @@ void G4DNAIRT::Sampling(G4Track* track){
auto fReactionDatas = fMolReactionTable->GetReactionData(molConfA);
G4double index = -1;
//change the scavenging filter of the IRT beyond 1 us proposed by Naoki and Jose
if(timeMax > 1*us)
{
minTime = timeMax;
}
//
for(size_t u=0; u<fReactionDatas->size();u++){
if((*fReactionDatas)[u]->GetReactant2()->GetDiffusionCoefficient() == 0){
@@ -1,642 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
/*
* G4DNAIRT_geometries.cc
*
* Created on: Jul 23, 2019
* Author: W. G. Shin
* J. Ramos-Mendez and B. Faddegon
*/
#include "G4DNAIRT_geometries.hh"
#include "G4ErrorFunction.hh"
#include "G4SystemOfUnits.hh"
#include "G4PhysicalConstants.hh"
#include "Randomize.hh"
#include "G4DNAMolecularReactionTable.hh"
#include "G4MolecularConfiguration.hh"
#include "G4Molecule.hh"
#include "G4ITReactionChange.hh"
#include "G4ITTrackHolder.hh"
#include "G4ITReaction.hh"
#include "G4Scheduler.hh"
#include "G4MoleculeTable.hh"
#include "G4NavigationHistory.hh"
#include "G4DNAMolecularMaterial.hh"
#include "G4VDNAMolecularGeometry.hh"
using namespace std;
G4DNAIRT_geometries::G4DNAIRT_geometries() :
G4VITReactionProcess(),
fMolReactionTable(reference_cast<const G4DNAMolecularReactionTable*>(fpReactionTable)),
fpReactionModel(nullptr),
fTrackHolder(G4ITTrackHolder::Instance()),
fReactionSet(nullptr),
fGeometry(nullptr)
{
timeMin = G4Scheduler::Instance()->GetStartTime();
timeMax = G4Scheduler::Instance()->GetEndTime();
fXMin = 1e9*nm;
fYMin = 1e9*nm;
fZMin = 1e9*nm;
fXMax = 0e0*nm;
fYMax = 0e0*nm;
fZMax = 0e0*nm;
fNx = 0;
fNy = 0;
fNz = 0;
xiniIndex = 0, yiniIndex = 0, ziniIndex = 0;
xendIndex = 0, yendIndex = 0, zendIndex = 0;
fRCutOff =
1.45 * nm + 2 * std::sqrt(8*9.46e9*nm*nm/s * timeMax); // 95% confidence level
erfc = new G4ErrorFunction();
}
G4DNAIRT_geometries::G4DNAIRT_geometries(G4VDNAReactionModel* pReactionModel)
: G4DNAIRT_geometries()
{
fpReactionModel = pReactionModel;
}
G4DNAIRT_geometries::~G4DNAIRT_geometries()
{
delete erfc;
}
void G4DNAIRT_geometries::Initialize(){
timeMin = G4Scheduler::Instance()->GetGlobalTime();
timeMax = std::min(timeMin + G4Scheduler::Instance()->GetLimitingTimeStep(),
G4Scheduler::Instance()->GetEndTime());
if(timeMin == 0) return;
fTrackHolder = G4ITTrackHolder::Instance();
if(fTrackHolder->GetMainList()->size() == 0) return;
fReactionSet = G4ITReactionSet::Instance();
fReactionSet->CleanAllReaction();
fReactionSet->SortByTime();
spaceBinned.clear();
positionMap.clear();
fRCutOff =
1.45 * nm + 2 * std::sqrt(8*9.46e9*nm*nm/s * (timeMax - timeMin));
xiniIndex = 0;
yiniIndex = 0;
ziniIndex = 0;
xendIndex = 0;
yendIndex = 0;
zendIndex = 0;
fXMin = 1e9*nm;
fYMin = 1e9*nm;
fZMin = 1e9*nm;
fXMax = 0e0*nm;
fYMax = 0e0*nm;
fZMax = 0e0*nm;
fNx = 0;
fNy = 0;
fNz = 0;
fGeometry = fMolReactionTable->GetGeometry();
SpaceBinning(); // 1. binning the space
IRTSampling(); // 2. Sampling of the IRT
}
void G4DNAIRT_geometries::SpaceBinning(){
G4double time_step = G4Scheduler::Instance()->GetPreviousTimeStep()*ps;
auto it_begin = fTrackHolder->GetMainList()->begin();
while(it_begin != fTrackHolder->GetMainList()->end()){
// for diffusion
G4double D = GetMolecule(*it_begin)->GetDiffusionCoefficient();
G4double sqrt_2Dt = sqrt(2 * D * time_step);
G4double x = G4RandGauss::shoot(0,sqrt_2Dt);
G4double y = G4RandGauss::shoot(0,sqrt_2Dt);
G4double z = G4RandGauss::shoot(0,sqrt_2Dt);
G4ThreeVector position_ori = it_begin->GetPosition();
G4ThreeVector position = position_ori + G4ThreeVector(x,y,z);
it_begin->SetPosition(position);
it_begin->SetGlobalTime(timeMax);
if ( fXMin > position.x() ) fXMin = position.x();
if ( fYMin > position.y() ) fYMin = position.y();
if ( fZMin > position.z() ) fZMin = position.z();
if ( fXMax < position.x() ) fXMax = position.x();
if ( fYMax < position.y() ) fYMax = position.y();
if ( fZMax < position.z() ) fZMax = position.z();
++it_begin;
}
fNx = G4int((fXMax-fXMin)/fRCutOff) == 0 ? 1 : G4int((fXMax-fXMin)/fRCutOff);
fNy = G4int((fYMax-fYMin)/fRCutOff) == 0 ? 1 : G4int((fYMax-fYMin)/fRCutOff);
fNz = G4int((fZMax-fZMin)/fRCutOff) == 0 ? 1 : G4int((fZMax-fZMin)/fRCutOff);
}
void G4DNAIRT_geometries::IRTSampling(){
auto it_begin = fTrackHolder->GetMainList()->begin();
while(it_begin != fTrackHolder->GetMainList()->end()){
G4int I = FindBin(fNx, fXMin, fXMax, it_begin->GetPosition().x());
G4int J = FindBin(fNy, fYMin, fYMax, it_begin->GetPosition().y());
G4int K = FindBin(fNz, fZMin, fZMax, it_begin->GetPosition().z());
spaceBinned[I][J][K].push_back(*it_begin);
Sampling(*it_begin);
++it_begin;
}
}
void G4DNAIRT_geometries::Sampling(G4Track* track){
G4Molecule* molA = G4Molecule::GetMolecule(track);
const G4MolecularConfiguration* molConfA = molA->GetMolecularConfiguration();
if(molConfA->GetDiffusionCoefficient() == 0) return;
const vector<const G4MolecularConfiguration*>* reactivesVector =
fMolReactionTable->CanReactWith(molConfA);
if(reactivesVector == nullptr) return;
G4double globalTime = G4Scheduler::Instance()->GetGlobalTime();
G4double minTime = timeMax;
xiniIndex = FindBin(fNx, fXMin, fXMax, track->GetPosition().x()-fRCutOff);
xendIndex = FindBin(fNx, fXMin, fXMax, track->GetPosition().x()+fRCutOff);
yiniIndex = FindBin(fNy, fYMin, fYMax, track->GetPosition().y()-fRCutOff);
yendIndex = FindBin(fNy, fYMin, fYMax, track->GetPosition().y()+fRCutOff);
ziniIndex = FindBin(fNz, fZMin, fZMax, track->GetPosition().z()-fRCutOff);
zendIndex = FindBin(fNz, fZMin, fZMax, track->GetPosition().z()+fRCutOff);
for ( G4int ii = xiniIndex; ii <= xendIndex; ++ii ) {
for ( G4int jj = yiniIndex; jj <= yendIndex; ++jj ) {
for ( G4int kk = ziniIndex; kk <= zendIndex; ++kk ) {
std::vector<G4Track*> spaceBin = spaceBinned[ii][jj][kk];
for ( G4int n = 0; n < (G4int)spaceBinned[ii][jj][kk].size(); ++n ) {
if(!spaceBin[n] || track == spaceBin[n]) continue;
if(spaceBin[n]->GetTrackStatus() == fStopButAlive) continue;
G4Molecule* molB = G4Molecule::GetMolecule(spaceBin[n]);
if(!molB) continue;
const G4MolecularConfiguration* molConfB = molB->GetMolecularConfiguration();
if(molConfB->GetDiffusionCoefficient() == 0) continue;
auto it = std::find(reactivesVector->begin(), reactivesVector->end(), molConfB);
if(it == reactivesVector->end()) continue;
G4ThreeVector orgPosB = spaceBin[n]->GetPosition();
G4double dt = track->GetGlobalTime() - spaceBin[n]->GetGlobalTime();
G4ThreeVector newPosB = orgPosB;
if(dt > 0){
G4double sigma, x, y, z;
G4double diffusionCoefficient = G4Molecule::GetMolecule(spaceBin[n])->GetDiffusionCoefficient();
sigma = std::sqrt(2.0 * diffusionCoefficient * dt);
x = G4RandGauss::shoot(0., 1.0)*sigma;
y = G4RandGauss::shoot(0., 1.0)*sigma;
z = G4RandGauss::shoot(0., 1.0)*sigma;
newPosB = orgPosB + G4ThreeVector(x,y,z);
}else if(dt < 0) continue;
G4double r0 = (newPosB - track->GetPosition()).mag();
G4double irt = GetIndependentReactionTime(molConfA,
molConfB,
r0);
if(irt>=0 && irt<timeMax - globalTime)
{
irt += globalTime;
if(irt < minTime) minTime = irt;
#ifdef DEBUG
G4cout<<irt<<'\t'<<molConfA->GetName()<<" "<<track->GetTrackID()<<'\t'<<molConfB->GetName()<<" "<<spaceBin[n]->GetTrackID()<<'\n';
#endif
fReactionSet->AddReaction(irt,track,spaceBin[n]);
}
}
spaceBin.clear();
}
}
}
// Scavenging & first order reactions
auto fReactionDatas = fMolReactionTable->GetReactionData(molConfA);
G4int index = -1;
for(size_t u=0; u<fReactionDatas->size();++u){
auto molB = (*fReactionDatas)[u]->GetReactant2();
if(molB == G4MoleculeTable::Instance()->GetConfiguration("H2O(B)") ||
molB == G4MoleculeTable::Instance()->GetConfiguration("H3Op(B)") ||
molB == G4MoleculeTable::Instance()->GetConfiguration("OHm(B)")){
G4double kObs = (*fReactionDatas)[u]->GetObservedReactionRateConstant();
if(kObs == 0) continue;
G4double time = -(std::log(1.0 - G4UniformRand())/kObs) + globalTime;
if( time < minTime && time >= globalTime && time < timeMax){
minTime = time;
index = (G4int)u;
}
}
}
if(index != -1){
#ifdef DEBUG
G4cout<<"scavenged: "<<minTime<<'\t'<<molConfA->GetName()<<it_begin->GetTrackID()<<'\n';
#endif
G4Molecule* fakeMol = new G4Molecule((*fReactionDatas)[index]->GetReactant2());
G4Track* fakeTrack = fakeMol->BuildTrack(globalTime,track->GetPosition());
fTrackHolder->Push(fakeTrack);
fReactionSet->AddReaction(minTime, track, fakeTrack);
}
// DNA reactions
if(fGeometry == nullptr) return;
const G4VTouchable* touchable = track->GetTouchable();
if(touchable == nullptr) return;
const G4LogicalVolume* logicalVolume = touchable->GetVolume()->GetLogicalVolume();
const G4ThreeVector& globalPos = track->GetPosition();
const G4ThreeVector& localPos = touchable->GetHistory()->GetTopTransform().TransformPoint(globalPos);
G4double D = GetMolecule(track)->GetDiffusionCoefficient();
G4double time_step = abs(timeMax - timeMin);
G4double search_range = 2*sqrt(2*D*time_step);
std::vector<G4VPhysicalVolume*> result_pv;
result_pv.clear();
fGeometry->FindNearbyMolecules(logicalVolume,
localPos,
result_pv,
search_range);
if(result_pv.empty()) return;
for(auto physicalVolume : result_pv){
const G4Material* material = physicalVolume->GetLogicalVolume()->GetMaterial();
G4MolecularConfiguration* dna_molConf =
G4DNAMolecularMaterial::Instance()->GetMolecularConfiguration(material);
auto it = std::find(reactivesVector->begin(), reactivesVector->end(), dna_molConf);
if(it == reactivesVector->end()) continue;
G4ThreeVector pos = physicalVolume->GetTranslation();
G4ThreeVector globalPos_DNA = touchable->GetHistory()->GetTopTransform().Inverse().TransformPoint(pos);
G4double r0 = (pos - localPos).mag();
G4double irt = GetIndependentReactionTime(molConfA,dna_molConf,r0);
if(irt>=0 && irt<timeMax - globalTime)
{
index = -1;
for(size_t i=0;i<positionMap.size();++i){
if(globalPos_DNA == positionMap[i].first){
index = (G4int)i;
break;
}
}
G4Track* DNATrack;
if(index == -1){
auto DNAMol = new G4Molecule(dna_molConf);
DNATrack = DNAMol->BuildTrack(globalTime,globalPos_DNA);
DNATrack->SetTrackStatus(fAlive);
fTrackHolder->Push(DNATrack);
positionMap.push_back(std::make_pair(globalPos_DNA,DNATrack));
}else{
DNATrack = positionMap[index].second;
}
irt += globalTime;
if(irt < minTime) minTime = irt;
#ifdef DEBUG
G4cout<<irt<<'\t'<<globalPos_DNA<<'\t'<<molConfA->GetName()<<" "<<track->GetTrackID()<<'\t'<<dna_molConf->GetName()<<" "<<DNATrack->GetTrackID()<<'\n';
#endif
fReactionSet->AddReaction(irt,track,DNATrack);
}
}
}
G4double G4DNAIRT_geometries::GetIndependentReactionTime(const G4MolecularConfiguration* molA, const G4MolecularConfiguration* molB, G4double distance) {
const auto pMoleculeA = molA;
const auto pMoleculeB = molB;
auto fReactionData = fMolReactionTable->GetReactionData(pMoleculeA, pMoleculeB);
G4int reactionType = fReactionData->GetReactionType();
G4double r0 = distance;
if(r0 == 0) r0 += 1e-3*nm;
G4double irt = -1 * ps;
G4double D = molA->GetDiffusionCoefficient() +
molB->GetDiffusionCoefficient();
if(D == 0) D += 1e-20*(m2/s);
G4double rc = fReactionData->GetOnsagerRadius();
if ( reactionType == 0){
G4double sigma = fReactionData->GetEffectiveReactionRadius();
if(sigma > r0) return 0; // contact reaction
if( rc != 0) r0 = -rc / (1-std::exp(rc/r0));
G4double Winf = sigma/r0;
G4double W = G4UniformRand();
if ( W > 0 && W < Winf ) irt = (0.25/D) * std::pow( (r0-sigma)/erfc->erfcInv(r0*W/sigma), 2 );
return irt;
}
else if ( reactionType == 1 ){
G4double sigma = fReactionData->GetReactionRadius();
G4double kact = fReactionData->GetActivationRateConstant();
G4double kdif = fReactionData->GetDiffusionRateConstant();
G4double kobs = fReactionData->GetObservedReactionRateConstant();
G4double a, b, Winf;
if ( rc == 0 ) {
a = 1/sigma * kact / kobs;
b = (r0 - sigma) / 2;
} else {
G4double v = kact/Avogadro/(4*CLHEP::pi*pow(sigma,2) * exp(-rc / sigma));
G4double alpha = v+rc*D/(pow(sigma,2)*(1-exp(-rc/sigma)));
a = 4*pow(sigma,2)*alpha/(D*pow(rc,2))*pow(sinh(rc/(2*sigma)),2);
b = rc/4*(cosh(rc/(2*r0))/sinh(rc/(2*r0))-cosh(rc/(2*sigma))/sinh(rc/(2*sigma)));
r0 = -rc/(1-std::exp(rc/r0));
sigma = fReactionData->GetEffectiveReactionRadius();
}
if(sigma > r0){
if(fReactionData->GetProbability() > G4UniformRand()) return 0;
else return irt;
}
Winf = sigma / r0 * kobs / kdif;
if(Winf > G4UniformRand()) irt = SamplePDC(a,b)/D;
return irt;
}
return -1 * ps;
}
G4int G4DNAIRT_geometries::FindBin(G4int n, G4double xmin, G4double xmax, G4double value) {
G4int bin = -1;
if ( value <= xmin )
bin = 0; //1;
else if ( value >= xmax) //!(xmax < value) ) //value >= xmax )
bin = n-1; //n;
else
bin = G4int( n * ( value - xmin )/( xmax - xmin ) ); //bin = 1 + G4int( n * ( value - xmin )/( xmax - xmin ) );
if ( bin < 0 ) bin = 0;
if ( bin >= n ) bin = n-1;
return bin;
}
G4double G4DNAIRT_geometries::SamplePDC(G4double a, G4double b) {
G4double p = 2.0 * std::sqrt(2.0*b/a);
G4double q = 2.0 / std::sqrt(2.0*b/a);
G4double M = max(1.0/(a*a),3.0*b/a);
G4double X, U, lambdax;
G4int ntrials = 0;
while(1) {
// Generate X
U = G4UniformRand();
if ( U < p/(p + q * M) ) X = pow(U * (p + q * M) / 2, 2);
else X = pow(2/((1-U)*(p+q*M)/M),2);
U = G4UniformRand();
lambdax = std::exp(-b*b/X) * ( 1.0 - a * std::sqrt(CLHEP::pi * X) * erfc->erfcx(b/std::sqrt(X) + a*std::sqrt(X)));
if ((X <= 2.0*b/a && U <= lambdax) ||
(X >= 2.0*b/a && U*M/X <= lambdax)) break;
ntrials++;
if ( ntrials > 10000 ){
G4cout<<"Totally rejected"<<'\n';
return -1.0;
}
}
return X;
}
std::unique_ptr<G4ITReactionChange> G4DNAIRT_geometries::MakeReaction(const G4Track& trackA,
const G4Track& trackB)
{
std::unique_ptr<G4ITReactionChange> pChanges(new G4ITReactionChange());
pChanges->Initialize(trackA, trackB);
const auto pMoleculeA = GetMolecule(trackA)->GetMolecularConfiguration();
const auto pMoleculeB = GetMolecule(trackB)->GetMolecularConfiguration();
const auto pReactionData = fMolReactionTable->GetReactionData(pMoleculeA, pMoleculeB);
G4double globalTime = G4Scheduler::Instance()->GetGlobalTime();
G4double effectiveReactionRadius = pReactionData->GetEffectiveReactionRadius();
const G4double D1 = pMoleculeA->GetDiffusionCoefficient();
const G4double D2 = pMoleculeB->GetDiffusionCoefficient();
G4ThreeVector r1 = trackA.GetPosition();
G4ThreeVector r2 = trackB.GetPosition();
if(r1 == r2) r2 += G4ThreeVector(0,0,1e-3*nm);
G4ThreeVector S1 = r1 - r2;
G4double r0 = S1.mag();
S1.setMag(effectiveReactionRadius);
G4double dt = globalTime - trackA.GetGlobalTime();
if(dt != 0 && (D1 + D2) != 0 && r0 != 0){
G4double s12 = 2.0 * D1 * dt;
G4double s22 = 2.0 * D2 * dt;
if(s12 == 0) r2 = r1;
else if(s22 == 0) r1 = r2;
else{
G4double alpha = effectiveReactionRadius * r0 / (2*(D1 + D2)*dt);
G4ThreeVector S2 = (r1 + (s12 / s22)*r2) + G4ThreeVector(G4RandGauss::shoot(0, s12 + s22 * s22 / s12),
G4RandGauss::shoot(0, s12 + s22 * s22 / s12),
G4RandGauss::shoot(0, s12 + s22 * s22 / s12));
S1.setPhi(rad * G4UniformRand() * 2.0 * CLHEP::pi);
S1.setTheta(rad * std::acos(1.0 + 1./alpha * std::log(1.0 - G4UniformRand() * (1 - std::exp(-2.0 * alpha)))));
r1 = (D1 * S1 + D2 * S2) / (D1 + D2);
r2 = D2 * (S2 - S1) / (D1 + D2);
}
}
auto pTrackA = const_cast<G4Track*>(pChanges->GetTrackA());
auto pTrackB = const_cast<G4Track*>(pChanges->GetTrackB());
pTrackA->SetPosition(r1);
pTrackB->SetPosition(r2);
pTrackA->SetGlobalTime(globalTime);
pTrackB->SetGlobalTime(globalTime);
pTrackA->SetTrackStatus(fStopButAlive);
pTrackB->SetTrackStatus(fStopButAlive);
const G4int nbProducts = pReactionData->GetNbProducts();
if(nbProducts){
const G4double sqrD1 = D1 == 0. ? 0. : std::sqrt(D1);
const G4double sqrD2 = D2 == 0. ? 0. : std::sqrt(D2);
const G4double inv_numerator = 1./(sqrD1 + sqrD2);
const G4ThreeVector reactionSite = sqrD2 * inv_numerator * trackA.GetPosition()
+ sqrD1 * inv_numerator * trackB.GetPosition();
std::vector<G4ThreeVector> position;
if(nbProducts == 1){
position.push_back(reactionSite);
}else if(nbProducts == 2){
position.push_back(trackA.GetPosition());
position.push_back(trackB.GetPosition());
}else if (nbProducts == 3){
position.push_back(reactionSite);
position.push_back(trackA.GetPosition());
position.push_back(trackB.GetPosition());
}
for(G4int u = 0; u < nbProducts; ++u){
auto product = new G4Molecule(pReactionData->GetProduct(u));
auto productTrack = product->BuildTrack(globalTime,
position[u]);
productTrack->SetTrackStatus(fAlive);
fTrackHolder->Push(productTrack);
pChanges->AddSecondary(productTrack);
G4int I = FindBin(fNx, fXMin, fXMax, position[u].x());
G4int J = FindBin(fNy, fYMin, fYMax, position[u].y());
G4int K = FindBin(fNz, fZMin, fZMax, position[u].z());
spaceBinned[I][J][K].push_back(productTrack);
Sampling(productTrack);
}
}
fTrackHolder->MergeSecondariesWithMainList();
pChanges->KillParents(true);
return pChanges;
}
std::vector<std::unique_ptr<G4ITReactionChange>> G4DNAIRT_geometries::FindReaction(
G4ITReactionSet* pReactionSet,
const G4double /*currentStepTime*/,
const G4double fGlobalTime,
const G4bool /*reachedUserStepTimeLimit*/)
{
std::vector<std::unique_ptr<G4ITReactionChange>> fReactionInfo;
fReactionInfo.clear();
if (pReactionSet == nullptr)
{
return fReactionInfo;
}
auto fReactionsetInTime = pReactionSet->GetReactionsPerTime();
assert(fReactionsetInTime.begin() != fReactionsetInTime.end());
auto it_begin = fReactionsetInTime.begin();
while(it_begin != fReactionsetInTime.end())
{
G4double irt = it_begin->get()->GetTime();
if(fGlobalTime < irt) break;
pReactionSet->SelectThisReaction(*it_begin);
G4Track* pTrackA = it_begin->get()->GetReactants().first;
G4Track* pTrackB = it_begin->get()->GetReactants().second;
auto pReactionChange = MakeReaction(*pTrackA, *pTrackB);
if(pReactionChange){
fReactionInfo.push_back(std::move(pReactionChange));
}
fReactionsetInTime = pReactionSet->GetReactionsPerTime();
it_begin = fReactionsetInTime.begin();
}
return fReactionInfo;
}
G4bool G4DNAIRT_geometries::TestReactibility(const G4Track& /*trackA*/,
const G4Track& /*trackB*/,
G4double /*currentStepTime*/,
G4bool /*userStepTimeLimit*/) /*const*/
{
return true;
}
void G4DNAIRT_geometries::SetReactionModel(G4VDNAReactionModel* model)
{
fpReactionModel = model;
}
@@ -27,108 +27,102 @@
#include "globals.hh"
#include "G4DNAMakeReaction.hh"
#include <G4DNAMolecularReactionTable.hh>
#include <memory>
#include "G4DNAIndependentReactionTimeModel.hh"
#include "G4DNAIndependentReactionTimeStepper.hh"
#include "G4DiffusionControlledReactionModel.hh"
#include "G4Molecule.hh"
#include "G4ReferenceCast.hh"
#include "G4VDNAReactionModel.hh"
#include "G4DNAReactionTypeManager.hh"
#include "G4ChemicalMoleculeFinder.hh"
G4DNAIndependentReactionTimeModel::G4DNAIndependentReactionTimeModel(const G4String& name)
: G4DNAIndependentReactionTimeModel(name,
std::unique_ptr<G4DNAIndependentReactionTimeStepper>
(new G4DNAIndependentReactionTimeStepper()),
std::unique_ptr<G4DNAMakeReaction>
(new G4DNAMakeReaction()))
G4DNAIndependentReactionTimeModel::G4DNAIndependentReactionTimeModel(
const G4String& name)
: G4DNAIndependentReactionTimeModel(
name, std::make_unique<G4DNAIndependentReactionTimeStepper>(),
std::make_unique<G4DNAMakeReaction>())
{}
G4DNAIndependentReactionTimeModel::G4DNAIndependentReactionTimeModel(const G4String& name,
std::unique_ptr<G4VITTimeStepComputer> pTimeStepper,
std::unique_ptr<G4VITReactionProcess> pReactionProcess)
: G4VITStepModel(std::move(pTimeStepper),
std::move(pReactionProcess),
name)
, fMolecularReactionTable(reference_cast<const G4DNAMolecularReactionTable*>(fpReactionTable))
G4DNAIndependentReactionTimeModel::G4DNAIndependentReactionTimeModel(
const G4String& name, std::unique_ptr<G4VITTimeStepComputer> pTimeStepper,
std::unique_ptr<G4VITReactionProcess> pReactionProcess)
: G4VITStepModel(std::move(pTimeStepper), std::move(pReactionProcess), name)
{
fType1 = G4Molecule::ITType();
fType2 = G4Molecule::ITType();
fType1 = G4Molecule::ITType();
fType2 = G4Molecule::ITType();
}
G4DNAIndependentReactionTimeModel::~G4DNAIndependentReactionTimeModel() = default;
G4DNAIndependentReactionTimeModel::~G4DNAIndependentReactionTimeModel() =
default;
void G4DNAIndependentReactionTimeModel::Initialize()
{
if(fpReactionTable == nullptr)
{
SetReactionTable(G4DNAMolecularReactionTable::GetReactionTable());
}
if(fpReactionTable == nullptr)
{
SetReactionTable(G4DNAMolecularReactionTable::GetReactionTable());
}
if(!fpReactionModel)
{
fpReactionModel.reset(new G4DiffusionControlledReactionModel());
}
if(!fpReactionModel)
{
fpReactionModel = std::make_unique<G4DiffusionControlledReactionModel>();
}
fpReactionModel->SetReactionTable((const G4DNAMolecularReactionTable*) fpReactionTable);
fpReactionModel->SetReactionTable(
(const G4DNAMolecularReactionTable*) fpReactionTable);
((G4DiffusionControlledReactionModel*) fpReactionModel.get())->SetReactionTypeManager(fReactionTypeManager.get());
((G4DNAMakeReaction*) fpReactionProcess.get())
->SetReactionModel(fpReactionModel.get());
((G4DNAMakeReaction*) fpReactionProcess.get())->SetReactionModel(fpReactionModel.get());
((G4DNAMakeReaction*) fpReactionProcess.get())
->SetTimeStepComputer(fpTimeStepper.get());
((G4DNAMakeReaction*) fpReactionProcess.get())->SetTimeStepComputer(fpTimeStepper.get());
((G4DNAIndependentReactionTimeStepper*) fpTimeStepper.get())->SetReactionModel(fpReactionModel.get());
((G4DNAIndependentReactionTimeStepper*) fpTimeStepper.get())
->SetReactionModel(fpReactionModel.get());
((G4DNAIndependentReactionTimeStepper*) fpTimeStepper.get())->SetReactionTypeManager(fReactionTypeManager.get());
((G4DNAIndependentReactionTimeStepper*) fpTimeStepper.get())
->SetReactionProcess((fpReactionProcess).get());
((G4DNAIndependentReactionTimeStepper*) fpTimeStepper.get())->SetReactionProcess((fpReactionProcess).get());
G4ChemicalMoleculeFinder::Instance()->Clear();
G4VITStepModel::Initialize();
G4ChemicalMoleculeFinder::Instance()->Clear();
G4ChemicalMoleculeFinder::Instance()->SetOctreeUsed(true);
G4VITStepModel::Initialize();
}
void G4DNAIndependentReactionTimeModel::PrintInfo()
{
#ifdef G4VERBOSE
if(G4Threading::IsMultithreadedApplication())
if(G4Threading::IsMultithreadedApplication())
{
if(G4Threading::G4GetThreadId() == 0)
{
if(G4Threading::G4GetThreadId() == 0)
{
G4VITStepModel::PrintInfo();
G4cout<<G4endl;
G4cout << fName << " will be used ==========================" << G4endl;
G4cout<<G4endl;
G4cout << "==============================="
"========================================"<<G4endl;
G4cout<<G4endl;
}
}
else
{
G4VITStepModel::PrintInfo();
G4cout<<G4endl;
G4cout << fName << " will be used ==========================" << G4endl;
G4cout<<G4endl;
G4cout << "==============================="
"========================================"<<G4endl;
G4cout<<G4endl;
G4VITStepModel::PrintInfo();
G4cout << G4endl;
G4cout << fName << " will be used ==========================" << G4endl;
G4cout << G4endl;
G4cout << "==============================="
"========================================"
<< G4endl;
G4cout << G4endl;
}
}
else
{
G4VITStepModel::PrintInfo();
G4cout << G4endl;
G4cout << fName << " will be used ==========================" << G4endl;
G4cout << G4endl;
G4cout << "==============================="
"========================================"
<< G4endl;
G4cout << G4endl;
}
#endif
}
void G4DNAIndependentReactionTimeModel::SetReactionModel(G4VDNAReactionModel* pReactionModel)
void G4DNAIndependentReactionTimeModel::SetReactionModel(
G4VDNAReactionModel* pReactionModel)
{
fpReactionModel.reset(pReactionModel);
fpReactionModel.reset(pReactionModel);
}
G4VDNAReactionModel* G4DNAIndependentReactionTimeModel::GetReactionModel()
{
return fpReactionModel.get();
}
void G4DNAIndependentReactionTimeModel::SetReactionTypeManager(G4VReactionTypeManager* pReactionProcessManager)
{
fReactionTypeManager.reset(pReactionProcessManager);
}
return fpReactionModel.get();
}
@@ -25,465 +25,452 @@
// 20/2/2019
// Author: HoangTRAN
#include <memory>
#include "G4DNAIndependentReactionTimeStepper.hh"
#include "G4VDNAReactionModel.hh"
#include "G4DNAMolecularReactionTable.hh"
#include "G4memory.hh"
#include "G4UnitsTable.hh"
#include "G4Molecule.hh"
#include "G4ChemicalMoleculeFinder.hh"
#include "G4MolecularConfiguration.hh"
#include "G4DNAChemistryManager.hh"
#include "G4DNAReactionTypeManager.hh"
#include "G4DNAMakeReaction.hh"
#include "G4ITReaction.hh"
#include "G4ITReactionChange.hh"
#include "G4Scheduler.hh"
#include "G4ITTrackHolder.hh"
#include "G4IRTUtils.hh"
#include "Randomize.hh"
#include "G4DiffusionControlledReactionModel.hh"
using namespace std;
using namespace CLHEP;
G4DNAIndependentReactionTimeStepper::Utils::Utils(const G4Track& trackA,
const G4Track& trackB)
: fTrackA(trackA)
, fTrackB(trackB)
: fTrackA(trackA)
, fTrackB(trackB)
{
fpMoleculeA = GetMolecule(trackA);
fpMoleculeB = GetMolecule(trackA);
fpMoleculeA = GetMolecule(trackA);
fpMoleculeB = GetMolecule(trackA);
}
G4DNAIndependentReactionTimeStepper::G4DNAIndependentReactionTimeStepper()
: G4VITTimeStepComputer()
, fHasAlreadyReachedNullTime(false)
, fMolecularReactionTable(reference_cast<const G4DNAMolecularReactionTable*>(fpReactionTable))
, fReactionModel(nullptr)
, fpTrackContainer(G4ITTrackHolder::Instance())
, fReactionSet(G4ITReactionSet::Instance())
, fVerbose(0)
, fRCutOff(G4IRTUtils::GetRCutOff())
, fReactionTypeManager(nullptr)
, fpReactionProcess(nullptr)
: G4VITTimeStepComputer()
{
fReactionSet->SortByTime();
fReactionSet->SortByTime();
}
void G4DNAIndependentReactionTimeStepper::Prepare()
{
G4VITTimeStepComputer::Prepare();
fSampledPositions.clear();
BuildChemicalMoleculeFinder()
G4VITTimeStepComputer::Prepare();
fSampledPositions.clear();
BuildChemicalMoleculeFinder()
}
void G4DNAIndependentReactionTimeStepper::InitializeForNewTrack()
{
if (fReactants != nullptr)
{
fReactants.reset();
}
fSampledMinTimeStep = DBL_MAX;
fHasAlreadyReachedNullTime = false;
if(fReactants != nullptr)
{
fReactants.reset();
}
fSampledMinTimeStep = DBL_MAX;
fHasAlreadyReachedNullTime = false;
}
template<typename T>
inline G4bool IsInf(T value)
G4double G4DNAIndependentReactionTimeStepper::CalculateStep(
const G4Track& trackA, const G4double& userMinTimeStep)
{
return std::numeric_limits<T>::has_infinity
&& value == std::numeric_limits<T>::infinity();
}
G4double
G4DNAIndependentReactionTimeStepper::CalculateStep(const G4Track& trackA,
const G4double& userMinTimeStep)
{
auto pMoleculeA = GetMolecule(trackA);
InitializeForNewTrack();
fUserMinTimeStep = userMinTimeStep;
auto pMoleculeA = GetMolecule(trackA);
InitializeForNewTrack();
fUserMinTimeStep = userMinTimeStep;
fCheckedTracks.insert(trackA.GetTrackID());
#ifdef G4VERBOSE
if (fVerbose)
{
G4cout
<< "_______________________________________________________________________"
<< G4endl;
G4cout << "G4DNAIndependentReactionTimeStepper::CalculateStep" << G4endl;
G4cout << "Check done for molecule : " << pMoleculeA->GetName()
<< " (" << trackA.GetTrackID() << ") "
<< G4endl;
}
if(fVerbose != 0)
{
G4cout << "________________________________________________________________"
"_______"
<< G4endl;
G4cout << "G4DNAIndependentReactionTimeStepper::CalculateStep" << G4endl;
G4cout << "Check done for molecule : " << pMoleculeA->GetName() << " ("
<< trackA.GetTrackID() << ") " << G4endl;
}
#endif
auto pMolConfA = pMoleculeA->GetMolecularConfiguration();
auto pMolConfA = pMoleculeA->GetMolecularConfiguration();
const auto pReactantList = fMolecularReactionTable->CanReactWith(pMolConfA);
const auto pReactantList = fMolecularReactionTable->CanReactWith(pMolConfA);
if (!pReactantList)
{
if(pReactantList == nullptr)
{
#ifdef G4VERBOSE
if (fVerbose > 1)
{
G4cout << "!!!!!!!!!!!!!!!!!!!!" << G4endl;
G4cout << "!!! WARNING" << G4endl;
G4cout << "G4DNAIndependentReactionTimeStepper::CalculateStep will return infinity "
if(fVerbose > 1)
{
G4cout << "!!!!!!!!!!!!!!!!!!!!" << G4endl;
G4cout << "!!! WARNING" << G4endl;
G4cout << "G4DNAIndependentReactionTimeStepper::CalculateStep will "
"return infinity "
"for the reaction because the molecule "
<< pMoleculeA->GetName()
<< " does not have any reactants given in the reaction table."
<< G4endl;
G4cout << "!!!!!!!!!!!!!!!!!!!!" << G4endl;
}
#endif
return DBL_MAX;
<< pMoleculeA->GetName()
<< " does not have any reactants given in the reaction table."
<< G4endl;
G4cout << "!!!!!!!!!!!!!!!!!!!!" << G4endl;
}
#endif
return DBL_MAX;
}
G4int nbReactives = pReactantList->size();
G4int nbReactives = pReactantList->size();
if (nbReactives == 0)
{
if(nbReactives == 0)
{
#ifdef G4VERBOSE
// DEBUG
if (fVerbose)
{
G4cout << "!!!!!!!!!!!!!!!!!!!!" << G4endl;
G4cout << "!!! WARNING" << G4endl;
G4cout << "G4DNAIndependentReactionTimeStepper::CalculateStep will return infinity "
// DEBUG
if(fVerbose != 0)
{
G4cout << "!!!!!!!!!!!!!!!!!!!!" << G4endl;
G4cout << "!!! WARNING" << G4endl;
G4cout << "G4DNAIndependentReactionTimeStepper::CalculateStep will "
"return infinity "
"for the reaction because the molecule "
<< pMoleculeA->GetName()
<< " does not have any reactants given in the reaction table."
<< "This message can also result from a wrong implementation of the reaction table."
<< G4endl;
G4cout << "!!!!!!!!!!!!!!!!!!!!" << G4endl;
}
<< pMoleculeA->GetName()
<< " does not have any reactants given in the reaction table."
<< "This message can also result from a wrong implementation of "
"the reaction table."
<< G4endl;
G4cout << "!!!!!!!!!!!!!!!!!!!!" << G4endl;
}
#endif
return DBL_MAX;
}
fReactants.reset(new vector<G4Track*>());
fReactionModel->Initialise(pMolConfA, trackA);
for (G4int i = 0; i < nbReactives; i++)
return DBL_MAX;
}
fReactants = std::make_shared<vector<G4Track*>>();
fReactionModel->Initialise(pMolConfA, trackA);
for(G4int i = 0; i < nbReactives; i++)
{
auto pMoleculeB = (*pReactantList)[i];
G4int key = pMoleculeB->GetMoleculeID();
// fRCutOff = G4IRTUtils::GetRCutOff(1 * ps);
fRCutOff = G4IRTUtils::GetRCutOff();
//______________________________________________________________
// Retrieve reaction range
const G4double Reff = fReactionModel->GetReactionRadius(i);
std::vector<std::pair<G4TrackList::iterator, G4double>> resultIndices;
resultIndices.clear();
G4ChemicalMoleculeFinder::Instance()->FindNearestInRange(
trackA, key, fRCutOff, resultIndices);
if(resultIndices.empty())
{
auto pMoleculeB = (*pReactantList)[i];
G4int key = pMoleculeB->GetMoleculeID();
//fRCutOff = G4IRTUtils::GetRCutOff(1 * ps);
fRCutOff = G4IRTUtils::GetRCutOff();
//______________________________________________________________
// Retrieve reaction range
const G4double Reff = fReactionModel->GetReactionRadius(i);
std::vector<std::pair<G4TrackList::iterator,G4double>> resultIndices;
resultIndices.clear();
G4ChemicalMoleculeFinder::Instance()->
FindNearestInRange(trackA,
key,
fRCutOff,
resultIndices);
if(resultIndices.empty())
{
continue;
}
for(auto& it : resultIndices)
{
G4Track* pTrackB = *(std::get<0>(it));
if(pTrackB == &trackA)
{
continue;
}
if(pTrackB == nullptr)
{
G4ExceptionDescription exceptionDescription;
exceptionDescription << "No trackB no valid";
G4Exception("G4DNAIndependentReactionTimeModel"
"::BuildReactionMap()", "NO_TRACK02",
FatalException, exceptionDescription);
}
Utils utils(trackA, *pTrackB);
auto pMolB = GetMolecule(pTrackB);
auto pMolConfB = pMolB->GetMolecularConfiguration();
G4double distance = (trackA.GetPosition() - pTrackB->GetPosition()).mag();
if(distance * distance < Reff * Reff)
{
auto processTable = *(fReactionTypeManager->GetReactionTypeTable());
auto typeOfReaction = (G4int)GetReactionType(trackA, *pTrackB);
if(processTable[typeOfReaction]->
GeminateRecombinationProbability(pMolConfA, pMolConfB))
{
if (!fHasAlreadyReachedNullTime)
{
fReactants->clear();
fHasAlreadyReachedNullTime = true;
}
fSampledMinTimeStep = 0.;
CheckAndRecordResults(utils);
}
}
else
{
G4double tempMinET = GetTimeToEncounter(trackA, *pTrackB);
if(tempMinET < 0 ||
tempMinET > G4Scheduler::Instance()->GetEndTime())
{
continue;
}
if (tempMinET >= fSampledMinTimeStep)
{
continue;
}
fSampledMinTimeStep = tempMinET;
fReactants->clear();
CheckAndRecordResults(utils);
}
}
continue;
}
for(auto& it : resultIndices)
{
G4Track* pTrackB = *(std::get<0>(it));
if(pTrackB == &trackA)
{
continue;
}
if(pTrackB == nullptr)
{
G4ExceptionDescription exceptionDescription;
exceptionDescription << "No trackB no valid";
G4Exception("G4DNAIndependentReactionTimeStepper"
"::CalculateStep()",
"G4DNAIndependentReactionTimeStepper007", FatalException,
exceptionDescription);
}
if(fCheckedTracks.find(pTrackB->GetTrackID()) != fCheckedTracks.end())
{
continue;
}
Utils utils(trackA, *pTrackB);
auto pMolB = GetMolecule(pTrackB);
auto pMolConfB = pMolB->GetMolecularConfiguration();
G4double distance = (trackA.GetPosition() - pTrackB->GetPosition()).mag();
if(distance * distance < Reff * Reff)
{
auto reactionData =
fMolecularReactionTable->GetReactionData(pMolConfA, pMolConfB);
if(reactionData->GetProbability() > G4UniformRand())
{
if(!fHasAlreadyReachedNullTime)
{
fReactants->clear();
fHasAlreadyReachedNullTime = true;
}
fSampledMinTimeStep = 0.;
CheckAndRecordResults(utils);
}
}
else
{
G4double tempMinET = GetTimeToEncounter(trackA, *pTrackB);
if(tempMinET < 0 || tempMinET > G4Scheduler::Instance()->GetEndTime())
{
continue;
}
if(tempMinET >= fSampledMinTimeStep)
{
continue;
}
fSampledMinTimeStep = tempMinET;
fReactants->clear();
CheckAndRecordResults(utils);
}
}
}
#ifdef G4VERBOSE
if (fVerbose)
if(fVerbose != 0)
{
G4cout << "G4DNAIndependentReactionTimeStepper::CalculateStep will finally "
"return :"
<< G4BestUnit(fSampledMinTimeStep, "Time") << G4endl;
if(fVerbose > 1)
{
G4cout << "G4DNAIndependentReactionTimeStepper::CalculateStep will finally return :"
<< G4BestUnit(fSampledMinTimeStep, "Time") << G4endl;
G4cout << "Selected reactants for trackA: " << pMoleculeA->GetName()
<< " (" << trackA.GetTrackID() << ") are: ";
if (fVerbose > 1)
{
G4cout << "Selected reactants for trackA: " << pMoleculeA->GetName()
<< " (" << trackA.GetTrackID() << ") are: ";
vector<G4Track*>::iterator it;
for (it = fReactants->begin(); it != fReactants->end(); it++)
{
G4Track* trackB = *it;
G4cout << GetMolecule(trackB)->GetName() << " ("
<< trackB->GetTrackID() << ") \t ";
}
G4cout << G4endl;
}
vector<G4Track*>::iterator it;
for(it = fReactants->begin(); it != fReactants->end(); it++)
{
G4Track* trackB = *it;
G4cout << GetMolecule(trackB)->GetName() << " (" << trackB->GetTrackID()
<< ") \t ";
}
G4cout << G4endl;
}
}
#endif
for (const auto& it : *fReactants)
{
auto pTrackB = it;
fSampledPositions[pTrackB->GetTrackID()] = pTrackB->GetPosition();
}
return fSampledMinTimeStep;
return fSampledMinTimeStep;
}
void G4DNAIndependentReactionTimeStepper::CheckAndRecordResults(const Utils& utils)
void G4DNAIndependentReactionTimeStepper::CheckAndRecordResults(
const Utils& utils)
{
if (utils.fTrackB.GetTrackStatus() != fAlive)
{
return;
}
if(utils.fTrackB.GetTrackStatus() != fAlive)
{
return;
}
if (&utils.fTrackB == &utils.fTrackA)
{
G4ExceptionDescription exceptionDescription;
exceptionDescription<< "A track is reacting with itself"
" (which is impossible) ie fpTrackA == trackB"<< G4endl;
exceptionDescription << "Molecule A is of type : "
<< utils.fpMoleculeA->GetName() << " with trackID : "
<< utils.fTrackA.GetTrackID()<<" and B : "
<< utils.fpMoleculeB->GetName() << " with trackID : "
<< utils.fTrackB.GetTrackID() << G4endl;
G4Exception("G4DNAIndependentReactionTimeStepper::RetrieveResults",
"G4DNAIndependentReactionTimeStepper003", FatalErrorInArgument,
exceptionDescription);
}
if(&utils.fTrackB == &utils.fTrackA)
{
G4ExceptionDescription exceptionDescription;
exceptionDescription << "A track is reacting with itself"
" (which is impossible) ie fpTrackA == trackB"
<< G4endl;
exceptionDescription << "Molecule A is of type : "
<< utils.fpMoleculeA->GetName()
<< " with trackID : " << utils.fTrackA.GetTrackID()
<< " and B : " << utils.fpMoleculeB->GetName()
<< " with trackID : " << utils.fTrackB.GetTrackID()
<< G4endl;
G4Exception("G4DNAIndependentReactionTimeStepper::RetrieveResults",
"G4DNAIndependentReactionTimeStepper003", FatalErrorInArgument,
exceptionDescription);
}
if (fabs(utils.fTrackB.GetGlobalTime() - utils.fTrackA.GetGlobalTime())
> utils.fTrackA.GetGlobalTime() * (1. - 1. / 100))
{
// DEBUG
G4ExceptionDescription exceptionDescription;
exceptionDescription
<< "The interacting tracks are not synchronized in time" << G4endl;
exceptionDescription
<< "trackB->GetGlobalTime() != fpTrackA.GetGlobalTime()" << G4endl;
if(fabs(utils.fTrackB.GetGlobalTime() - utils.fTrackA.GetGlobalTime()) >
utils.fTrackA.GetGlobalTime() * (1. - 1. / 100))
{
// DEBUG
G4ExceptionDescription exceptionDescription;
exceptionDescription
<< "The interacting tracks are not synchronized in time" << G4endl;
exceptionDescription
<< "trackB->GetGlobalTime() != fpTrackA.GetGlobalTime()" << G4endl;
exceptionDescription << "fpTrackA : trackID : " << utils.fTrackA.GetTrackID()
<< "\t Name :" << utils.fpMoleculeA->GetName()
<< "\t fpTrackA->GetGlobalTime() = "
<< G4BestUnit(utils.fTrackA.GetGlobalTime(), "Time") << G4endl;
exceptionDescription << "fpTrackA : trackID : "
<< utils.fTrackA.GetTrackID()
<< "\t Name :" << utils.fpMoleculeA->GetName()
<< "\t fpTrackA->GetGlobalTime() = "
<< G4BestUnit(utils.fTrackA.GetGlobalTime(), "Time")
<< G4endl;
exceptionDescription << "trackB : trackID : " << utils.fTrackB.GetTrackID()
<< "\t Name :" << utils.fpMoleculeB->GetName()
<< "\t trackB->GetGlobalTime() = "
<< G4BestUnit(utils.fTrackB.GetGlobalTime(), "Time") << G4endl;
exceptionDescription << "trackB : trackID : " << utils.fTrackB.GetTrackID()
<< "\t Name :" << utils.fpMoleculeB->GetName()
<< "\t trackB->GetGlobalTime() = "
<< G4BestUnit(utils.fTrackB.GetGlobalTime(), "Time")
<< G4endl;
G4Exception("G4DNAIndependentReactionTimeStepper::RetrieveResults",
"G4DNAIndependentReactionTimeStepper004", FatalErrorInArgument,
exceptionDescription);
}
fReactants->push_back(const_cast<G4Track*>(&utils.fTrackB));
G4Exception("G4DNAIndependentReactionTimeStepper::RetrieveResults",
"G4DNAIndependentReactionTimeStepper004", FatalErrorInArgument,
exceptionDescription);
}
fReactants->push_back(const_cast<G4Track*>(&utils.fTrackB));
}
std::unique_ptr<G4ITReactionChange>
G4DNAIndependentReactionTimeStepper::FindReaction(G4ITReactionSet* pReactionSet,
const G4double& currentStepTime,
const G4double& /*previousStepTime*/,
const G4bool& /*reachedUserStepTimeLimit*/)
G4DNAIndependentReactionTimeStepper::FindReaction(
G4ITReactionSet* pReactionSet, const G4double& currentStepTime,
const G4double& /*previousStepTime*/,
const G4bool& /*reachedUserStepTimeLimit*/)
{
if (pReactionSet == nullptr)
{
return nullptr;
}
G4ITReactionPerTime& reactionPerTime = pReactionSet->GetReactionsPerTime();
if(reactionPerTime.empty())
{
return nullptr;
}
for (auto reaction_i = reactionPerTime.begin();
reaction_i != reactionPerTime.end();
reaction_i = reactionPerTime.begin())
{
G4Track* pTrackA = (*reaction_i)->GetReactants().first;
if (pTrackA->GetTrackStatus() == fStopAndKill)
{
continue;
}
G4Track* pTrackB = (*reaction_i)->GetReactant(pTrackA);
if (pTrackB->GetTrackStatus() == fStopAndKill)
{
continue;
}
if (pTrackB == pTrackA)
{
G4ExceptionDescription exceptionDescription;
exceptionDescription
<< "The IT reaction process sent back a reaction between trackA and trackB. ";
exceptionDescription << "The problem is trackA == trackB";
G4Exception("G4ITModelProcessor::FindReaction",
"ITModelProcessor005",
FatalErrorInArgument,
exceptionDescription);
}
pReactionSet->SelectThisReaction(*reaction_i);
if(fpReactionProcess != nullptr && fpReactionProcess->TestReactibility(*pTrackA,
*pTrackB,
currentStepTime,
false))
{
pTrackA->SetPosition(fSampledPositions[pTrackA->GetTrackID()]);
pTrackB->SetPosition(fSampledPositions[pTrackB->GetTrackID()]);
auto pReactionChange = fpReactionProcess->MakeReaction(*pTrackA, *pTrackB);
if (pReactionChange == nullptr)
{
return nullptr;
}
return pReactionChange;
}
}
if(pReactionSet == nullptr)
{
return nullptr;
}
G4ITReactionPerTime& reactionPerTime = pReactionSet->GetReactionsPerTime();
if(reactionPerTime.empty())
{
return nullptr;
}
for(auto reaction_i = reactionPerTime.begin();
reaction_i != reactionPerTime.end(); reaction_i = reactionPerTime.begin())
{
G4Track* pTrackA = (*reaction_i)->GetReactants().first;
if(pTrackA->GetTrackStatus() == fStopAndKill)
{
continue;
}
G4Track* pTrackB = (*reaction_i)->GetReactant(pTrackA);
if(pTrackB->GetTrackStatus() == fStopAndKill)
{
continue;
}
if(pTrackB == pTrackA)
{
G4ExceptionDescription exceptionDescription;
exceptionDescription << "The IT reaction process sent back a reaction "
"between trackA and trackB. ";
exceptionDescription << "The problem is trackA == trackB";
G4Exception("G4DNAIndependentReactionTimeStepper::FindReaction",
"G4DNAIndependentReactionTimeStepper02", FatalErrorInArgument,
exceptionDescription);
}
pReactionSet->SelectThisReaction(*reaction_i);
if(fpReactionProcess != nullptr &&
fpReactionProcess->TestReactibility(*pTrackA, *pTrackB, currentStepTime,
false))
{
if((fSampledPositions.find(pTrackA->GetTrackID()) ==
fSampledPositions.end() &&
(fSampledPositions.find(pTrackB->GetTrackID()) ==
fSampledPositions.end())))
{
G4ExceptionDescription exceptionDescription;
exceptionDescription
<< "The positions of trackA and trackB have no counted ";
G4Exception("G4DNAIndependentReactionTimeStepper::FindReaction",
"G4DNAIndependentReactionTimeStepper0001",
FatalErrorInArgument, exceptionDescription);
}
pTrackA->SetPosition(fSampledPositions[pTrackA->GetTrackID()]);
pTrackB->SetPosition(fSampledPositions[pTrackB->GetTrackID()]);
auto pReactionChange =
fpReactionProcess->MakeReaction(*pTrackA, *pTrackB);
if(pReactionChange == nullptr)
{
return nullptr;
}
return pReactionChange;
}
}
return nullptr;
}
void G4DNAIndependentReactionTimeStepper::SetReactionModel(G4VDNAReactionModel* pReactionModel)
void G4DNAIndependentReactionTimeStepper::SetReactionModel(
G4VDNAReactionModel* pReactionModel)
{
fReactionModel = pReactionModel;
fReactionModel = pReactionModel;
}
G4VDNAReactionModel* G4DNAIndependentReactionTimeStepper::GetReactionModel()
{
return fReactionModel;
return fReactionModel;
}
void G4DNAIndependentReactionTimeStepper::SetVerbose(G4int flag)
{
fVerbose = flag;
fVerbose = flag;
}
ReactionType G4DNAIndependentReactionTimeStepper::GetReactionType(const G4Track& trackA,
const G4Track& trackB)
G4double G4DNAIndependentReactionTimeStepper::GetTimeToEncounter(
const G4Track& trackA, const G4Track& trackB)
{
auto pMoleculeA = GetMolecule(trackA)->GetMolecularConfiguration();
auto pMoleculeB = GetMolecule(trackB)->GetMolecularConfiguration();
auto pData = fMolecularReactionTable->GetReactionData(pMoleculeA,pMoleculeB);
G4int reactionID = pData->GetReactionID();
return fReactionTypeManager->GetReactionTypeByID(reactionID);
G4double timeToReaction =
dynamic_cast<G4DiffusionControlledReactionModel*>(fReactionModel)
->GetTimeToEncounter(trackA, trackB);
return timeToReaction;
}
G4double G4DNAIndependentReactionTimeStepper::GetTimeToEncounter(const G4Track& trackA,
const G4Track& trackB)
void G4DNAIndependentReactionTimeStepper::SetReactionProcess(
G4VITReactionProcess* pReactionProcess)
{
if(fReactionTypeManager == nullptr)
fpReactionProcess = pReactionProcess;
}
G4double G4DNAIndependentReactionTimeStepper::CalculateMinTimeStep(
G4double /*currentGlobalTime*/, G4double definedMinTimeStep)
{
G4double fTSTimeStep = DBL_MAX;
fCheckedTracks.clear();
for(auto pTrack : *fpTrackContainer->GetMainList())
{
if(pTrack == nullptr)
{
G4ExceptionDescription exceptionDescription;
exceptionDescription << "fpProManager is not "
"initialized ";
G4Exception("G4DNAIndependentReactionTimeModel::"
"GetIndependentReactionTime()",
"G4DNAIndependentReactionTimeModel002",
FatalErrorInArgument,exceptionDescription);
}
auto processTable = *(fReactionTypeManager->GetReactionTypeTable());
ReactionType reactionType = GetReactionType(trackA,trackB);
#ifdef DEBUG
G4cout<<"A: "<<GetMolecule(trackA)->GetName()<<"("<<trackA.GetTrackID()<<")"<<" + B : "
<<GetMolecule(trackB)->GetName()<<"("<<trackB.GetTrackID()<<")"<<G4endl;
#endif
return processTable[(G4int)reactionType]->GetTimeToEncounter(trackA,trackB);
}
void G4DNAIndependentReactionTimeStepper::SetReactionTypeManager(G4VReactionTypeManager* typeManager)
{
fReactionTypeManager = ((G4DNAReactionTypeManager*)typeManager);
}
void G4DNAIndependentReactionTimeStepper::SetReactionProcess(G4VITReactionProcess* pReactionProcess)
{
fpReactionProcess = pReactionProcess;
}
G4double G4DNAIndependentReactionTimeStepper::CalculateMinTimeStep(G4double /*currentGlobalTime*/, G4double definedMinTimeStep)
{
G4double fTSTimeStep = DBL_MAX;
for (auto pTrack : *fpTrackContainer->GetMainList())
{
if (pTrack == nullptr)
{
G4ExceptionDescription exceptionDescription;
exceptionDescription << "No track found.";
G4Exception("G4Scheduler::CalculateMinStep", "ITScheduler006",
FatalErrorInArgument, exceptionDescription);
continue;
}
G4TrackStatus trackStatus = pTrack->GetTrackStatus();
if (trackStatus == fStopAndKill || trackStatus == fStopButAlive)
{
continue;
}
G4double sampledMinTimeStep = CalculateStep(*pTrack, definedMinTimeStep);
G4TrackVectorHandle reactants = GetReactants();
if (sampledMinTimeStep < fTSTimeStep)
{
fTSTimeStep = sampledMinTimeStep;
fReactionSet->CleanAllReaction();
if (reactants)
{
fReactionSet->AddReactions(fTSTimeStep,
const_cast<G4Track*>(pTrack),
reactants);
ResetReactants();
}
}
else if (fTSTimeStep == sampledMinTimeStep && G4bool(reactants))
{
fReactionSet->AddReactions(fTSTimeStep,
const_cast<G4Track*>(pTrack),
reactants);
ResetReactants();
}
else if (reactants)
{
ResetReactants();
}
G4ExceptionDescription exceptionDescription;
exceptionDescription << "No track found.";
G4Exception("G4DNAIndependentReactionTimeStepper::CalculateMinTimeStep",
"G4DNAIndependentReactionTimeStepper006",
FatalErrorInArgument, exceptionDescription);
continue;
}
return fTSTimeStep;
G4TrackStatus trackStatus = pTrack->GetTrackStatus();
if(trackStatus == fStopAndKill || trackStatus == fStopButAlive)
{
continue;
}
G4double sampledMinTimeStep = CalculateStep(*pTrack, definedMinTimeStep);
G4TrackVectorHandle reactants = GetReactants();
if(sampledMinTimeStep < fTSTimeStep)
{
fTSTimeStep = sampledMinTimeStep;
fReactionSet->CleanAllReaction();
if(reactants)
{
fReactionSet->AddReactions(fTSTimeStep, const_cast<G4Track*>(pTrack),
reactants);
fSampledPositions[pTrack->GetTrackID()] = pTrack->GetPosition();
for(const auto& it : *fReactants)
{
auto pTrackB = it;
// G4cout<<"position : "<<pTrackB->GetTrackID()<<G4endl;
fSampledPositions[pTrackB->GetTrackID()] = pTrackB->GetPosition();
}
ResetReactants();
}
}
else if(fTSTimeStep == sampledMinTimeStep && G4bool(reactants))
{
fReactionSet->AddReactions(fTSTimeStep, const_cast<G4Track*>(pTrack),
reactants);
fSampledPositions[pTrack->GetTrackID()] = pTrack->GetPosition();
for(const auto& it : *fReactants)
{
auto pTrackB = it;
// G4cout<<"position : "<<pTrackB->GetTrackID()<<G4endl;
fSampledPositions[pTrackB->GetTrackID()] = pTrackB->GetPosition();
}
ResetReactants();
}
else if(reactants)
{
ResetReactants();
}
}
return fTSTimeStep;
}
@@ -120,7 +120,7 @@ G4DNAIonElasticModel::Initialise (
G4double scaleFactor = 1e-16*cm*cm;
char *path = getenv("G4LEDATA");
const char *path = G4FindDataDir("G4LEDATA");
if (!path)
{
@@ -30,7 +30,10 @@
#include "G4DNAChemistryManager.hh"
#include "G4DNAMolecularMaterial.hh"
#include "G4Exp.hh"
#include "G4Pow.hh"
#include "G4Alpha.hh"
static G4Pow * gpow = G4Pow::GetInstance();
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
using namespace std;
@@ -86,11 +89,11 @@ void G4DNAMillerGreenExcitationModel::Initialise(const G4ParticleDefinition* par
G4DNAGenericIonsManager *instance;
instance = G4DNAGenericIonsManager::Instance();
G4ParticleDefinition* protonDef = G4Proton::ProtonDefinition();
G4ParticleDefinition* hydrogenDef = instance->GetIon("hydrogen");
G4ParticleDefinition* alphaPlusPlusDef = instance->GetIon("alpha++");
G4ParticleDefinition* alphaPlusDef = instance->GetIon("alpha+");
G4ParticleDefinition* heliumDef = instance->GetIon("helium");
protonDef = G4Proton::ProtonDefinition();
hydrogenDef = instance->GetIon("hydrogen");
alphaPlusPlusDef = G4Alpha::Alpha();
alphaPlusDef = instance->GetIon("alpha+");
heliumDef = instance->GetIon("helium");
G4String proton;
G4String hydrogen;
@@ -232,19 +235,16 @@ G4double G4DNAMillerGreenExcitationModel::CrossSectionPerVolume(const G4Material
// Calculate total cross section for model
G4DNAGenericIonsManager *instance;
instance = G4DNAGenericIonsManager::Instance();
if (
particleDefinition != G4Proton::ProtonDefinition()
particleDefinition != protonDef
&&
particleDefinition != instance->GetIon("hydrogen")
particleDefinition != hydrogenDef
&&
particleDefinition != instance->GetIon("alpha++")
particleDefinition != alphaPlusPlusDef
&&
particleDefinition != instance->GetIon("alpha+")
particleDefinition != alphaPlusDef
&&
particleDefinition != instance->GetIon("helium")
particleDefinition != heliumDef
)
return 0;
@@ -279,9 +279,9 @@ G4double G4DNAMillerGreenExcitationModel::CrossSectionPerVolume(const G4Material
// add ONE or TWO electron-water excitation for alpha+ and helium
/*
if ( particleDefinition == instance->GetIon("alpha+")
if ( particleDefinition == alphaPlusDef
||
particleDefinition == instance->GetIon("helium")
particleDefinition == heliumDef
)
{
@@ -295,10 +295,10 @@ G4double G4DNAMillerGreenExcitationModel::CrossSectionPerVolume(const G4Material
excitationXS->CrossSectionPerVolume(material,G4Electron::ElectronDefinition(),k*0.511/3728,tmp,tmp)
/material->GetAtomicNumDensityVector()[1];
if ( particleDefinition == instance->GetIon("alpha+") )
if ( particleDefinition == alphaPlusDef )
crossSection = crossSection + sigmaExcitation ;
if ( particleDefinition == instance->GetIon("helium") )
if ( particleDefinition == heliumDef )
crossSection = crossSection + 2*sigmaExcitation ;
delete excitationXS;
@@ -315,10 +315,10 @@ G4double G4DNAMillerGreenExcitationModel::CrossSectionPerVolume(const G4Material
excitationXS->CrossSectionPerVolume(material,G4Electron::ElectronDefinition(),k*0.511/3728,tmp,tmp)
/material->GetAtomicNumDensityVector()[1];
if ( particleDefinition == instance->GetIon("alpha+") )
if ( particleDefinition == alphaPlusDef )
crossSection = crossSection + sigmaExcitation ;
if ( particleDefinition == instance->GetIon("helium") )
if ( particleDefinition == heliumDef )
crossSection = crossSection + 2*sigmaExcitation ;
delete excitationXS;
@@ -421,14 +421,12 @@ G4double G4DNAMillerGreenExcitationModel::PartialCrossSection(G4double k, G4int
const G4double Eliq[5]={ 8.17*eV, 10.13*eV, 11.31*eV, 12.91*eV, 14.50*eV};
G4int particleTypeIndex = 0;
G4DNAGenericIonsManager* instance;
instance = G4DNAGenericIonsManager::Instance();
if (particleDefinition == G4Proton::ProtonDefinition()) particleTypeIndex=0;
if (particleDefinition == instance->GetIon("hydrogen")) particleTypeIndex=0;
if (particleDefinition == instance->GetIon("alpha++")) particleTypeIndex=1;
if (particleDefinition == instance->GetIon("alpha+")) particleTypeIndex=2;
if (particleDefinition == instance->GetIon("helium")) particleTypeIndex=3;
if (particleDefinition == protonDef) particleTypeIndex=0;
if (particleDefinition == hydrogenDef) particleTypeIndex=0;
if (particleDefinition == alphaPlusPlusDef) particleTypeIndex=1;
if (particleDefinition == alphaPlusDef) particleTypeIndex=2;
if (particleDefinition == heliumDef) particleTypeIndex=3;
G4double tCorrected;
tCorrected = k * kineticEnergyCorrection[particleTypeIndex];
@@ -440,21 +438,21 @@ G4double G4DNAMillerGreenExcitationModel::PartialCrossSection(G4double k, G4int
G4int z = 10;
G4double numerator;
numerator = std::pow(z * aj[excitationLevel], omegaj[excitationLevel]) *
std::pow(tCorrected - Eliq[excitationLevel], nu);
numerator = gpow->powA(z * aj[excitationLevel], omegaj[excitationLevel]) *
gpow->powA(tCorrected - Eliq[excitationLevel], nu);
// H case : see S. Uehara et al. IJRB 77, 2, 139-154 (2001) - section 3.3
if (particleDefinition == instance->GetIon("hydrogen"))
numerator = std::pow(z * 0.75*aj[excitationLevel], omegaj[excitationLevel]) *
std::pow(tCorrected - Eliq[excitationLevel], nu);
if (particleDefinition == hydrogenDef)
numerator = gpow->powA(z * 0.75*aj[excitationLevel], omegaj[excitationLevel]) *
gpow->powA(tCorrected - Eliq[excitationLevel], nu);
G4double power;
power = omegaj[excitationLevel] + nu;
G4double denominator;
denominator = std::pow(jj[excitationLevel], power) + std::pow(tCorrected, power);
denominator = gpow->powA(jj[excitationLevel], power) + gpow->powA(tCorrected, power);
G4double zEff = particleDefinition->GetPDGCharge() / eplus + particleDefinition->GetLeptonNumber();
@@ -462,7 +460,7 @@ G4double G4DNAMillerGreenExcitationModel::PartialCrossSection(G4double k, G4int
sCoefficient[1][particleTypeIndex] * S_2s(k, Eliq[excitationLevel], slaterEffectiveCharge[1][particleTypeIndex], 2.) +
sCoefficient[2][particleTypeIndex] * S_2p(k, Eliq[excitationLevel], slaterEffectiveCharge[2][particleTypeIndex], 2.) );
if (particleDefinition == instance->GetIon("hydrogen")) zEff = 1.;
if (particleDefinition == hydrogenDef) zEff = 1.;
G4double cross = sigma0 * zEff * zEff * numerator / denominator;
@@ -478,14 +476,11 @@ G4int G4DNAMillerGreenExcitationModel::RandomSelect(G4double k,const G4ParticleD
G4double value = 0.;
std::deque<G4double> values;
G4DNAGenericIonsManager *instance;
instance = G4DNAGenericIonsManager::Instance();
if ( particle == instance->GetIon("alpha++") ||
particle == G4Proton::ProtonDefinition()||
particle == instance->GetIon("hydrogen") ||
particle == instance->GetIon("alpha+") ||
particle == instance->GetIon("helium")
if ( particle == alphaPlusPlusDef ||
particle == protonDef||
particle == hydrogenDef ||
particle == alphaPlusDef ||
particle == heliumDef
)
{
while (i > 0)
@@ -511,9 +506,9 @@ G4int G4DNAMillerGreenExcitationModel::RandomSelect(G4double k,const G4ParticleD
/*
// add ONE or TWO electron-water excitation for alpha+ and helium
if ( particle == instance->GetIon("alpha+")
if ( particle == alphaPlusDef
||
particle == instance->GetIon("helium")
particle == heliumDef
)
{
while (i>0)
@@ -529,8 +524,8 @@ G4int G4DNAMillerGreenExcitationModel::RandomSelect(G4double k,const G4ParticleD
G4double partial = PartialCrossSection(k,i,particle);
if (particle == instance->GetIon("alpha+")) partial = PartialCrossSection(k,i,particle) + sigmaExcitation;
if (particle == instance->GetIon("helium")) partial = PartialCrossSection(k,i,particle) + 2*sigmaExcitation;
if (particle == alphaPlusDef) partial = PartialCrossSection(k,i,particle) + sigmaExcitation;
if (particle == heliumDef) partial = PartialCrossSection(k,i,particle) + 2*sigmaExcitation;
values.push_front(partial);
value += partial;
@@ -203,7 +203,7 @@ void G4DNAPTBElasticModel::ReadDiffCSFile(const G4String& materialName,
// This method is not yet standard.
// get the path of the G4LEDATA data folder
char *path = std::getenv("G4LEDATA");
const char* path = G4FindDataDir("G4LEDATA");
// if it is not found then quit and print error message
if(!path)
{
@@ -437,7 +437,7 @@ void G4DNAPTBIonisationModel::ReadDiffCSFile(const G4String& materialName,
// To read and save the informations contained within the differential cross section files
// get the path of the G4LEDATA data folder
char *path = std::getenv("G4LEDATA");
const char* path = G4FindDataDir("G4LEDATA");
// if it is not found then quit and print error message
if(!path)
{
@@ -1,168 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
#include "G4DNAPartiallyDiffusionControlled.hh"
#include "G4IRTUtils.hh"
#include "G4DNAMolecularReactionTable.hh"
#include "G4VDNAReactionModel.hh"
#include "G4SystemOfUnits.hh"
#include "G4PhysicalConstants.hh"
#include "G4MolecularConfiguration.hh"
#include "Randomize.hh"
#include "G4Molecule.hh"
#include "G4ITReactionChange.hh"
#include "G4VReactionType.hh"
#include "G4Electron_aq.hh"
#include "G4ErrorFunction.hh"
G4DNAPartiallyDiffusionControlled::G4DNAPartiallyDiffusionControlled()
: G4VReactionType()
{}
G4DNAPartiallyDiffusionControlled::~G4DNAPartiallyDiffusionControlled() = default;
G4bool
G4DNAPartiallyDiffusionControlled::GeminateRecombinationProbability(const G4MolecularConfiguration* mA,
const G4MolecularConfiguration* mB)
{
auto reactionData = G4DNAMolecularReactionTable::Instance()
->GetReactionData(mA, mB);
G4double D = GetDiffusionCoefficient(mA, mB);
G4double R = mA->GetVanDerVaalsRadius() + mB->GetVanDerVaalsRadius();
const G4double Rs = 0.3 * nm;
G4double kobs = reactionData->GetObservedReactionRateConstant() / Avogadro;
if(mA->GetCharge() * mB->GetCharge() == 0)
{
G4double kdif = 4 * CLHEP::pi * D * R * Avogadro;
G4double kact = G4IRTUtils::GetKact(kobs, kdif);
return G4UniformRand() < Rs / ( Rs + ( kdif / kact ) * ( R + Rs ));
}
else
{
G4double rc = 0.71 * nm * mA->GetCharge() *
mB->GetCharge();
G4double sigmaEff = G4IRTUtils::EffectiveDistance(rc, R);
G4double kdif = 4 * CLHEP::pi * D * sigmaEff;
G4double kact = G4IRTUtils::GetKact(kobs, kdif);
G4double a = std::exp( -rc / R );
G4double b = std::exp( -rc / ( R + Rs ) );
G4double Preact = ( a - b ) / ( a - b - ( kdif / kact ) * ( 1 - a ) );
return G4UniformRand() < Preact;
}
}
G4double
G4DNAPartiallyDiffusionControlled::GetDiffusionCoefficient(const G4MolecularConfiguration* mA,
const G4MolecularConfiguration* mB)
{
G4double D;
if(mA == mB)
{
D = (mA->GetDiffusionCoefficient());
}
else
{
D = (mA->GetDiffusionCoefficient() +
mB->GetDiffusionCoefficient());
}
return D;
}
G4double G4DNAPartiallyDiffusionControlled::GetTimeToEncounter(const G4Track& trackA,
const G4Track& trackB)
{
auto pMolConfA = GetMolecule(trackA)->GetMolecularConfiguration();
auto pMolConfB = GetMolecule(trackB)->GetMolecularConfiguration();
G4double D = GetDiffusionCoefficient(pMolConfA, pMolConfB);
auto reactionData = G4DNAMolecularReactionTable::Instance()
->GetReactionData(pMolConfA, pMolConfB);
G4double Reff;
G4double kobs = reactionData->GetObservedReactionRateConstant();
G4double distance = (trackA.GetPosition() - trackB.GetPosition()).mag();
G4double SmoluchowskiRadius;
G4double RVal = pMolConfA->GetVanDerVaalsRadius() + pMolConfB->GetVanDerVaalsRadius();
if((pMolConfA->GetCharge() != 0) &&
(pMolConfB->GetCharge() != 0))
{
G4double rc = 0.71 * nm * pMolConfA->GetCharge() *
pMolConfB->GetCharge();
distance = G4IRTUtils::EffectiveDistance( rc, distance );
Reff = G4IRTUtils::EffectiveDistance( rc, RVal );
SmoluchowskiRadius = Reff;
}
else
{
SmoluchowskiRadius = RVal;
}
G4double Winf = SmoluchowskiRadius / distance;
G4double U1 = G4UniformRand();
G4double U2 = G4UniformRand();
G4double U = G4UniformRand();
G4double X = 0;
G4double irt_1 = -1.0 * ps;
G4double irt_2;
G4double kdif = 4 * CLHEP::pi * D * SmoluchowskiRadius * Avogadro;
G4double kact = G4IRTUtils::GetKact(kobs, kdif);
if ( U < Winf )
{
G4double d = ( distance - SmoluchowskiRadius ) /
G4ErrorFunction::erfcInv( U / Winf );
irt_1 = ( 1.0 / ( 4 * D ) ) * d * d;
}
if( irt_1 < 0)
{
return irt_1;
}
else
{
G4double rateFactor = kact / ( kact + kdif );
if( U1 > rateFactor )
{
return -1.0 * ps;
}
G4double Y = std::abs(G4RandGauss::shoot(0.0,std::sqrt(2)));
if( Y > 0)
{
X = - ( G4Log( U2 ) ) / Y;
}
G4double f = X * SmoluchowskiRadius * kdif / ( kact + kdif );
irt_2 = ( f * f ) / D ;
}
return irt_1 + irt_2;
}
@@ -322,7 +322,7 @@ G4int G4DNAQuinnPlasmonExcitationModel::GetNValenceElectron(G4int z)
if(!datadir)
{
datadir = getenv("G4LEDATA");
datadir = G4FindDataDir("G4LEDATA");
if(!datadir)
{
G4Exception("G4DNAQuinnPlasmonExcitationModel::GetNValenceElectron()"
@@ -0,0 +1,260 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// Created on 2022/03/03
//
// Authors: A.D. Dominguez-Munoz, M.I. Gallardo, M.C. Bordage,
// Z. Francis, S. Incerti, M.A. Cortes-Giraldo
//
// Contact: M.A. Cortes-Giraldo (miancortes -at- us.es)
//
//
#include "G4DNARPWBAExcitationModel.hh"
#include "G4SystemOfUnits.hh"
#include "G4DNAChemistryManager.hh"
#include "G4DNAMolecularMaterial.hh"
#include <map>
using namespace std;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4DNARPWBAExcitationModel::G4DNARPWBAExcitationModel(
const G4ParticleDefinition*, const G4String& nam)
: G4VEmModel(nam)
{
// Verbosity scale:
// 0 = nothing
// 1 = warning for energy non-conservation
// 2 = details of energy budget
// 3 = calculation of cross sections, file openings, sampling of atoms
// 4 = entering in methods
if(verboseLevel > 0)
{
G4cout << "RPWBA excitation model is constructed " << G4endl;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4DNARPWBAExcitationModel::~G4DNARPWBAExcitationModel() = default;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4DNARPWBAExcitationModel::Initialise(const G4ParticleDefinition* particle,
const G4DataVector& /*cuts*/)
{
if(isInitialised)
{
return;
}
if(verboseLevel > 3)
{
G4cout << "Calling G4DNARPWBAExcitationModel::Initialise()" << G4endl;
}
if(fParticleDefinition != nullptr && fParticleDefinition != particle)
{
G4Exception("G4DNARPWBAExcitationModel::Initialise", "em0001",
FatalException,
"Model already initialized for another particle type.");
}
fTableFile = "dna/sigma_excitation_p_RPWBA";
fLowEnergy = 100. * MeV;
fHighEnergy = 300. * MeV;
//SetLowEnergyLimit(fLowEnergy);
//SetHighEnergyLimit(fHighEnergy);
G4double scaleFactor = 1 * cm * cm;
fTableData = make_unique<G4DNACrossSectionDataSet>(new G4LogLogInterpolation,
eV, scaleFactor);
fTableData->LoadData(fTableFile);
if(verboseLevel > 0)
{
G4cout << "RPWBA excitation model is initialized " << G4endl
<< "Energy range: " << LowEnergyLimit() / eV << " eV - "
<< HighEnergyLimit() / keV << " keV for "
<< particle->GetParticleName() << G4endl;
}
// Initialize water density pointer
if(G4Material::GetMaterial("G4_WATER") != nullptr){
fpMolWaterDensity =
G4DNAMolecularMaterial::Instance()->GetNumMolPerVolTableFor(
G4Material::GetMaterial("G4_WATER"));
}else{
G4ExceptionDescription exceptionDescription;
exceptionDescription << "G4_WATER does not exist :";
G4Exception("G4DNARPWBAIonisationModel::Initialise", "em00020",
FatalException, exceptionDescription);
}
fParticleChangeForGamma = GetParticleChangeForGamma();
isInitialised = true;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4DNARPWBAExcitationModel::CrossSectionPerVolume(
const G4Material* material, const G4ParticleDefinition* particleDefinition,
G4double ekin, G4double, G4double)
{
if(verboseLevel > 3)
{
G4cout << "Calling CrossSectionPerVolume() of G4DNARPWBAExcitationModel"
<< G4endl;
}
if(fTableData == nullptr)
{
G4ExceptionDescription exceptionDescription;
exceptionDescription << "No cross section data ";
G4Exception("G4DNARPWBAIonisationModel::CrossSectionPerVolume", "em00120",
FatalException, exceptionDescription);
}
if(particleDefinition != fParticleDefinition)
return 0;
// Calculate total cross section for model
G4double sigma = 0;
G4double waterDensity = (*fpMolWaterDensity)[material->GetIndex()];
if(ekin >= fLowEnergy && ekin <= fHighEnergy)
{
sigma = fTableData->FindValue(ekin);
}
if(verboseLevel > 2)
{
G4cout << "__________________________________" << G4endl;
G4cout << "G4DNARPWBAExcitationModel - XS INFO START" << G4endl;
G4cout << "Kinetic energy(eV)=" << ekin / eV
<< " particle : " << particleDefinition->GetParticleName() << G4endl;
G4cout << "Cross section per water molecule (cm^2)=" << sigma / cm / cm
<< G4endl;
G4cout << "Cross section per water molecule (cm^-1)="
<< sigma * waterDensity / (1. / cm) << G4endl;
G4cout << "G4DNARPWBAExcitationModel - XS INFO END" << G4endl;
}
return sigma * waterDensity;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4DNARPWBAExcitationModel::SampleSecondaries(
std::vector<G4DynamicParticle*>* /*fvect*/,
const G4MaterialCutsCouple* /*couple*/,
const G4DynamicParticle* aDynamicParticle, G4double, G4double)
{
if(verboseLevel > 3)
{
G4cout << "Calling SampleSecondaries() of G4DNARPWBAExcitationModel"
<< G4endl;
}
G4double k = aDynamicParticle->GetKineticEnergy();
G4int level = RandomSelect(k);
G4double excitationEnergy = waterStructure.ExcitationEnergy(level);
G4double newEnergy = k - excitationEnergy;
if(newEnergy > 0)
{
fParticleChangeForGamma->ProposeMomentumDirection(
aDynamicParticle->GetMomentumDirection());
if(!statCode){
fParticleChangeForGamma->SetProposedKineticEnergy(newEnergy);
}
else{
fParticleChangeForGamma->SetProposedKineticEnergy(k);
}
fParticleChangeForGamma->ProposeLocalEnergyDeposit(excitationEnergy);
}
const G4Track* theIncomingTrack = fParticleChangeForGamma->GetCurrentTrack();
G4DNAChemistryManager::Instance()->CreateWaterMolecule(
eExcitedMolecule, level, theIncomingTrack);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4DNARPWBAExcitationModel::GetPartialCrossSection(
const G4Material*, G4int level, const G4ParticleDefinition* particle,
G4double kineticEnergy)
{
if(fParticleDefinition != particle)
{
G4Exception("G4DNARPWBAExcitationModel::GetPartialCrossSection",
"RPWBAParticleType", FatalException,
"Model initialized for another particle type.");
}
return fTableData->GetComponent(level)->FindValue(kineticEnergy);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4int G4DNARPWBAExcitationModel::RandomSelect(G4double k)
{
G4int level = 0;
G4double* valuesBuffer = new G4double[fTableData->NumberOfComponents()];
const size_t n(fTableData->NumberOfComponents());
size_t i(n);
G4double value = 0.;
while(i > 0)
{
i--;
valuesBuffer[i] = fTableData->GetComponent(i)->FindValue(k);
value += valuesBuffer[i];
}
value *= G4UniformRand();
i = n;
while(i > 0)
{
i--;
if(valuesBuffer[i] > value)
{
delete[] valuesBuffer;
return i;
}
value -= valuesBuffer[i];
}
delete[] valuesBuffer;
return level;
}
@@ -0,0 +1,724 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// Created on 2022/03/03
//
// Authors: A.D. Dominguez-Munoz, M.I. Gallardo, M.C. Bordage,
// Z. Francis, S. Incerti, M.A. Cortes-Giraldo
//
// Contact: M.A. Cortes-Giraldo (miancortes -at- us.es)
//
//
#include "G4DNARPWBAIonisationModel.hh"
#include "G4PhysicalConstants.hh"
#include "G4SystemOfUnits.hh"
#include "G4UAtomicDeexcitation.hh"
#include "G4LossTableManager.hh"
#include "G4DNAChemistryManager.hh"
#include "G4DNAMolecularMaterial.hh"
#include "G4DNABornAngle.hh"
#include "G4Exp.hh"
using namespace std;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4DNARPWBAIonisationModel::G4DNARPWBAIonisationModel(
const G4ParticleDefinition*, const G4String& nam)
: G4VEmModel(nam)
{
// Verbosity scale:
// 0 = nothing
// 1 = warning for energy non-conservation
// 2 = details of energy budget
// 3 = calculation of cross sections, file openings, sampling of atoms
// 4 = entering in methods
if(verboseLevel > 0)
{
G4cout << "RPWBA ionisation model is constructed " << G4endl;
}
SetDeexcitationFlag(true);
SetAngularDistribution(new G4DNABornAngle());
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4DNARPWBAIonisationModel::~G4DNARPWBAIonisationModel()
{
eVecm.clear();
pVecm.clear();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4bool G4DNARPWBAIonisationModel::InEnergyLimit(const G4double& k)
{
if(lowEnergyLimit == highEnergyLimit)
{
G4Exception("G4DNARPWBAIonisationModel::InEnergyLimit", "em0102",
FatalException, "lowEnergyLimit == highEnergyLimit");
}
if(k >= lowEnergyLimit && k <= highEnergyLimit)
{
return true;
}
else
{
return false;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4DNARPWBAIonisationModel::InitialiseForProton(
const G4ParticleDefinition* part)
{
if(part != fProtonDef)
{
G4Exception("G4DNARPWBAIonisationModel::CrossSectionPerVolume", "em0002",
FatalException, "Model not applicable to particle type.");
}
// Energy limits
G4String fileProton("dna/sigma_ionisation_p_RPWBA");
G4double scaleFactor = 1 * cm * cm;
const char *path = G4FindDataDir("G4LEDATA");
lowEnergyLimit = 100. * MeV;
highEnergyLimit = 300. * MeV;
fpTotalCrossSection = make_unique<G4DNACrossSectionDataSet>(
new G4LogLogInterpolation, eV, scaleFactor);
fpTotalCrossSection->LoadData(fileProton);
// Final state
std::ostringstream pFullFileName;
fasterCode ? pFullFileName
<< path << "/dna/sigmadiff_cumulated_ionisation_p_RPWBA.dat.dat"
: pFullFileName << path << "/dna/sigmadiff_ionisation_p_RPWBA.dat";
std::ifstream pDiffCrossSection(pFullFileName.str().c_str());
if(!pDiffCrossSection)
{
G4ExceptionDescription exceptionDescription;
exceptionDescription << "Missing data file: " + pFullFileName.str();
G4Exception("G4DNARPWBAIonisationModel::Initialise", "em0003",
FatalException, exceptionDescription);
}
pTdummyVec.push_back(0.);
while(!pDiffCrossSection.eof())
{
G4double tDummy;
G4double eDummy;
pDiffCrossSection >> tDummy >> eDummy;
if(tDummy != pTdummyVec.back())
{
pTdummyVec.push_back(tDummy);
}
for(G4int j = 0; j < 5; j++)
{
pDiffCrossSection >> pDiffCrossSectionData[j][tDummy][eDummy];
if(fasterCode)
{
pNrjTransfData[j][tDummy][pDiffCrossSectionData[j][tDummy][eDummy]] =
eDummy;
pProbaShellMap[j][tDummy].push_back(
pDiffCrossSectionData[j][tDummy][eDummy]);
}
// SI - only if eof is not reached !
if(!pDiffCrossSection.eof() && !fasterCode)
{
pDiffCrossSectionData[j][tDummy][eDummy] *= scaleFactor;
}
if(!fasterCode)
{
pVecm[tDummy].push_back(eDummy);
}
}
}
// be careful about this
// SetLowEnergyLimit(lowEnergyLimit);
// SetHighEnergyLimit(highEnergyLimit);
}
void G4DNARPWBAIonisationModel::Initialise(const G4ParticleDefinition* particle,
const G4DataVector& /*cuts*/)
{
if(isInitialised)
{
return;
}
if(verboseLevel > 3)
{
G4cout << "Calling G4DNARPWBAIonisationModel::Initialise()"
<< particle->GetParticleName() << G4endl;
}
InitialiseForProton(particle);
if(verboseLevel > 0)
{
G4cout << "RPWBA ionisation model is initialized " << G4endl
<< "Energy range: " << LowEnergyLimit() / eV << " eV - "
<< HighEnergyLimit() / keV << " keV for "
<< particle->GetParticleName() << G4endl;
}
// Initialize water density pointer
if(G4Material::GetMaterial("G4_WATER") != nullptr)
{
fpMolWaterDensity =
G4DNAMolecularMaterial::Instance()->GetNumMolPerVolTableFor(
G4Material::GetMaterial("G4_WATER"));
}
else
{
G4ExceptionDescription exceptionDescription;
exceptionDescription << "G4_WATER does not exist :";
G4Exception("G4DNARPWBAIonisationModel::Initialise", "em00020",
FatalException, exceptionDescription);
}
fAtomDeexcitation = G4LossTableManager::Instance()->AtomDeexcitation();
fParticleChangeForGamma = GetParticleChangeForGamma();
isInitialised = true;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4DNARPWBAIonisationModel::CrossSectionPerVolume(
const G4Material* material, const G4ParticleDefinition* particleDefinition,
G4double ekin, G4double, G4double)
{
if(particleDefinition != fProtonDef)
{
G4Exception("G4DNARPWBAIonisationModel::CrossSectionPerVolume", "em0402",
FatalException, "Model not applicable to particle type.");
}
if(verboseLevel > 3)
{
G4cout << "Calling CrossSectionPerVolume() of G4DNARPWBAIonisationModel"
<< G4endl;
}
G4double sigma;
G4double waterDensity = (*fpMolWaterDensity)[material->GetIndex()];
if(InEnergyLimit(ekin))
{
sigma = fpTotalCrossSection->FindValue(ekin);
}
else
{
// nput energy is outside this interval the cross section is set to zero
// should add a warning or exception ?
return 0;
}
if(verboseLevel > 2)
{
G4cout << "__________________________________" << G4endl;
G4cout << "G4DNARPWBAIonisationModel - XS INFO START" << G4endl;
G4cout << "Kinetic energy(eV)=" << ekin / eV
<< " particle : " << fProtonDef->GetParticleName() << G4endl;
G4cout << "Cross section per water molecule (cm^2)=" << sigma / cm / cm
<< G4endl;
G4cout << "Cross section per water molecule (cm^-1)="
<< sigma * waterDensity / (1. / cm) << G4endl;
G4cout << "G4DNARPWBAIonisationModel - XS INFO END" << G4endl;
}
return sigma * waterDensity;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4DNARPWBAIonisationModel::SampleSecondaries(
std::vector<G4DynamicParticle*>* fvect, const G4MaterialCutsCouple* couple,
const G4DynamicParticle* particle, G4double, G4double)
{
if(verboseLevel > 3)
{
G4cout << "Calling SampleSecondaries() of G4DNARPWBAIonisationModel"
<< G4endl;
}
G4double k = particle->GetKineticEnergy();
if(InEnergyLimit(k))
{
G4ParticleMomentum primaryDirection = particle->GetMomentumDirection();
G4double particleMass = particle->GetDefinition()->GetPDGMass();
G4double totalEnergy = k + particleMass;
G4double pSquare = k * (totalEnergy + particleMass);
G4double totalMomentum = std::sqrt(pSquare);
G4int ionizationShell;
if(!fasterCode)
{
ionizationShell = RandomSelect(k);
}
else
{
// fasterCode = true
do
{
ionizationShell = RandomSelect(k);
} while(k < 19 * eV && ionizationShell == 2 &&
particle->GetDefinition() == G4Electron::ElectronDefinition());
}
G4double bindingEnergy = 0;
bindingEnergy = waterStructure.IonisationEnergy(ionizationShell);
// SI: additional protection if tcs interpolation method is modified
if(k < bindingEnergy)
{
return;
}
//
G4double secondaryKinetic;
if(!fasterCode)
{
secondaryKinetic = RandomizeEjectedElectronEnergy(k, ionizationShell);
}
else
{
secondaryKinetic =
RandomizeEjectedElectronEnergyFromCumulatedDcs(k, ionizationShell);
}
G4int Z = 8; // water Z (6 Oxygen + 2 hydrogen)
G4ThreeVector deltaDirection =
GetAngularDistribution()->SampleDirectionForShell(
particle, secondaryKinetic, Z, ionizationShell, couple->GetMaterial());
if(secondaryKinetic > 0){
auto dp = new G4DynamicParticle(G4Electron::Electron(), deltaDirection,
secondaryKinetic);
fvect->push_back(dp);
}
if(particle->GetDefinition() == G4Electron::ElectronDefinition()){
G4double deltaTotalMomentum = std::sqrt(
secondaryKinetic * (secondaryKinetic + 2. * electron_mass_c2));
G4double finalPx = totalMomentum * primaryDirection.x() -
deltaTotalMomentum * deltaDirection.x();
G4double finalPy = totalMomentum * primaryDirection.y() -
deltaTotalMomentum * deltaDirection.y();
G4double finalPz = totalMomentum * primaryDirection.z() -
deltaTotalMomentum * deltaDirection.z();
G4double finalMomentum =
std::sqrt(finalPx * finalPx + finalPy * finalPy + finalPz * finalPz);
finalPx /= finalMomentum;
finalPy /= finalMomentum;
finalPz /= finalMomentum;
G4ThreeVector direction;
direction.set(finalPx, finalPy, finalPz);
fParticleChangeForGamma->ProposeMomentumDirection(direction.unit());
}
else
{
fParticleChangeForGamma->ProposeMomentumDirection(primaryDirection);
}
// AM: sample deexcitation
// here we assume that H_{2}O electronic levels are the same as Oxygen.
// this can be considered true with a rough 10% error in energy on K-shell,
size_t secNumberInit; // need to know at a certain point the energy of
// secondaries
size_t
secNumberFinal; // So I'll make the diference and then sum the energies
G4double scatteredEnergy = k - bindingEnergy - secondaryKinetic;
// SI: only atomic deexcitation from K shell is considered
if((fAtomDeexcitation != nullptr) && ionizationShell == 4)
{
const G4AtomicShell* shell =
fAtomDeexcitation->GetAtomicShell(Z, G4AtomicShellEnumerator(0));
secNumberInit = fvect->size();
fAtomDeexcitation->GenerateParticles(fvect, shell, Z, 0, 0);
secNumberFinal = fvect->size();
if(secNumberFinal > secNumberInit){
for(size_t i = secNumberInit; i < secNumberFinal; ++i){
if(bindingEnergy >= ((*fvect)[i])->GetKineticEnergy())
{
bindingEnergy -= ((*fvect)[i])->GetKineticEnergy();
}else{
delete(*fvect)[i];
(*fvect)[i] = nullptr;
}
}
}
}
// This should never happen
if(bindingEnergy < 0.0)
{
G4Exception("G4DNARPWBAIonisatioModel::SampleSecondaries()", "em2050",
FatalException, "Negative local energy deposit");
}
// bindingEnergy has been decreased
// by the amount of energy taken away by deexc. products
if(!statCode){
fParticleChangeForGamma->SetProposedKineticEnergy(scatteredEnergy);
fParticleChangeForGamma->ProposeLocalEnergyDeposit(bindingEnergy);
}else{
fParticleChangeForGamma->SetProposedKineticEnergy(k);
fParticleChangeForGamma->ProposeLocalEnergyDeposit(k - scatteredEnergy);
}
const G4Track* theIncomingTrack =
fParticleChangeForGamma->GetCurrentTrack();
G4DNAChemistryManager::Instance()->CreateWaterMolecule(
eIonizedMolecule, ionizationShell, theIncomingTrack);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4DNARPWBAIonisationModel::RandomizeEjectedElectronEnergy(
const G4double& k, const G4int& shell)
{
G4double maximumKineticEnergyTransfer =
4. * (electron_mass_c2 / proton_mass_c2) * k;
G4double crossSectionMaximum = 0.;
for(G4double value = waterStructure.IonisationEnergy(shell);
value <= 4. * waterStructure.IonisationEnergy(shell); value += 0.1 * eV)
{
G4double differentialCrossSection =
DifferentialCrossSection(k / eV, value / eV, shell);
if(differentialCrossSection >= crossSectionMaximum)
{
crossSectionMaximum = differentialCrossSection;
}
}
G4double secondaryElectronKineticEnergy = 0.;
do
{
secondaryElectronKineticEnergy =
G4UniformRand() * maximumKineticEnergyTransfer;
} while(G4UniformRand() * crossSectionMaximum >=
DifferentialCrossSection(k / eV,
(secondaryElectronKineticEnergy +
waterStructure.IonisationEnergy(shell)) /
eV,
shell));
return secondaryElectronKineticEnergy;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4DNARPWBAIonisationModel::DifferentialCrossSection(
const G4double& kine, const G4double& energyTransfer,
const G4int& ionizationLevelIndex)
{
G4double k = kine;
G4double sigma = 0.;
if(energyTransfer >=
waterStructure.IonisationEnergy(ionizationLevelIndex) / eV)
{
G4double valueT1 = 0;
G4double valueT2 = 0;
G4double valueE21 = 0;
G4double valueE22 = 0;
G4double valueE12 = 0;
G4double valueE11 = 0;
G4double xs11 = 0;
G4double xs12 = 0;
G4double xs21 = 0;
G4double xs22 = 0;
// Protection against out of boundary access - proton case : 100 MeV
if(k == pTdummyVec.back())
{
k = k * (1. - 1e-12);
}
// k should be in eV and energy transfer eV also
auto t2 = std::upper_bound(pTdummyVec.begin(), pTdummyVec.end(), k);
auto t1 = t2 - 1;
auto e12 = std::upper_bound(pVecm[(*t1)].begin(), pVecm[(*t1)].end(),
energyTransfer);
auto e11 = e12 - 1;
auto e22 = std::upper_bound(pVecm[(*t2)].begin(), pVecm[(*t2)].end(),
energyTransfer);
auto e21 = e22 - 1;
valueT1 = *t1;
valueT2 = *t2;
valueE21 = *e21;
valueE22 = *e22;
valueE12 = *e12;
valueE11 = *e11;
xs11 = pDiffCrossSectionData[ionizationLevelIndex][valueT1][valueE11];
xs12 = pDiffCrossSectionData[ionizationLevelIndex][valueT1][valueE12];
xs21 = pDiffCrossSectionData[ionizationLevelIndex][valueT2][valueE21];
xs22 = pDiffCrossSectionData[ionizationLevelIndex][valueT2][valueE22];
G4double xsProduct = xs11 * xs12 * xs21 * xs22;
if(xsProduct != 0.)
{
sigma =
QuadInterpolator(valueE11, valueE12, valueE21, valueE22, xs11, xs12,
xs21, xs22, valueT1, valueT2, k, energyTransfer);
}
}
return sigma;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4DNARPWBAIonisationModel::Interpolate(const G4double& e1,
const G4double& e2,
const G4double& e,
const G4double& xs1,
const G4double& xs2)
{
G4double value = 0.;
// Log-log interpolation by default
if(e1 != 0 && e2 != 0 && (std::log10(e2) - std::log10(e1)) != 0 &&
!fasterCode)
{
G4double a =
(std::log10(xs2) - std::log10(xs1)) / (std::log10(e2) - std::log10(e1));
G4double b = std::log10(xs2) - a * std::log10(e2);
G4double sigma = a * std::log10(e) + b;
value = (std::pow(10., sigma));
}
// Switch to lin-lin interpolation
/*
if ((e2-e1)!=0)
{
G4double d1 = xs1;
G4double d2 = xs2;
value = (d1 + (d2 - d1)*(e - e1)/ (e2 - e1));
}
*/
// Switch to log-lin interpolation for faster code
if((e2 - e1) != 0 && xs1 != 0 && xs2 != 0 && fasterCode)
{
G4double d1 = std::log10(xs1);
G4double d2 = std::log10(xs2);
value = std::pow(10., (d1 + (d2 - d1) * (e - e1) / (e2 - e1)));
}
// Switch to lin-lin interpolation for faster code
// in case one of xs1 or xs2 (=cum proba) value is zero
if((e2 - e1) != 0 && (xs1 == 0 || xs2 == 0) && fasterCode)
{
G4double d1 = xs1;
G4double d2 = xs2;
value = (d1 + (d2 - d1) * (e - e1) / (e2 - e1));
}
return value;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4DNARPWBAIonisationModel::QuadInterpolator(
const G4double& e11, const G4double& e12, const G4double& e21,
const G4double& e22, const G4double& xs11, const G4double& xs12,
const G4double& xs21, const G4double& xs22, const G4double& t1,
const G4double& t2, const G4double& t, const G4double& e)
{
G4double interpolatedvalue1 = Interpolate(e11, e12, e, xs11, xs12);
G4double interpolatedvalue2 = Interpolate(e21, e22, e, xs21, xs22);
G4double value =
Interpolate(t1, t2, t, interpolatedvalue1, interpolatedvalue2);
return value;
}
G4double G4DNARPWBAIonisationModel::GetPartialCrossSection(
const G4Material* /*material*/, G4int level,
const G4ParticleDefinition* particle, G4double kineticEnergy)
{
if(fpTotalCrossSection != nullptr && particle != fProtonDef)
{
G4Exception("G4DNARPWBAIonisationModel::GetPartialCrossSection", "em0010",
FatalException, "Model not applicable to particle type.");
}
return fpTotalCrossSection->GetComponent(level)->FindValue(kineticEnergy);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4int G4DNARPWBAIonisationModel::RandomSelect(G4double k)
{
if(fpTotalCrossSection == nullptr)
{
G4Exception("G4DNARPWBAIonisationModel::RandomSelect", "em0010",
FatalException, "Model not applicable to particle type.");
}
else
{
auto valuesBuffer = new G4double[fpTotalCrossSection->NumberOfComponents()];
const size_t n(fpTotalCrossSection->NumberOfComponents());
size_t i(n);
G4double value = 0.;
while(i > 0)
{
i--;
valuesBuffer[i] = fpTotalCrossSection->GetComponent(i)->FindValue(k);
value += valuesBuffer[i];
}
value *= G4UniformRand();
i = n;
while(i > 0)
{
i--;
if(valuesBuffer[i] > value)
{
delete[] valuesBuffer;
return i;
}
value -= valuesBuffer[i];
}
delete[] valuesBuffer;
}
return 0;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double
G4DNARPWBAIonisationModel::RandomizeEjectedElectronEnergyFromCumulatedDcs(
const G4double& k, const G4int& shell)
{
G4double secondaryElectronKineticEnergy = 0.;
G4double random = G4UniformRand();
secondaryElectronKineticEnergy =
TransferedEnergy(k / eV, shell, random) * eV -
waterStructure.IonisationEnergy(shell);
if(secondaryElectronKineticEnergy < 0.)
{
return 0.;
}
return secondaryElectronKineticEnergy;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4DNARPWBAIonisationModel::TransferedEnergy(G4double k,
G4int ionizationLevelIndex,
const G4double& random)
{
G4double nrj = 0.;
G4double valueK1 = 0;
G4double valueK2 = 0;
G4double valuePROB21 = 0;
G4double valuePROB22 = 0;
G4double valuePROB12 = 0;
G4double valuePROB11 = 0;
G4double nrjTransf11 = 0;
G4double nrjTransf12 = 0;
G4double nrjTransf21 = 0;
G4double nrjTransf22 = 0;
// Protection against out of boundary access - proton case : 100 MeV
if(k == pTdummyVec.back())
{
k = k * (1. - 1e-12);
}
// k should be in eV
auto k2 = std::upper_bound(pTdummyVec.begin(), pTdummyVec.end(), k);
auto k1 = k2 - 1;
// SI : the following condition avoids situations where random > last vector
// element,
// for eg. when the last element is zero
if(random <= pProbaShellMap[ionizationLevelIndex][(*k1)].back() &&
random <= pProbaShellMap[ionizationLevelIndex][(*k2)].back())
{
auto prob12 = std::upper_bound(
pProbaShellMap[ionizationLevelIndex][(*k1)].begin(),
pProbaShellMap[ionizationLevelIndex][(*k1)].end(), random);
auto prob11 = prob12 - 1;
auto prob22 = std::upper_bound(
pProbaShellMap[ionizationLevelIndex][(*k2)].begin(),
pProbaShellMap[ionizationLevelIndex][(*k2)].end(), random);
auto prob21 = prob22 - 1;
valueK1 = *k1;
valueK2 = *k2;
valuePROB21 = *prob21;
valuePROB22 = *prob22;
valuePROB12 = *prob12;
valuePROB11 = *prob11;
nrjTransf11 = pNrjTransfData[ionizationLevelIndex][valueK1][valuePROB11];
nrjTransf12 = pNrjTransfData[ionizationLevelIndex][valueK1][valuePROB12];
nrjTransf21 = pNrjTransfData[ionizationLevelIndex][valueK2][valuePROB21];
nrjTransf22 = pNrjTransfData[ionizationLevelIndex][valueK2][valuePROB22];
}
// Avoids cases where cum xs is zero for k1 and is not for k2 (with always
// k1<k2)
if(random > pProbaShellMap[ionizationLevelIndex][(*k1)].back())
{
auto prob22 = std::upper_bound(
pProbaShellMap[ionizationLevelIndex][(*k2)].begin(),
pProbaShellMap[ionizationLevelIndex][(*k2)].end(), random);
auto prob21 = prob22 - 1;
valueK1 = *k1;
valueK2 = *k2;
valuePROB21 = *prob21;
valuePROB22 = *prob22;
nrjTransf21 = pNrjTransfData[ionizationLevelIndex][valueK2][valuePROB21];
nrjTransf22 = pNrjTransfData[ionizationLevelIndex][valueK2][valuePROB22];
G4double interpolatedvalue2 =
Interpolate(valuePROB21, valuePROB22, random, nrjTransf21, nrjTransf22);
G4double value = Interpolate(valueK1, valueK2, k, 0., interpolatedvalue2);
return value;
}
G4double nrjTransfProduct =
nrjTransf11 * nrjTransf12 * nrjTransf21 * nrjTransf22;
if(nrjTransfProduct != 0.)
{
nrj = QuadInterpolator(valuePROB11, valuePROB12, valuePROB21, valuePROB22,
nrjTransf11, nrjTransf12, nrjTransf21, nrjTransf22,
valueK1, valueK2, k, random);
}
return nrj;
}
@@ -116,7 +116,7 @@ void G4DNARelativisticIonisationModel::Initialise(const G4ParticleDefinition* pa
std::ostringstream eFullFileNameZ;
char *path = getenv("G4LEDATA");
const char *path = G4FindDataDir("G4LEDATA");
if (!path)
{
G4Exception("G4DNARelativisticIonisationModel::Initialise","em0006",
@@ -404,7 +404,7 @@ void G4DNARelativisticIonisationModel::LoadAtomicStates(
const char *datadir = path;
if(!datadir)
{
datadir = getenv("G4LEDATA");
datadir = G4FindDataDir("G4LEDATA");
if(!datadir)
{
G4Exception("G4DNARelativisticIonisationModel::LoadAtomicStates()",
@@ -39,6 +39,12 @@
#include "G4DNARuddAngle.hh"
#include "G4DeltaAngle.hh"
#include "G4Exp.hh"
#include "G4Log.hh"
#include "G4Pow.hh"
#include "G4Alpha.hh"
static G4Pow * gpow = G4Pow::GetInstance();
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -130,9 +136,9 @@ void G4DNARuddIonisationExtendedModel::Initialise(const G4ParticleDefinition* pa
G4String fileAlphaPlusPlus("dna/sigma_ionisation_alphaplusplus_rudd");
G4String fileAlphaPlus("dna/sigma_ionisation_alphaplus_rudd");
G4String fileHelium("dna/sigma_ionisation_he_rudd");
G4String fileLithium("dna/sigma_ionisation_li_rudd");
G4String fileBeryllium("dna/sigma_ionisation_be_rudd");
G4String fileBoron("dna/sigma_ionisation_b_rudd");
//G4String fileLithium("dna/sigma_ionisation_li_rudd");
//G4String fileBeryllium("dna/sigma_ionisation_be_rudd");
//G4String fileBoron("dna/sigma_ionisation_b_rudd");
G4String fileCarbon("dna/sigma_ionisation_c_rudd");
G4String fileNitrogen("dna/sigma_ionisation_n_rudd");
G4String fileOxygen("dna/sigma_ionisation_o_rudd");
@@ -141,35 +147,29 @@ void G4DNARuddIonisationExtendedModel::Initialise(const G4ParticleDefinition* pa
G4DNAGenericIonsManager *instance;
instance = G4DNAGenericIonsManager::Instance();
G4ParticleDefinition* protonDef = G4Proton::ProtonDefinition();
G4ParticleDefinition* hydrogenDef = instance->GetIon("hydrogen");
G4ParticleDefinition* alphaPlusPlusDef = instance->GetIon("alpha++");
G4ParticleDefinition* alphaPlusDef = instance->GetIon("alpha+");
G4ParticleDefinition* heliumDef = instance->GetIon("helium");
protonDef = G4Proton::ProtonDefinition();
hydrogenDef = instance->GetIon("hydrogen");
alphaPlusPlusDef = G4Alpha::Alpha();
alphaPlusDef = instance->GetIon("alpha+");
heliumDef = instance->GetIon("helium");
//G4ParticleDefinition* carbonDef = instance->GetIon("carbon");
//G4ParticleDefinition* nitrogenDef = instance->GetIon("nitrogen");
//G4ParticleDefinition* oxygenDef = instance->GetIon("oxygen");
//G4ParticleDefinition* siliconDef = instance->GetIon("silicon");
//G4ParticleDefinition* ironDef = instance->GetIon("iron");
G4ParticleDefinition* lithiumDef = G4IonTable::GetIonTable()->GetIon(3,7);
G4ParticleDefinition* berylliumDef = G4IonTable::GetIonTable()->GetIon(4,9);
G4ParticleDefinition* boronDef = G4IonTable::GetIonTable()->GetIon(5,11);
G4ParticleDefinition* carbonDef = G4IonTable::GetIonTable()->GetIon(6,12);
G4ParticleDefinition* nitrogenDef = G4IonTable::GetIonTable()->GetIon(7,14);
G4ParticleDefinition* oxygenDef = G4IonTable::GetIonTable()->GetIon(8,16);
G4ParticleDefinition* siliconDef = G4IonTable::GetIonTable()->GetIon(14,28);
G4ParticleDefinition* ironDef = G4IonTable::GetIonTable()->GetIon(26,56);
//
carbonDef = instance->GetIon("carbon");
nitrogenDef = instance->GetIon("nitrogen");
oxygenDef = instance->GetIon("oxygen");
siliconDef = instance->GetIon("silicon");
ironDef = instance->GetIon("iron");
//lithiumDef = G4IonTable::GetIonTable()->GetIon(3,7);
//berylliumDef = G4IonTable::GetIonTable()->GetIon(4,9);
//boronDef = G4IonTable::GetIonTable()->GetIon(5,11);
G4String proton;
G4String hydrogen;
G4String alphaPlusPlus;
G4String alphaPlus;
G4String helium;
G4String lithium;
G4String beryllium;
G4String boron;
//G4String lithium;
//G4String beryllium;
//G4String boron;
G4String carbon;
G4String nitrogen;
G4String oxygen;
@@ -262,7 +262,7 @@ void G4DNARuddIonisationExtendedModel::Initialise(const G4ParticleDefinition* pa
tableData[helium] = tableHelium;
// **********************************************************************************************
/*
lithium = lithiumDef->GetParticleName();
tableFile[lithium] = fileLithium;
@@ -272,7 +272,7 @@ void G4DNARuddIonisationExtendedModel::Initialise(const G4ParticleDefinition* pa
lowEnergyLimit[lithium] = 0.5*7*MeV;
highEnergyLimit[lithium] = 1e6*7*MeV;
//
// Cross section
G4DNACrossSectionDataSet* tableLithium = new G4DNACrossSectionDataSet(new G4LogLogInterpolation,
@@ -280,7 +280,7 @@ void G4DNARuddIonisationExtendedModel::Initialise(const G4ParticleDefinition* pa
scaleFactor );
tableLithium->LoadData(fileLithium);
tableData[lithium] = tableLithium;
// **********************************************************************************************
beryllium = berylliumDef->GetParticleName();
@@ -320,7 +320,7 @@ void G4DNARuddIonisationExtendedModel::Initialise(const G4ParticleDefinition* pa
scaleFactor );
tableBoron->LoadData(fileBoron);
tableData[boron] = tableBoron;
*/
// **********************************************************************************************
carbon = carbonDef->GetParticleName();
@@ -457,7 +457,7 @@ void G4DNARuddIonisationExtendedModel::Initialise(const G4ParticleDefinition* pa
SetLowEnergyLimit(lowEnergyLimit[alphaPlusPlus]);
SetHighEnergyLimit(highEnergyLimit[alphaPlusPlus]);
}
/*
if (particle==lithiumDef)
{
SetLowEnergyLimit(lowEnergyLimit[lithium]);
@@ -475,7 +475,7 @@ void G4DNARuddIonisationExtendedModel::Initialise(const G4ParticleDefinition* pa
SetLowEnergyLimit(lowEnergyLimit[boron]);
SetHighEnergyLimit(highEnergyLimit[boron]);
}
*/
if (particle==carbonDef)
{
SetLowEnergyLimit(lowEnergyLimit[carbon]);
@@ -533,7 +533,7 @@ void G4DNARuddIonisationExtendedModel::Initialise(const G4ParticleDefinition* pa
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4DNARuddIonisationExtendedModel::CrossSectionPerVolume(const G4Material* material,
const G4ParticleDefinition* particleDefinition,
const G4ParticleDefinition* partDef,
G4double k,
G4double,
G4double)
@@ -545,21 +545,20 @@ G4double G4DNARuddIonisationExtendedModel::CrossSectionPerVolume(const G4Materia
if (verboseLevel > 3)
G4cout << "Calling CrossSectionPerVolume() of G4DNARuddIonisationExtendedModel" << G4endl;
auto particleDefinition = GetDNAIonParticleDefinition(partDef);
// Calculate total cross section for model
G4DNAGenericIonsManager *instance;
instance = G4DNAGenericIonsManager::Instance();
if (
particleDefinition != G4Proton::ProtonDefinition()
particleDefinition != protonDef
&&
particleDefinition != instance->GetIon("hydrogen")
particleDefinition != hydrogenDef
&&
particleDefinition != instance->GetIon("alpha++")
particleDefinition != alphaPlusPlusDef
&&
particleDefinition != instance->GetIon("alpha+")
particleDefinition != alphaPlusDef
&&
particleDefinition != instance->GetIon("helium")
particleDefinition != heliumDef
&&
// SI
//particleDefinition != instance->GetIon("carbon")
@@ -569,21 +568,23 @@ G4double G4DNARuddIonisationExtendedModel::CrossSectionPerVolume(const G4Materia
//particleDefinition != instance->GetIon("oxygen")
//&&
//particleDefinition != instance->GetIon("iron")
particleDefinition != G4IonTable::GetIonTable()->GetIon(3,7)
/*
particleDefinition != lithiumDef
&&
particleDefinition != G4IonTable::GetIonTable()->GetIon(4,9)
particleDefinition != berylliumDef
&&
particleDefinition != G4IonTable::GetIonTable()->GetIon(5,11)
particleDefinition != boronDef
&&
particleDefinition != G4IonTable::GetIonTable()->GetIon(6,12)
*/
particleDefinition != carbonDef
&&
particleDefinition != G4IonTable::GetIonTable()->GetIon(7,14)
particleDefinition != nitrogenDef
&&
particleDefinition != G4IonTable::GetIonTable()->GetIon(8,16)
particleDefinition != oxygenDef
&&
particleDefinition != G4IonTable::GetIonTable()->GetIon(14,28)
particleDefinition != siliconDef
&&
particleDefinition != G4IonTable::GetIonTable()->GetIon(26,56)
particleDefinition != ironDef
//
)
@@ -591,15 +592,15 @@ G4double G4DNARuddIonisationExtendedModel::CrossSectionPerVolume(const G4Materia
G4double lowLim = 0;
if ( particleDefinition == G4Proton::ProtonDefinition()
|| particleDefinition == instance->GetIon("hydrogen")
if ( particleDefinition == protonDef
|| particleDefinition == hydrogenDef
)
lowLim = lowEnergyLimitOfModelForA[1];
else if ( particleDefinition == instance->GetIon("alpha++")
|| particleDefinition == instance->GetIon("alpha+")
|| particleDefinition == instance->GetIon("helium")
else if ( particleDefinition == alphaPlusPlusDef
|| particleDefinition == alphaPlusDef
|| particleDefinition == heliumDef
)
lowLim = lowEnergyLimitOfModelForA[4];
@@ -682,29 +683,30 @@ void G4DNARuddIonisationExtendedModel::SampleSecondaries(std::vector<G4DynamicPa
if (verboseLevel > 3)
G4cout << "Calling SampleSecondaries() of G4DNARuddIonisationExtendedModel" << G4endl;
auto particleDefinition = GetDNAIonParticleDefinition(particle->GetDefinition());
G4double lowLim = 0;
G4double highLim = 0;
// ZF: the following line summarizes the commented part
if(particle->GetDefinition()->GetAtomicMass() <= 4) lowLim = killBelowEnergyForA[particle->GetDefinition()->GetAtomicMass()];
if(particle->GetDefinition()->GetAtomicMass() <= 4) lowLim = killBelowEnergyForA[particleDefinition->GetAtomicMass()];
else lowLim = killBelowEnergyForA[5]*particle->GetDefinition()->GetAtomicMass();
else lowLim = killBelowEnergyForA[5]*particleDefinition->GetAtomicMass();
/*
if(particle->GetDefinition()->GetAtomicMass() >= 5) lowLim = killBelowEnergyForA[5]*particle->GetDefinition()->GetAtomicMass();
if ( particle->GetDefinition() == G4Proton::ProtonDefinition()
|| particle->GetDefinition() == instance->GetIon("hydrogen")
if ( particle->GetDefinition() == protonDef
|| particle->GetDefinition() == hydrogenDef
)
lowLim = killBelowEnergyForA[1];
if ( particle->GetDefinition() == instance->GetIon("alpha++")
|| particle->GetDefinition() == instance->GetIon("alpha+")
|| particle->GetDefinition() == instance->GetIon("helium")
if ( particle->GetDefinition() == alphaPlusPlusDef
|| particle->GetDefinition() == alphaPlusDef
|| particle->GetDefinition() == heliumDef
)
lowLim = killBelowEnergyForA[4];
@@ -714,7 +716,7 @@ void G4DNARuddIonisationExtendedModel::SampleSecondaries(std::vector<G4DynamicPa
G4double k = particle->GetKineticEnergy();
const G4String& particleName = particle->GetDefinition()->GetParticleName();
const G4String& particleName = particleDefinition->GetParticleName();
// SI - the following is useless since lowLim is already defined
/*
@@ -736,7 +738,7 @@ void G4DNARuddIonisationExtendedModel::SampleSecondaries(std::vector<G4DynamicPa
// SI: no strict limits, like in the non extended version of the model
{
G4ParticleDefinition* definition = particle->GetDefinition();
G4ParticleDefinition* definition = particleDefinition;
G4ParticleMomentum primaryDirection = particle->GetMomentumDirection();
/*
G4double particleMass = definition->GetPDGMass();
@@ -987,8 +989,7 @@ G4double G4DNARuddIonisationExtendedModel::RejectionFunction(G4ParticleDefinitio
G4double energyTransfer = proposed_ws + Bj_energy;
proposed_ws/=Bj_energy;
G4DNAGenericIonsManager *instance;
instance = G4DNAGenericIonsManager::Instance();
G4double tau = 0.;
G4double A_ion = 0.;
tau = (electron_mass_c2 / particleDefinition->GetPDGMass()) * k;
@@ -1017,8 +1018,8 @@ G4double G4DNARuddIonisationExtendedModel::RejectionFunction(G4ParticleDefinitio
G4bool isHelium = false;
if ( particleDefinition == G4Proton::ProtonDefinition()
|| particleDefinition == instance->GetIon("hydrogen")
if ( particleDefinition == protonDef
|| particleDefinition == hydrogenDef
)
{
return(rejection_term);
@@ -1028,12 +1029,12 @@ G4double G4DNARuddIonisationExtendedModel::RejectionFunction(G4ParticleDefinitio
{
G4double Z = particleDefinition->GetAtomicNumber();
G4double x = 100.*std::sqrt(beta2)/std::pow(Z,(2./3.));
G4double x = 100.*std::sqrt(beta2)/gpow->powA(Z,(2./3.));
G4double Zeffion = Z*(1.-G4Exp(-1.316*x+0.112*x*x-0.0650*x*x*x));
rejection_term*=Zeffion*Zeffion;
}
else if (particleDefinition == instance->GetIon("alpha++") )
else if (particleDefinition == alphaPlusPlusDef )
{
isHelium = true;
slaterEffectiveCharge[0]=0.;
@@ -1044,7 +1045,7 @@ G4double G4DNARuddIonisationExtendedModel::RejectionFunction(G4ParticleDefinitio
sCoefficient[2]=0.;
}
else if (particleDefinition == instance->GetIon("alpha+") )
else if (particleDefinition == alphaPlusDef )
{
isHelium = true;
slaterEffectiveCharge[0]=2.0;
@@ -1057,7 +1058,7 @@ G4double G4DNARuddIonisationExtendedModel::RejectionFunction(G4ParticleDefinitio
sCoefficient[2]=0.15;
}
else if (particleDefinition == instance->GetIon("helium") )
else if (particleDefinition == heliumDef )
{
isHelium = true;
slaterEffectiveCharge[0]=1.7;
@@ -1068,9 +1069,9 @@ G4double G4DNARuddIonisationExtendedModel::RejectionFunction(G4ParticleDefinitio
sCoefficient[2]=0.25;
}
// if ( particleDefinition == instance->GetIon("helium")
// || particleDefinition == instance->GetIon("alpha+")
// || particleDefinition == instance->GetIon("alpha++")
// if ( particleDefinition == heliumDef
// || particleDefinition == alphaPlusDef
// || particleDefinition == alphaPlusPlusDef
// )
if (isHelium)
@@ -1167,9 +1168,9 @@ G4double G4DNARuddIonisationExtendedModel::ProposedSampledEnergy(G4ParticleDefin
G4double v = std::sqrt(v2);
//G4double wc = 4.*v2 - 2.*v - (Ry/(4.*Bj_energy));
G4double L1 = (C1* std::pow(v,(D1))) / (1.+ E1*std::pow(v, (D1+4.)));
G4double L2 = C2*std::pow(v,(D2));
G4double H1 = (A1*std::log(1.+v2)) / (v2+(B1/v2));
G4double L1 = (C1* gpow->powA(v,(D1))) / (1.+ E1*gpow->powA(v, (D1+4.)));
G4double L2 = C2*gpow->powA(v,(D2));
G4double H1 = (A1*G4Log(1.+v2)) / (v2+(B1/v2));
G4double H2 = (A2/v2) + (B2/(v2*v2));
G4double F1 = L1+H1;
G4double F2 = (L2*H2)/(L2+H2);
@@ -1280,12 +1281,10 @@ G4double G4DNARuddIonisationExtendedModel::R(G4double t,
G4double G4DNARuddIonisationExtendedModel::CorrectionFactor(G4ParticleDefinition* particleDefinition, G4double k, G4int shell)
{
// ZF Shortened
G4DNAGenericIonsManager *instance;
instance = G4DNAGenericIonsManager::Instance();
if (particleDefinition == instance->GetIon("hydrogen") && shell < 4)
if (particleDefinition == hydrogenDef && shell < 4)
{
G4double value = (std::log10(k/eV)-4.2)/0.5;
G4double value = ((G4Log(k/eV)/gpow->logZ(10))-4.2)/0.5;
// The following values are provided by M. Dingfelder (priv. comm)
return((0.6/(1+G4Exp(value))) + 0.9);
}
@@ -1416,3 +1415,34 @@ G4double G4DNARuddIonisationExtendedModel::Sum(G4double /* energy */, const G4St
return 0;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4ParticleDefinition* G4DNARuddIonisationExtendedModel::GetDNAIonParticleDefinition(const G4ParticleDefinition* particleDefinition)
{
//for proton, hydrogen, alphas
if(particleDefinition->GetAtomicMass() <= 4)
{
return const_cast<G4ParticleDefinition*>(particleDefinition);
}
else{
auto instance = G4DNAGenericIonsManager::Instance();
auto PDGEncoding = particleDefinition->GetPDGEncoding();
if(PDGEncoding == 1000140280){
return instance->GetIon("silicon");
}else if(PDGEncoding == 1000260560){
return instance->GetIon("iron");
}else if(PDGEncoding == 1000080160){
return instance->GetIon("oxygen");
}else if(PDGEncoding == 1000070140){
return instance->GetIon("nitrogen");
}else if(PDGEncoding == 1000060120){
return instance->GetIon("carbon");
}
G4ExceptionDescription description;
description << "DNA physics does not support this ion : "<<particleDefinition->GetParticleName()<< G4endl;
G4Exception("G4DNARuddIonisationExtendedModel::GetDNAIonParticleDefinition()",
"em2051",FatalException,description);
return nullptr;
}
}
@@ -35,7 +35,11 @@
#include "G4DNARuddAngle.hh"
#include "G4DeltaAngle.hh"
#include "G4Exp.hh"
#include "G4Pow.hh"
#include "G4Log.hh"
#include "G4Alpha.hh"
static G4Pow * gpow = G4Pow::GetInstance();
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
using namespace std;
@@ -128,11 +132,11 @@ void G4DNARuddIonisationModel::Initialise(const G4ParticleDefinition* particle,
G4DNAGenericIonsManager *instance;
instance = G4DNAGenericIonsManager::Instance();
G4ParticleDefinition* protonDef = G4Proton::ProtonDefinition();
G4ParticleDefinition* hydrogenDef = instance->GetIon("hydrogen");
G4ParticleDefinition* alphaPlusPlusDef = instance->GetIon("alpha++");
G4ParticleDefinition* alphaPlusDef = instance->GetIon("alpha+");
G4ParticleDefinition* heliumDef = instance->GetIon("helium");
protonDef = G4Proton::ProtonDefinition();
hydrogenDef = instance->GetIon("hydrogen");
alphaPlusPlusDef = G4Alpha::Alpha();
alphaPlusDef = instance->GetIon("alpha+");
heliumDef = instance->GetIon("helium");
G4String proton;
G4String hydrogen;
@@ -298,34 +302,31 @@ G4double G4DNARuddIonisationModel::CrossSectionPerVolume(const G4Material* mater
// Calculate total cross section for model
G4DNAGenericIonsManager *instance;
instance = G4DNAGenericIonsManager::Instance();
if (
particleDefinition != G4Proton::ProtonDefinition()
particleDefinition != protonDef
&&
particleDefinition != instance->GetIon("hydrogen")
particleDefinition != hydrogenDef
&&
particleDefinition != instance->GetIon("alpha++")
particleDefinition != alphaPlusPlusDef
&&
particleDefinition != instance->GetIon("alpha+")
particleDefinition != alphaPlusDef
&&
particleDefinition != instance->GetIon("helium")
particleDefinition != heliumDef
)
return 0;
G4double lowLim = 0;
if ( particleDefinition == G4Proton::ProtonDefinition()
|| particleDefinition == instance->GetIon("hydrogen")
if ( particleDefinition == protonDef
|| particleDefinition == hydrogenDef
)
lowLim = lowEnergyLimitOfModelForZ1;
if ( particleDefinition == instance->GetIon("alpha++")
|| particleDefinition == instance->GetIon("alpha+")
|| particleDefinition == instance->GetIon("helium")
if ( particleDefinition == alphaPlusPlusDef
|| particleDefinition == alphaPlusDef
|| particleDefinition == heliumDef
)
lowLim = lowEnergyLimitOfModelForZ2;
@@ -416,18 +417,15 @@ void G4DNARuddIonisationModel::SampleSecondaries(std::vector<G4DynamicParticle*>
G4double lowLim = 0;
G4double highLim = 0;
G4DNAGenericIonsManager *instance;
instance = G4DNAGenericIonsManager::Instance();
if ( particle->GetDefinition() == G4Proton::ProtonDefinition()
|| particle->GetDefinition() == instance->GetIon("hydrogen")
if ( particle->GetDefinition() == protonDef
|| particle->GetDefinition() == hydrogenDef
)
lowLim = killBelowEnergyForZ1;
if ( particle->GetDefinition() == instance->GetIon("alpha++")
|| particle->GetDefinition() == instance->GetIon("alpha+")
|| particle->GetDefinition() == instance->GetIon("helium")
if ( particle->GetDefinition() == alphaPlusPlusDef
|| particle->GetDefinition() == alphaPlusDef
|| particle->GetDefinition() == heliumDef
)
lowLim = killBelowEnergyForZ2;
@@ -605,18 +603,15 @@ G4double G4DNARuddIonisationModel::RandomizeEjectedElectronEnergy(G4ParticleDefi
{
G4double maximumKineticEnergyTransfer = 0.;
G4DNAGenericIonsManager *instance;
instance = G4DNAGenericIonsManager::Instance();
if (particleDefinition == G4Proton::ProtonDefinition()
|| particleDefinition == instance->GetIon("hydrogen"))
if (particleDefinition == protonDef
|| particleDefinition == hydrogenDef)
{
maximumKineticEnergyTransfer = 4. * (electron_mass_c2 / proton_mass_c2) * k;
}
else if (particleDefinition == instance->GetIon("helium")
|| particleDefinition == instance->GetIon("alpha+")
|| particleDefinition == instance->GetIon("alpha++"))
else if (particleDefinition == heliumDef
|| particleDefinition == alphaPlusDef
|| particleDefinition == alphaPlusPlusDef)
{
maximumKineticEnergyTransfer = 4. * (0.511 / 3728) * k;
}
@@ -663,15 +658,15 @@ G4double G4DNARuddIonisationModel::RandomizeEjectedElectronEnergy(G4ParticleDefi
G4double maxSecKinetic = 0.;
if (particleDefinition == G4Proton::ProtonDefinition()
|| particleDefinition == instance->GetIon("hydrogen"))
if (particleDefinition == protonDef
|| particleDefinition == hydrogenDef)
{
maxSecKinetic = 4.* (electron_mass_c2 / proton_mass_c2) * k;
}
else if (particleDefinition == instance->GetIon("helium")
|| particleDefinition == instance->GetIon("alpha+")
|| particleDefinition == instance->GetIon("alpha++"))
else if (particleDefinition == heliumDef
|| particleDefinition == alphaPlusDef
|| particleDefinition == alphaPlusPlusDef)
{
maxSecKinetic = 4.* (0.511 / 3728) * k;
}
@@ -760,9 +755,6 @@ G4double G4DNARuddIonisationModel::DifferentialCrossSection(G4ParticleDefinition
const G4double n = 2.;
const G4double Gj[5] = { 0.99, 1.11, 1.11, 0.52, 1. };
G4DNAGenericIonsManager* instance;
instance = G4DNAGenericIonsManager::Instance();
G4double wBig = (energyTransfer
- waterStructure.IonisationEnergy(ionizationLevelIndex));
if (wBig < 0)
@@ -780,26 +772,26 @@ G4double G4DNARuddIonisationModel::DifferentialCrossSection(G4ParticleDefinition
G4bool isProtonOrHydrogen = false;
G4bool isHelium = false;
if (particleDefinition == G4Proton::ProtonDefinition()
|| particleDefinition == instance->GetIon("hydrogen"))
if (particleDefinition == protonDef
|| particleDefinition == hydrogenDef)
{
isProtonOrHydrogen = true;
tau = (electron_mass_c2 / proton_mass_c2) * k;
}
else if (particleDefinition == instance->GetIon("helium")
|| particleDefinition == instance->GetIon("alpha+")
|| particleDefinition == instance->GetIon("alpha++"))
else if (particleDefinition == heliumDef
|| particleDefinition == alphaPlusDef
|| particleDefinition == alphaPlusPlusDef)
{
isHelium = true;
tau = (0.511 / 3728.) * k;
}
G4double S = 4. * pi * Bohr_radius * Bohr_radius * n
* std::pow((Ry / Bj[ionizationLevelIndex]), 2);
* gpow->powN((Ry / Bj[ionizationLevelIndex]), 2);
if (j == 4)
S = 4. * pi * Bohr_radius * Bohr_radius * n
* std::pow((Ry / waterStructure.IonisationEnergy(ionizationLevelIndex)),
* gpow->powN((Ry / waterStructure.IonisationEnergy(ionizationLevelIndex)),
2);
G4double v2 = tau / Bj[ionizationLevelIndex];
@@ -812,9 +804,9 @@ G4double G4DNARuddIonisationModel::DifferentialCrossSection(G4ParticleDefinition
wc = 4. * v2 - 2. * v
- (Ry / (4. * waterStructure.IonisationEnergy(ionizationLevelIndex)));
G4double L1 = (C1 * std::pow(v, (D1))) / (1. + E1 * std::pow(v, (D1 + 4.)));
G4double L2 = C2 * std::pow(v, (D2));
G4double H1 = (A1 * std::log(1. + v2)) / (v2 + (B1 / v2));
G4double L1 = (C1 * gpow->powA(v, (D1))) / (1. + E1 * gpow->powA(v, (D1 + 4.)));
G4double L2 = C2 * gpow->powA(v, (D2));
G4double H1 = (A1 * G4Log(1. + v2)) / (v2 + (B1 / v2));
G4double H2 = (A2 / v2) + (B2 / (v2 * v2));
G4double F1 = L1 + H1;
@@ -824,28 +816,28 @@ G4double G4DNARuddIonisationModel::DifferentialCrossSection(G4ParticleDefinition
CorrectionFactor(particleDefinition, k) * Gj[j]
* (S / Bj[ionizationLevelIndex])
* ((F1 + w * F2)
/ (std::pow((1. + w), 3)
/ (gpow->powN((1. + w), 3)
* (1. + G4Exp(alphaConst * (w - wc) / v))));
if (j == 4)
sigma = CorrectionFactor(particleDefinition, k) * Gj[j]
* (S / waterStructure.IonisationEnergy(ionizationLevelIndex))
* ((F1 + w * F2)
/ (std::pow((1. + w), 3)
/ (gpow->powN((1. + w), 3)
* (1. + G4Exp(alphaConst * (w - wc) / v))));
if ((particleDefinition == instance->GetIon("hydrogen"))
if ((particleDefinition == hydrogenDef)
&& (ionizationLevelIndex == 4))
{
// sigma = Gj[j] * (S/Bj[ionizationLevelIndex])
sigma = Gj[j] * (S / waterStructure.IonisationEnergy(ionizationLevelIndex))
* ((F1 + w * F2)
/ (std::pow((1. + w), 3)
/ (gpow->powN((1. + w), 3)
* (1. + G4Exp(alphaConst * (w - wc) / v))));
}
// if ( particleDefinition == G4Proton::ProtonDefinition()
// || particleDefinition == instance->GetIon("hydrogen")
// if ( particleDefinition == protonDef
// || particleDefinition == hydrogenDef
// )
if (isProtonOrHydrogen)
@@ -853,7 +845,7 @@ G4double G4DNARuddIonisationModel::DifferentialCrossSection(G4ParticleDefinition
return (sigma);
}
if (particleDefinition == instance->GetIon("alpha++"))
if (particleDefinition == alphaPlusPlusDef)
{
slaterEffectiveCharge[0] = 0.;
slaterEffectiveCharge[1] = 0.;
@@ -863,7 +855,7 @@ G4double G4DNARuddIonisationModel::DifferentialCrossSection(G4ParticleDefinition
sCoefficient[2] = 0.;
}
else if (particleDefinition == instance->GetIon("alpha+"))
else if (particleDefinition == alphaPlusDef)
{
slaterEffectiveCharge[0] = 2.0;
// The following values are provided by M. Dingfelder (priv. comm)
@@ -875,7 +867,7 @@ G4double G4DNARuddIonisationModel::DifferentialCrossSection(G4ParticleDefinition
sCoefficient[2] = 0.15;
}
else if (particleDefinition == instance->GetIon("helium"))
else if (particleDefinition == heliumDef)
{
slaterEffectiveCharge[0] = 1.7;
slaterEffectiveCharge[1] = 1.15;
@@ -885,22 +877,22 @@ G4double G4DNARuddIonisationModel::DifferentialCrossSection(G4ParticleDefinition
sCoefficient[2] = 0.25;
}
// if ( particleDefinition == instance->GetIon("helium")
// || particleDefinition == instance->GetIon("alpha+")
// || particleDefinition == instance->GetIon("alpha++")
// if ( particleDefinition == heliumDef
// || particleDefinition == alphaPlusDef
// || particleDefinition == alphaPlusPlusDef
// )
if (isHelium)
{
sigma = Gj[j] * (S / Bj[ionizationLevelIndex])
* ((F1 + w * F2)
/ (std::pow((1. + w), 3)
/ (gpow->powN((1. + w), 3)
* (1. + G4Exp(alphaConst * (w - wc) / v))));
if (j == 4)
sigma = Gj[j]
* (S / waterStructure.IonisationEnergy(ionizationLevelIndex))
* ((F1 + w * F2)
/ (std::pow((1. + w), 3)
/ (gpow->powN((1. + w), 3)
* (1. + G4Exp(alphaConst * (w - wc) / v))));
G4double zEff = particleDefinition->GetPDGCharge() / eplus
@@ -995,15 +987,13 @@ G4double G4DNARuddIonisationModel::R(G4double t,
G4double G4DNARuddIonisationModel::CorrectionFactor(G4ParticleDefinition* particleDefinition,
G4double k)
{
G4DNAGenericIonsManager *instance;
instance = G4DNAGenericIonsManager::Instance();
if (particleDefinition == G4Proton::Proton())
{
return (1.);
} else if (particleDefinition == instance->GetIon("hydrogen"))
} else if (particleDefinition == hydrogenDef)
{
G4double value = (std::log10(k / eV) - 4.2) / 0.5;
G4double value = (G4Log(k / eV)/gpow->logZ(10) - 4.2) / 0.5;
// The following values are provided by M. Dingfelder (priv. comm)
return ((0.6 / (1 + G4Exp(value))) + 0.9);
} else
@@ -136,7 +136,7 @@ Initialise(const G4ParticleDefinition* /*particle*/,
fParticleChangeForGamma = GetParticleChangeForGamma();
isInitialised = true;
char *path = getenv("G4LEDATA");
const char *path = G4FindDataDir("G4LEDATA");
std::ostringstream eFullFileName;
eFullFileName << path << "/dna/sigma_excitationvib_e_sanche.dat";
std::ifstream input(eFullFileName.str().c_str());
@@ -58,7 +58,7 @@ G4double G4DNASmoluchowskiReactionModel::GetReactionRadius(const G4MolecularConf
return __output;
}
G4double G4DNASmoluchowskiReactionModel::GetReactionRadius(const G4int __i)
G4double G4DNASmoluchowskiReactionModel::GetReactionRadius(const G4int& __i)
{
G4double __output = (*fpReactionData)[__i]->GetEffectiveReactionRadius();
return __output;
@@ -1,129 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// 20/2/2019
// Author : HoangTRAN
#include "G4DNATotallyDiffusionControlled.hh"
#include "G4IRTUtils.hh"
#include "G4DNAMolecularReactionTable.hh"
#include "G4VDNAReactionModel.hh"
#include "G4OctreeFinder.hh"
#include "G4SystemOfUnits.hh"
#include "G4PhysicalConstants.hh"
#include "G4MolecularConfiguration.hh"
#include "Randomize.hh"
#include "G4Molecule.hh"
#include "G4Electron_aq.hh"
#include "G4Hydrogen.hh"
#include "G4ErrorFunction.hh"
G4DNATotallyDiffusionControlled::G4DNATotallyDiffusionControlled()
: G4VReactionType()
{}
G4DNATotallyDiffusionControlled::~G4DNATotallyDiffusionControlled() = default;
G4double G4DNATotallyDiffusionControlled::GetTimeToEncounter(const G4Track& trackA,
const G4Track& trackB)
{
auto pMolConfA = GetMolecule(trackA)->GetMolecularConfiguration();
auto pMolConfB = GetMolecule(trackB)->GetMolecularConfiguration();
G4double D = GetDiffusionCoefficient(pMolConfA, pMolConfB);
auto reactionData = G4DNAMolecularReactionTable::Instance()
->GetReactionData(pMolConfA, pMolConfB);
G4double kobs = reactionData->GetObservedReactionRateConstant();
G4double distance = (trackA.GetPosition() - trackB.GetPosition()).mag();
G4double Reff = kobs / ( 4 * CLHEP::pi * D * Avogadro );
if( distance < Reff )
{
G4ExceptionDescription exceptionDescription;
exceptionDescription << "distance = "<< distance
<< " is uncorrected with "
<<" Reff = "<<Reff
<<" for : "<<pMolConfA->GetName()
<<" and "<<pMolConfB->GetName();
G4Exception("G4DNATotallyDiffusionControlled"
"::GetTimeToEncounter()", "G4DNATotallyDiffusionControlled02",
FatalException, exceptionDescription);
}
G4double Winf = Reff / distance;
G4double U = G4UniformRand();
G4double irt = -1.0 * ps;
if ( U < Winf )
{
G4double d = ( distance - Reff ) /
G4ErrorFunction::erfcInv( U / Winf );
irt = ( 1.0 / ( 4 * D ) ) * d * d;
}
return irt;
}
G4bool G4DNATotallyDiffusionControlled::
GeminateRecombinationProbability(const G4MolecularConfiguration* pMolA,
const G4MolecularConfiguration* pMolB)
{
if(pMolA->GetDefinition() == G4Electron_aq::Definition() ||
pMolA->GetDefinition() == G4Hydrogen::Definition())
{
G4bool spinA;
G4bool spinB;
spinA = G4UniformRand() < 0.5;
if(spinA &&
(pMolB->GetDefinition() == G4Electron_aq::Definition() ||
pMolB->GetDefinition() == G4Hydrogen::Definition()))
{
spinB = G4UniformRand() < 0.5;
if( !spinB )
{
return true;
}
}
return false;
}
return true;
}
G4double
G4DNATotallyDiffusionControlled::GetDiffusionCoefficient(const G4MolecularConfiguration* mA,
const G4MolecularConfiguration* mB)
{
G4double D;
if(mA == mB)
{
D = (mA->GetDiffusionCoefficient());
}
else
{
D = (mA->GetDiffusionCoefficient() +
mB->GetDiffusionCoefficient());//
}
return D;
}
@@ -33,9 +33,6 @@
#include "G4Scheduler.hh"
G4DNAUpdateSystemModel::G4DNAUpdateSystemModel()
: G4VUpdateSystemModel()
, fpMesh(nullptr)
, fVerbose(0)
, fGlobalTime(DBL_MAX)
{}
void G4DNAUpdateSystemModel::SetMesh(G4DNAMesh* pMesh) { fpMesh = pMesh; }
@@ -48,10 +45,13 @@ void G4DNAUpdateSystemModel::KillMolecule(const Index& index, MolType type)
{
if(iter->second <= 0)
{
G4cout << "G4DNAUpdateSystemModel::KillMolecule::molecule : "
<< type->GetName() << " index : " << index
<< " number : " << iter->second << G4endl;
assert(false);
G4ExceptionDescription exceptionDescription;
exceptionDescription
<< "G4DNAUpdateSystemModel::KillMolecule::molecule : "
<< type->GetName() << " index : " << index
<< " number : " << iter->second << G4endl;
G4Exception("G4DNAEventScheduler::Stepping", "G4DNAEventScheduler002",
FatalErrorInArgument, exceptionDescription);
}
iter->second--;
if(G4VMoleculeCounter::Instance()->InUse())
@@ -70,10 +70,13 @@ void G4DNAUpdateSystemModel::KillMolecule(const Index& index, MolType type)
}
else
{
G4cout << "index : " << index << " " << type->GetName() << G4endl;
G4cout << "This molecule is not belong scavengers or particle-base"
<< G4endl;
assert(false);
G4ExceptionDescription exceptionDescription;
exceptionDescription
<< "index : " << index << " " << type->GetName()
<< " This molecule is not belong scavengers or particle-base"
<< G4endl;
G4Exception("G4DNAEventScheduler::Stepping", "G4DNAEventScheduler002",
FatalErrorInArgument, exceptionDescription);
}
}
}
@@ -81,24 +84,28 @@ void G4DNAUpdateSystemModel::KillMolecule(const Index& index, MolType type)
void G4DNAUpdateSystemModel::JumpTo(const Index& index, MolType type)
{
auto& node = fpMesh->GetVoxelMapList(index);
auto iter = node.find(type);
auto iter = node.find(type);
if(iter != node.end())
{
if(iter->second <= 0)
{
G4cout << "G4DNAUpdateSystemModel::KillMolecule::molecule : "
<< type->GetName() << " index : " << index
<< " number : " << iter->second << G4endl;
assert(false);
G4ExceptionDescription exceptionDescription;
exceptionDescription << "G4DNAUpdateSystemModel::JumpTo::molecule : "
<< type->GetName() << " index : " << index
<< " number : " << iter->second;
G4Exception("G4DNAUpdateSystemModel::JumpTo", "G4DNAUpdateSystemModel001",
FatalErrorInArgument, exceptionDescription);
}
iter->second--;
}
else
{
G4cout << "index : " << index << " " << type->GetName() << G4endl;
G4cout << "This molecule is not belong particle-base" << G4endl;
assert(false);
fpMesh->PrintVoxel(index);
G4ExceptionDescription exceptionDescription;
exceptionDescription << "index : " << index << " " << type->GetName()
<< " There is no this type";
G4Exception("G4DNAUpdateSystemModel::JumpTo", "G4DNAUpdateSystemModel002",
FatalErrorInArgument, exceptionDescription);
}
}
@@ -172,34 +179,9 @@ void G4DNAUpdateSystemModel::UpdateSystem(const Index& index,
if(fVerbose != 0)
{
G4cout << data.GetProduct(j)->GetName();
// for test
// G4cout<<" fGlobalTime : "<<fGlobalTime;
// end fortest
}
#endif
CreateMolecule(index, data.GetProduct(j));
//#define DEBUG 1
#ifdef DEBUG
if(G4MoleculeCounter::Instance()->InUse())
if(fpMesh->GetNumberOfType(data.GetProduct(j)) !=
G4MoleculeCounter::Instance()->GetCurrentNumberOf(
data.GetProduct(j)))
{
G4cout << "*********G4DNAUpdateSystemModel::DEBUG::GetNumberOfType("
<< data.GetProduct(j)->GetName()
<< ") : " << fpMesh->GetNumberOfType(data.GetProduct(j))
<< G4endl;
G4cout << "G4MoleculeCounter::GetCurrentNumberOf ("
<< data.GetProduct(j)->GetName() << ") : "
<< G4MoleculeCounter::Instance()->GetCurrentNumberOf(
data.GetProduct(j))
<< G4endl;
G4MoleculeCounter::Instance()->Dump();
throw;
}
#endif
}
}
else
@@ -208,9 +190,6 @@ void G4DNAUpdateSystemModel::UpdateSystem(const Index& index,
if(fVerbose != 0)
{
G4cout << "No product";
// for test
// G4cout<<" fGlobalTime : "<<fGlobalTime;
// end fortest
}
#endif
}
@@ -221,40 +200,7 @@ void G4DNAUpdateSystemModel::UpdateSystem(const Index& index,
}
#endif
KillMolecule(index, reactant1);
#ifdef DEBUG
if(G4MoleculeCounter::Instance()->InUse())
if(fpMesh->GetNumberOfType(reactant1) !=
G4MoleculeCounter::Instance()->GetCurrentNumberOf(reactant1))
{
G4cout << "*********G4DNAUpdateSystemModel::DEBUG::GetNumberOfType("
<< reactant1->GetName()
<< ") : " << fpMesh->GetNumberOfType(reactant1) << G4endl;
G4cout << "G4MoleculeCounter::GetCurrentNumberOf ("
<< reactant1->GetName() << ") : "
<< G4MoleculeCounter::Instance()->GetCurrentNumberOf(reactant1)
<< G4endl;
G4MoleculeCounter::Instance()->Dump();
throw;
}
#endif
KillMolecule(index, reactant2);
#ifdef DEBUG
if(G4MoleculeCounter::Instance()->InUse())
if(fpMesh->GetNumberOfType(reactant2) !=
G4MoleculeCounter::Instance()->GetCurrentNumberOf(reactant2))
{
G4cout << "*********G4DNAUpdateSystemModel::DEBUG::GetNumberOfType("
<< reactant2->GetName()
<< ") : " << fpMesh->GetNumberOfType(reactant2) << G4endl;
G4cout << "G4MoleculeCounter::GetCurrentNumberOf ("
<< reactant2->GetName() << ") : "
<< G4MoleculeCounter::Instance()->GetCurrentNumberOf(reactant2)
<< G4endl;
G4MoleculeCounter::Instance()->Dump();
throw;
}
#endif
}
void G4DNAUpdateSystemModel::UpdateSystem(const Index& index,
@@ -32,78 +32,148 @@
#include "G4Exp.hh"
#include "G4IRTUtils.hh"
#include "G4SystemOfUnits.hh"
#include "G4DNAReactionTypeManager.hh"
#include "G4Electron_aq.hh"
#include "Randomize.hh"
#include "G4Molecule.hh"
#include "G4ErrorFunction.hh"
G4DiffusionControlledReactionModel::G4DiffusionControlledReactionModel()
: G4VDNAReactionModel()
, fpReactionData(nullptr)
, fReactionTypeManager(nullptr)
: G4VDNAReactionModel()
{}
G4DiffusionControlledReactionModel::~G4DiffusionControlledReactionModel() =
default;
void G4DiffusionControlledReactionModel::Initialise(
const G4MolecularConfiguration* pMolecule, const G4Track&)
{
fpReactionData = fpReactionTable->GetReactionData(pMolecule);
}
G4DiffusionControlledReactionModel::~G4DiffusionControlledReactionModel() = default;
void G4DiffusionControlledReactionModel::Initialise(const G4MolecularConfiguration* pMolecule,
const G4Track&)
void G4DiffusionControlledReactionModel::InitialiseToPrint(
const G4MolecularConfiguration* pMolecule)
{
fpReactionData = fpReactionTable->GetReactionData(pMolecule);
fpReactionData = fpReactionTable->GetReactionData(pMolecule);
}
void G4DiffusionControlledReactionModel::InitialiseToPrint(const G4MolecularConfiguration* pMolecule)
G4double G4DiffusionControlledReactionModel::GetReactionRadius(
const G4MolecularConfiguration* pMol1, const G4MolecularConfiguration* pMol2)
{
fpReactionData = fpReactionTable->GetReactionData(pMolecule);
auto reactionData = fpReactionTable->GetReactionData(pMol1, pMol2);
if(reactionData == nullptr)
{
G4ExceptionDescription exceptionDescription;
exceptionDescription << "No reactionData"
<< " for : " << pMol1->GetName() << " and "
<< pMol2->GetName();
G4Exception("G4DiffusionControlledReactionModel"
"::GetReactionRadius()",
"G4DiffusionControlledReactionModel00", FatalException,
exceptionDescription);
}
return reactionData->GetEffectiveReactionRadius();
}
G4double G4DiffusionControlledReactionModel::GetReactionRadius(const G4MolecularConfiguration* pMol1,
const G4MolecularConfiguration* pMol2)
G4double G4DiffusionControlledReactionModel::GetReactionRadius(const G4int& i)
{
auto reactionData = fpReactionTable->GetReactionData(pMol1, pMol2);
if(reactionData == nullptr)
auto pMol1 = (*fpReactionData)[i]->GetReactant1();
auto pMol2 = (*fpReactionData)[i]->GetReactant2();
return GetReactionRadius(pMol1, pMol2);
}
G4double G4DiffusionControlledReactionModel::GetTimeToEncounter(
const G4Track& trackA, const G4Track& trackB)
{
auto pMolConfA = GetMolecule(trackA)->GetMolecularConfiguration();
auto pMolConfB = GetMolecule(trackB)->GetMolecularConfiguration();
G4double D =
pMolConfA->GetDiffusionCoefficient() + pMolConfB->GetDiffusionCoefficient();
if(D == 0)
{
G4ExceptionDescription exceptionDescription;
exceptionDescription << "The total diffusion coefficient for : "
<< pMolConfA->GetName() << " and "
<< pMolConfB->GetName() << " is null ";
G4Exception("G4DiffusionControlledReactionModel"
"::GetTimeToEncounter()",
"G4DiffusionControlledReactionModel03", FatalException,
exceptionDescription);
}
auto reactionData = G4DNAMolecularReactionTable::Instance()->GetReactionData(
pMolConfA, pMolConfB);
G4double kobs = reactionData->GetObservedReactionRateConstant();
G4double distance = (trackA.GetPosition() - trackB.GetPosition()).mag();
G4double SmoluchowskiRadius = reactionData->GetEffectiveReactionRadius();
if(distance == 0 || distance < SmoluchowskiRadius)
{
G4ExceptionDescription exceptionDescription;
exceptionDescription << "distance = " << distance << " is uncorrected with "
<< " Reff = " << SmoluchowskiRadius
<< " for : " << pMolConfA->GetName() << " and "
<< pMolConfB->GetName();
G4Exception("G4DiffusionControlledReactionModel"
"::GetTimeToEncounter()",
"G4DiffusionControlledReactionModel02", FatalException,
exceptionDescription);
}
else
{
G4double Winf = SmoluchowskiRadius / distance;
G4double U = G4UniformRand();
G4double X = 0;
G4double irt_1 = -1.0 * ps;
if(Winf > 0 && U < Winf)
{
G4ExceptionDescription exceptionDescription;
exceptionDescription << "No reactionData"
<<" for : "<<pMol1->GetName()
<<" and "<<pMol2->GetName();
G4Exception("G4DiffusionControlledReactionModel"
"::GetReactionRadius()", "G4DiffusionControlledReactionModel00",
FatalException, exceptionDescription);
G4double erfcIn = G4ErrorFunction::erfcInv(U / Winf);
if(erfcIn != 0)
{
G4double d =
(distance - SmoluchowskiRadius) / erfcIn;
irt_1 = (1.0 / (4 * D)) * d * d;
}
}
G4double kobs = reactionData->GetObservedReactionRateConstant();
G4double D;
if(pMol1 == pMol2)
{
D = (pMol1->GetDiffusionCoefficient());
if(reactionData->GetReactionType() == 0) // Totally diffused contr
{
return irt_1;
}
if(irt_1 < 0)
{
return irt_1;
}
else
{
D = (pMol1->GetDiffusionCoefficient() +
pMol2->GetDiffusionCoefficient());//
G4double kdif = 4 * CLHEP::pi * D * SmoluchowskiRadius * Avogadro;
if(pMolConfA == pMolConfB)
{
kdif /= 2;
}
G4double kact = G4IRTUtils::GetKact(kobs, kdif);
G4double sumOfk = kact + kdif;
if(sumOfk != 0)
{
G4double rateFactor = kact / sumOfk;
if(G4UniformRand() > rateFactor)
{
return -1.0 * ps;
}
G4double Y = std::abs(G4RandGauss::shoot(0.0, std::sqrt(2)));
if(Y > 0)
{
X = -(G4Log(G4UniformRand())) / Y;
}
G4double f = X * SmoluchowskiRadius * kdif / sumOfk;
G4double irt_2 = (f * f) / D;
return irt_1 + irt_2;
}
}
if ( D == 0 )
{
G4ExceptionDescription exceptionDescription;
exceptionDescription << "D = "<< D
<< " is uncorrected"
<<" for : "<<pMol1->GetName()
<<" and "<<pMol2->GetName();
G4Exception("G4DiffusionControlledReactionModel"
"::GetReactionRadius()", "G4DiffusionControlledReactionModel01",
FatalException, exceptionDescription);
}
G4double Reff = kobs / ( 4 * CLHEP::pi * D * Avogadro );
return Reff;
}
G4double G4DiffusionControlledReactionModel::GetReactionRadius(G4int i)
{
auto pMol1 = (*fpReactionData)[i]->GetReactant1();
auto pMol2 = (*fpReactionData)[i]->GetReactant2();
return GetReactionRadius(pMol1,pMol2);
}
void G4DiffusionControlledReactionModel::SetReactionTypeManager(G4VReactionTypeManager* typeManager)
{
fReactionTypeManager = ((G4DNAReactionTypeManager*)typeManager);
}
return -1.0 * ps;
}
@@ -23,17 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// Author: Mathieu Karamitros (kara (AT) cenbg . in2p3 . fr)
//
// History:
// -----------
// 10 Oct 2011 M.Karamitros created
//
// -------------------------------------------------------------------
#include "G4ITFinder.hh"
G4VITFinder::G4VITFinder()
{
}
#include "G4VDNAHitModel.hh"
G4VDNAHitModel::G4VDNAHitModel(const G4String& name)
: fName(name)
{}
@@ -84,7 +84,7 @@ G4double G4VLEPTSModel::GetMeanFreePath(const G4Material* aMaterial,
void G4VLEPTSModel::BuildPhysicsTable(const G4ParticleDefinition& aParticleType)
{
//CHECK IF PATH VARIABLE IS DEFINED
char* path = std::getenv("G4LEDATA");
const char* path = G4FindDataDir("G4LEDATA");
if( !path ) {
G4Exception("G4VLEPTSModel",
"",
@@ -293,6 +293,9 @@ public:
inline void Finalize();
static void FinalizeAll();
static void PrintAll(); //hoang added
inline void UnFinalize();
void SetUserID(const G4String& userID);//hoang moved it to public
inline const G4String& GetUserID() const;
@@ -331,7 +334,6 @@ protected:
void CheckElectronOccupancy(const char* line) const;
void MakeExceptionIfFinalized();
void SetUserID(const G4String& userID);
void CreateDefaultDiffCoeffParam();
static void ScaleAllDiffusionCoefficientsOnWater(double temperature_K);
@@ -591,4 +593,9 @@ G4MolecularConfiguration::GetDiffusionCoefficient(const G4Material* material,
return fDiffParam(material, temperature, this);
}
inline void G4MolecularConfiguration::UnFinalize()
{
fIsFinalized = false;
}
#endif
@@ -49,8 +49,11 @@
#include "G4MoleculeIterator.hh"
#include "G4ElectronOccupancy.hh"
#include <memory>
class G4MoleculeDefinition;
class G4MolecularConfiguration;
class G4MoleculeTableMessenger;
typedef G4MoleculeIterator<G4MoleculeDefinition> G4MoleculeDefinitionIterator;
typedef G4MoleculeIterator<G4MolecularConfiguration> G4ConfigurationIterator;
@@ -131,6 +134,8 @@ protected:
typedef std::map<G4String, G4MoleculeDefinition*> MoleculeDefTable;
MoleculeDefTable fMoleculeDefTable;
std::unique_ptr<G4MoleculeTableMessenger> fMoleculeDefTableMessenger;
};
#endif /* G4MOLECULETABLE_HH_ */
@@ -24,49 +24,32 @@
// ********************************************************************
//
#ifndef _G4MOLECULETABLEMESSENGER_HH
#define _G4MOLECULETABLEMESSENGER_HH
#include "G4DNAReactionTypeManager.hh"
#include "G4VReactionType.hh"
#include <G4UImessenger.hh>
G4DNAReactionTypeManager::G4DNAReactionTypeManager()
: G4VReactionTypeManager()
{}
#include <memory>
G4DNAReactionTypeManager::~G4DNAReactionTypeManager()
class G4UIcmdWithAString;
class G4DNAMolecularReactionTable;
class G4UIcmdWithoutParameter;
class G4UIcmdWithADoubleAndUnit;
class G4UIcmdWithAnInteger;
class G4UIcmdWithABool;
class G4MoleculeTableMessenger : public G4UImessenger
{
Clear();
}
public:
G4MoleculeTableMessenger();
~G4MoleculeTableMessenger() override;
void SetNewValue(G4UIcommand * command,G4String newValue) override;
void G4DNAReactionTypeManager::Clear()
{
for(auto it : fReactionTypeTable)
{
if(it.second != nullptr)
{
delete it.second;
it.second = nullptr;
}
}
fReactionTypeTable.clear();
}
protected:
std::unique_ptr<G4UIcmdWithoutParameter> fpPrintTable;
std::unique_ptr<G4UIcmdWithAString> fpSpecies;
void G4DNAReactionTypeManager::SetReactionTypeTable(G4VReactionType* process)
{
G4int index = fReactionTypeTable.size();
fReactionTypeTable[index] = process;
}
};
const ReactionTypeTable* G4DNAReactionTypeManager::GetReactionTypeTable() const
{
return &fReactionTypeTable;
}
void G4DNAReactionTypeManager::SetTypeTableByID(std::map<ReactionID, ReactionType> byIDMap)
{
fReactionTypeByID = byIDMap;
}
ReactionType G4DNAReactionTypeManager::GetReactionTypeByID(ReactionID iD)
{
return fReactionTypeByID[iD];
}
#endif // GEANT4_G4MOLECULETABLEMESSENGER_HH
@@ -44,7 +44,7 @@ class G4VMoleculeCounter
{
protected:
static G4ThreadLocal G4VMoleculeCounter* fpInstance;
static G4bool fUse;
G4bool fUse = false;
G4VMoleculeCounter() = default;
@@ -70,9 +70,9 @@ public:
* at every creation/deletion of a molecule to
* to increase/decrease the number at a given time.
*/
static void Use(G4bool flag = true);
void Use(G4bool flag = true);
static G4bool InUse();
G4bool InUse();
//----------------------------------------------------
@@ -17,6 +17,7 @@ geant4_add_module(G4emdna-molman
G4Serialize.hh
G4VMolecularDissociationDisplacer.hh
G4VMoleculeCounter.hh
G4MoleculeTableMessenger.hh
SOURCES
G4MolecularConfiguration.cc
G4MolecularDissociationChannel.cc
@@ -28,7 +29,8 @@ geant4_add_module(G4emdna-molman
G4MoleculeTable.cc
G4Serialize.cc
G4VMolecularDissociationDisplacer.cc
G4VMoleculeCounter.cc)
G4VMoleculeCounter.cc
G4MoleculeTableMessenger.cc)
geant4_module_link_libraries(G4emdna-molman
PUBLIC
@@ -1553,3 +1553,23 @@ void G4MolecularConfiguration::FinalizeAll()
}
}
void G4MolecularConfiguration::PrintAll() //hoang added
{
const std::vector<G4MolecularConfiguration*>& species =
GetManager()->GetAllSpecies();
G4cout<<G4endl;
G4cout<<"Molecular Config"<<std::setw(25)<<" | Diffusion Coefficient (m2 / s) "<<std::setw(20)<<" | Radius (nm) "<<G4endl;
G4cout<<"__________________________________________"
"___________________________________"<<G4endl;
for(size_t i = 0; i < species.size() ; ++i)
{
G4cout<<species[i]->GetName()
<<std::setw(30 - species[i]->GetName().length())
<<right<<species[i]->GetDiffusionCoefficient() * 1.0e3<<std::setw(30)
<<species[i]->GetVanDerVaalsRadius()/CLHEP::nm<<G4endl;
G4cout<<"__________________________________________"
"___________________________________"<<G4endl;
}
}
@@ -56,8 +56,6 @@
using namespace std;
ITImp(G4Molecule)
G4Allocator<G4Molecule>*& aMoleculeAllocator()
{
G4ThreadLocalStatic G4Allocator<G4Molecule>* _instance = nullptr;
@@ -396,7 +394,7 @@ G4Track* G4Molecule::BuildTrack(G4double globalTime,
fpMolecularConfiguration->GetDefinition(), MomentumDirection,
KineticEnergy);
if (G4VMoleculeCounter::InUse())
if (G4VMoleculeCounter::Instance()->InUse())
{
G4VMoleculeCounter::Instance()->
AddAMoleculeAtTime(fpMolecularConfiguration,
@@ -33,12 +33,14 @@
#include "G4MoleculeTable.hh"
#include "G4MolecularConfiguration.hh"
#include "G4MoleculeDefinition.hh"
#include "G4MoleculeTableMessenger.hh"
G4MoleculeTable* G4MoleculeTable::fpgMoleculeTable(0);
//------------------------------------------------------------------------------
G4MoleculeTable::G4MoleculeTable()
: fMoleculeDefTableMessenger(new G4MoleculeTableMessenger())
{
}
@@ -0,0 +1,163 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
#include "G4MoleculeTableMessenger.hh"
#include "G4UIcmdWithAString.hh"
#include <G4SystemOfUnits.hh>
#include <G4UIcmdWithoutParameter.hh>
#include "G4MoleculeTable.hh"
#include "G4MoleculeDefinition.hh"
#include "G4MolecularConfiguration.hh"
#include "G4ParticleTable.hh"
//------------------------------------------------------------------------------
G4MoleculeTableMessenger::G4MoleculeTableMessenger()
: G4UImessenger()
, fpPrintTable(new G4UIcmdWithoutParameter("/chem/PrintSpeciesTable", this))
, fpSpecies(new G4UIcmdWithAString("/chem/species", this))
{}
G4MoleculeTableMessenger::~G4MoleculeTableMessenger() = default;
//------------------------------------------------------------------------------
void G4MoleculeTableMessenger::SetNewValue(G4UIcommand* command,
G4String newValue)
{
if(command == fpPrintTable.get())
{
G4MolecularConfiguration::PrintAll();
}
if(command == fpSpecies.get())
{
std::istringstream iss(newValue);
G4String speciesName;
iss >> speciesName;
G4String marker;
iss >> marker; // must be [
if(marker != "[")
{
G4ExceptionDescription description;
description << " marker : " << marker << G4endl;
G4Exception("G4MoleculeTableMessenger::SetNewValue",
"FAIL_SPECIES_DEFINITION04", FatalException, description);
}
G4String speciesDefName;
iss >> speciesDefName;
iss >> marker; // peut etre |
G4int charge = 0;
if(marker == "|")
{
iss >> charge;
}
iss >> marker; // peut etre |
G4double diffusion_coefficient = 0;
if(marker == "|")
{
iss >> diffusion_coefficient;
}
iss >> marker; // peut etre |
G4double VanDerVaalsRadius = 0;
if(marker == "|")
{
iss >> VanDerVaalsRadius; // in nm
}
auto pConf =
G4MolecularConfiguration::GetMolecularConfiguration(speciesName);
if(pConf != nullptr)
{
pConf->UnFinalize();
if(VanDerVaalsRadius != 0)
{
pConf->SetVanDerVaalsRadius(VanDerVaalsRadius * nm);
}
if(diffusion_coefficient != 0)
{
pConf->SetDiffusionCoefficient(diffusion_coefficient * (m2 / s));
}
}
else
{
auto particleDef = dynamic_cast<G4MoleculeDefinition*>(
G4ParticleTable::GetParticleTable()->FindParticle(speciesDefName));
if(particleDef != nullptr)
{
auto molConf =
G4MolecularConfiguration::GetOrCreateMolecularConfiguration(
particleDef, charge);
if(molConf == nullptr)
{
G4ExceptionDescription description;
description << "This molecule has not been defined" << G4endl;
G4Exception("G4MoleculeTableMessenger::SetNewValue",
"FAIL_SPECIES_DEFINITION02", FatalException, description);
}
molConf->UnFinalize();
if(VanDerVaalsRadius != 0)
{
molConf->SetVanDerVaalsRadius(VanDerVaalsRadius * nm);
}
if(diffusion_coefficient != 0)
{
molConf->SetDiffusionCoefficient(diffusion_coefficient * (m2 / s));
}
auto usedName = molConf->GetUserID();
if(usedName != "")
{
molConf->PrintState();
G4ExceptionDescription description;
description << "This molecule has been defined by the name : "
<< usedName << " . Please, use this name." << G4endl;
G4Exception("G4MoleculeTableMessenger::SetNewValue",
"FAIL_SPECIES_DEFINITION", FatalException, description);
}
else
{
molConf->SetUserID(speciesName);
}
}
else
{
auto speciesDef =
new G4MoleculeDefinition(speciesDefName, /*mass no needed*/ 0,
/*D*/ diffusion_coefficient * (m * m / s),
/*charge*/ charge, 1,
/*electronL*/ 0,
/*radius*/ VanDerVaalsRadius * nm);
G4bool alreadyCreated(false);
G4MolecularConfiguration::CreateMolecularConfiguration(
speciesName, speciesDef, alreadyCreated);
}
}
}
}
@@ -32,8 +32,6 @@
#include "G4VMoleculeCounter.hh"
#include "G4MoleculeCounter.hh"
G4bool G4VMoleculeCounter::fUse = false;
G4ThreadLocal
G4VMoleculeCounter* G4VMoleculeCounter::fpInstance = nullptr;
@@ -50,6 +50,7 @@
class G4SafetyHelper;
class G4Molecule;
class G4VUserBrownianAction;
// experimental
class G4BrownianAction
@@ -111,12 +112,12 @@ public:
G4DNABrownianTransportation(const G4String& aName =
"DNABrownianTransportation",
G4int verbosityLevel = 0);
G4IT_ADD_CLONE(G4VITProcess,G4DNABrownianTransportation)
virtual ~G4DNABrownianTransportation();
G4DNABrownianTransportation(const G4DNABrownianTransportation&);
G4DNABrownianTransportation& operator=(const G4DNABrownianTransportation&);
G4DNABrownianTransportation(const G4DNABrownianTransportation&) = delete;
G4DNABrownianTransportation& operator=(const G4DNABrownianTransportation&) = delete;
inline void SetBrownianAction(G4BrownianAction*);
inline void SetUserBrownianAction(G4VUserBrownianAction*);
virtual void BuildPhysicsTable(const G4ParticleDefinition&);
@@ -236,6 +237,8 @@ protected:
const std::vector<G4double>* fpWaterDensity;
G4BrownianAction* fpBrownianAction;
G4VUserBrownianAction *fpUserBrownianAction;
};
@@ -244,4 +247,10 @@ inline void G4DNABrownianTransportation::SetBrownianAction(G4BrownianAction* bro
fpBrownianAction = brownianAction;
}
inline void G4DNABrownianTransportation::SetUserBrownianAction(G4VUserBrownianAction* brownianAction)
{
fpUserBrownianAction = brownianAction;
}
#endif // G4ITBROWNIANTRANSPORTATION_H
@@ -52,7 +52,7 @@
class G4ParticleChange;
class G4VMolecularDissociationDisplacer;
class G4MoleculeDefinition;
class G4VUserBrownianAction;
/**
* G4DNAMolecularDissociation should be called only for molecules.
* It will dissociate the molecules using the decay associated to
@@ -88,6 +88,11 @@ public:
void SetVerbose(G4int);
inline void SetUserBrownianAction(G4VUserBrownianAction* pBrownianAction)
{
fpBrownianAction = pBrownianAction;
}
void SetDisplacer(Species*, Displacer*);
Displacer* GetDisplacer(Species*);
@@ -102,7 +107,7 @@ protected:
private:
using DisplacementMap = std::map<Species*, std::unique_ptr<Displacer>>;
G4VUserBrownianAction* fpBrownianAction = nullptr;
G4bool fDecayAtFixedTime;
DisplacementMap fDisplacementMap;
G4int fVerbose;
@@ -0,0 +1,104 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
/// file: G4DNAPolyNucleotideReactionProcess.hh
/// brief: This file handls reaction process with DNA geometry.
#ifndef G4DNAPolyNucleotideReactionProcess_hh
#define G4DNAPolyNucleotideReactionProcess_hh
#include <CLHEP/Units/SystemOfUnits.h>
#include "G4VITDiscreteProcess.hh"
#include <variant>
class G4DNAMolecularReactionTable;
class G4DNAComponentNode;
class G4VDNAHitModel;
class G4DNAPolyNucleotideReactionProcess : public G4VITDiscreteProcess
{
public:
explicit G4DNAPolyNucleotideReactionProcess(
const G4String& aName = "DNAStaticMoleculeReactionProcess",
G4int verbosityLevel = 0);
~G4DNAPolyNucleotideReactionProcess() override;
inline void SetDNADamageReactionModel(G4VDNAHitModel* pModel);
G4bool IsApplicable(const G4ParticleDefinition&) override { return true; }
G4double CalculateTimeStep(const G4Track& trackA,
const G4double& userTimeStep = 0);
void StartTracking(G4Track* aTrack) override;
G4double PostStepGetPhysicalInteractionLength(
const G4Track&, // track
G4double, // previousStepSize
G4ForceCondition* pForceCond) override;
G4VParticleChange* PostStepDoIt(const G4Track& track, const G4Step&) override;
G4double GetMeanFreePath(const G4Track&, G4double, G4ForceCondition*) override
{
return DBL_MAX;
}
G4DNAPolyNucleotideReactionProcess& operator =(
const G4DNAPolyNucleotideReactionProcess&) = delete;
inline void SetVerbose(G4int verbose);
protected:
G4VParticleChange fParticleChange;
private:
struct G4PolyNucleotideReactionState
: public G4ProcessStateBase<G4PolyNucleotideReactionState>
{
G4PolyNucleotideReactionState();
~G4PolyNucleotideReactionState() override = default;
G4String GetType() override { return "PolyNucleotideReactionState"; }
using DNANode =
std::variant<const G4DNAComponentNode*, /*for dnadamage chain*/
const G4VPhysicalVolume* /*for molecularDNA chain*/>;
DNANode fNodeReactant;
G4double fSampledMinTimeStep;
G4double fPreviousTimeAtPreStepPoint;
};
G4bool fHasAlreadyReachedNullTime;
G4int fVerbose;
G4double fRCutOff;
G4VDNAHitModel* fpDamageModel;
const G4DNAMolecularReactionTable* fMolecularReactionTable;
G4DNAPolyNucleotideReactionProcess(const G4DNAPolyNucleotideReactionProcess&);
};
inline void G4DNAPolyNucleotideReactionProcess::SetVerbose(G4int verbose)
{
fVerbose = verbose;
}
inline void G4DNAPolyNucleotideReactionProcess::SetDNADamageReactionModel(
G4VDNAHitModel* pModel)
{
fpDamageModel = pModel;
}
#endif
@@ -39,7 +39,7 @@ class G4DNAScavengerProcess : public G4VITProcess
using Data = const G4DNAMolecularReactionData;
explicit G4DNAScavengerProcess(const G4String& aName,
const G4DNABoundingBox& box,
G4ProcessType type = fDecay);
G4ProcessType type = fUserDefined);
~G4DNAScavengerProcess() override;
G4DNAScavengerProcess(const G4DNAScavengerProcess&) = delete;
G4DNAScavengerProcess& operator=(const G4DNAScavengerProcess&) = delete;
@@ -100,6 +100,5 @@ class G4DNAScavengerProcess : public G4VITProcess
MolType fpMaterialConf;
const G4DNABoundingBox* fpBoundingBox;
G4DNAScavengerMaterial* fpScavengerMaterial;
G4int fVerbose;
};
#endif // FLASH1_G4DNASCAVENGERPROCESS_HH
@@ -22,6 +22,7 @@ geant4_add_module(G4emdna-processes
G4DNASecondOrderReaction.hh
G4DNAVibExcitation.hh
G4DNAScavengerProcess.hh
G4DNAPolyNucleotideReactionProcess.hh
SOURCES
G4DNAAttachment.cc
G4DNABrownianTransportation.cc
@@ -40,7 +41,8 @@ geant4_add_module(G4emdna-processes
G4DNAWaterDissociationDisplacer.cc
G4DNASecondOrderReaction.cc
G4DNAVibExcitation.cc
G4DNAScavengerProcess.cc)
G4DNAScavengerProcess.cc
G4DNAPolyNucleotideReactionProcess.cc)
geant4_module_link_libraries(G4emdna-processes
PUBLIC

Some files were not shown because too many files have changed in this diff Show More