Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4DNAPTBExcitationModel.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26// Authors: S. Meylan and C. Villagrasa (IRSN, France)
27// Models come from
28// M. Bug et al, Rad. Phys and Chem. 130, 459-479 (2017)
29//
30
32
36#include "G4SystemOfUnits.hh"
37
39 const G4ParticleDefinition*, const G4String& nam)
40 : G4VDNAModel(nam, applyToMaterial)
41{
42 fpTHF = G4Material::GetMaterial("THF", false);
43 fpPY = G4Material::GetMaterial("PY", false);
44 fpPU = G4Material::GetMaterial("PU", false);
45 fpTMP = G4Material::GetMaterial("TMP", false);
46 fpG4_WATER = G4Material::GetMaterial("G4_WATER", false);
47 fpBackbone_THF = G4Material::GetMaterial("backbone_THF", false);
48 fpCytosine_PY = G4Material::GetMaterial("cytosine_PY", false);
49 fpThymine_PY = G4Material::GetMaterial("thymine_PY", false);
50 fpAdenine_PU = G4Material::GetMaterial("adenine_PU", false);
51 fpBackbone_TMP = G4Material::GetMaterial("backbone_TMP", false);
52 fpGuanine_PU = G4Material::GetMaterial("guanine_PU", false);
53 fpN2 = G4Material::GetMaterial("N2", false);
54 // initialisation of mean energy loss for each material
55
56 if (fpTHF != nullptr) {
57 fTableMeanEnergyPTB[fpTHF->GetIndex()] = 8.01 * eV;
58 }
59
60 if (fpPY != nullptr) {
61 fTableMeanEnergyPTB[fpPY->GetIndex()] = 7.61 * eV;
62 }
63
64 if (fpPU != nullptr) {
65 fTableMeanEnergyPTB[fpPU->GetIndex()] = 7.61 * eV;
66 }
67 if (fpTMP != nullptr) {
68 fTableMeanEnergyPTB[fpTMP->GetIndex()] = 8.01 * eV;
69 }
70
71 if (verboseLevel > 0) {
72 G4cout << "PTB excitation model is constructed " << G4endl;
73 }
74}
75
76//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
77
79 const G4DataVector& /*cuts*/)
80{
81 if (isInitialised) {
82 return;
83 }
84 if (verboseLevel > 3)
85 {
86 G4cout << "Calling G4DNAPTBExcitationModel::Initialise()" << G4endl;
87 }
88
89 if (particle != G4Electron::ElectronDefinition()) {
90 std::ostringstream oss;
91 oss << " Model is not applied for this particle " << particle->GetParticleName();
92 G4Exception("G4DNAPTBExcitationModel::Initialise", "PTB001", FatalException, oss.str().c_str());
93 }
94
95 G4double scaleFactor = 1e-16 * cm * cm;
96 G4double scaleFactorBorn = (1.e-22 / 3.343) * m * m;
97
98 //*******************************************************
99 // Cross section data
100 //*******************************************************
101 std::size_t index;
102 if (fpTHF != nullptr) {
103 index = fpTHF->GetIndex();
104 AddCrossSectionData(index, particle, "dna/sigma_excitation_e-_PTB_THF", scaleFactor);
105 SetLowELimit(index, particle, 9. * eV);
106 SetHighELimit(index, particle, 1. * keV);
107 }
108 if (fpPY != nullptr) {
109 index = fpPY->GetIndex();
110 AddCrossSectionData(index, particle, "dna/sigma_excitation_e-_PTB_PY", scaleFactor);
111 SetLowELimit(index, particle, 9. * eV);
112 SetHighELimit(index, particle, 1. * keV);
113 }
114
115 if (fpPU != nullptr) {
116 index = fpPU->GetIndex();
117 AddCrossSectionData(index, particle, "dna/sigma_excitation_e-_PTB_PU", scaleFactor);
118 SetLowELimit(index, particle, 9. * eV);
119 SetHighELimit(index, particle, 1. * keV);
120 }
121
122 if (fpTMP != nullptr) {
123 index = fpTMP->GetIndex();
124 AddCrossSectionData(index, particle, "dna/sigma_excitation_e-_PTB_TMP", scaleFactor);
125 SetLowELimit(index, particle, 9. * eV);
126 SetHighELimit(index, particle, 1. * keV);
127 }
128 if (fpG4_WATER != nullptr) {
129 index = fpG4_WATER->GetIndex();
130 AddCrossSectionData(index, particle, "dna/sigma_excitation_e_born", scaleFactorBorn);
131 SetLowELimit(index, particle, 9. * eV);
132 SetHighELimit(index, particle, 1. * keV);
133 }
134 // DNA materials
135 //
136 if (fpBackbone_THF != nullptr) {
137 index = fpBackbone_THF->GetIndex();
138 AddCrossSectionData(index, particle, "dna/sigma_excitation_e-_PTB_THF", scaleFactor * 33. / 30);
139 SetLowELimit(index, particle, 9. * eV);
140 SetHighELimit(index, particle, 1. * keV);
141 }
142 if (fpCytosine_PY != nullptr) {
143 index = fpCytosine_PY->GetIndex();
144 AddCrossSectionData(index, particle, "dna/sigma_excitation_e-_PTB_PY", scaleFactor * 42. / 30);
145 SetLowELimit(index, particle, 9. * eV);
146 SetHighELimit(index, particle, 1. * keV);
147 }
148 if (fpThymine_PY != nullptr) {
149 index = fpThymine_PY->GetIndex();
150 AddCrossSectionData(index, particle, "dna/sigma_excitation_e-_PTB_PY", scaleFactor * 48. / 30);
151 SetLowELimit(index, particle, 9. * eV);
152 SetHighELimit(index, particle, 1. * keV);
153 }
154 if (fpAdenine_PU != nullptr) {
155 index = fpAdenine_PU->GetIndex();
156 AddCrossSectionData(index, particle, "dna/sigma_excitation_e-_PTB_PU", scaleFactor * 50. / 44);
157 SetLowELimit(index, particle, 9. * eV);
158 SetHighELimit(index, particle, 1. * keV);
159 }
160 if (fpGuanine_PU != nullptr) {
161 index = fpGuanine_PU->GetIndex();
162 AddCrossSectionData(index, particle, "dna/sigma_excitation_e-_PTB_PU", scaleFactor * 56. / 44);
163 SetLowELimit(index, particle, 9. * eV);
164 SetHighELimit(index, particle, 1. * keV);
165 }
166 if (fpBackbone_TMP != nullptr) {
167 index = fpBackbone_TMP->GetIndex();
168 AddCrossSectionData(index, particle, "dna/sigma_excitation_e-_PTB_TMP", scaleFactor * 33. / 50);
169 SetLowELimit(index, particle, 9. * eV);
170 SetHighELimit(index, particle, 1. * keV);
171 }
172 // MPietrzak, adding paths for N2
173 if (fpN2 != nullptr) {
174 index = fpN2->GetIndex();
175 AddCrossSectionData(index, particle, "dna/sigma_excitation_e-_PTB_N2", scaleFactor);
176 SetLowELimit(index, particle, 13. * eV);
177 SetHighELimit(index, particle, 1.02 * MeV);
178 }
180 // Load data
181 LoadCrossSectionData(particle);
183 fpModelData = this;
184 }
185 else {
186 auto dataModel = dynamic_cast<G4DNAPTBExcitationModel*>(
188 if (dataModel == nullptr) {
189 G4cout << "G4DNAPTBExcitationModel::Initialise:: not good modelData" << G4endl;
190 G4Exception("G4DNAPTBExcitationModel::Initialise", "PTB0006", FatalException,
191 "not good modelData");
192 }
193 else {
194 fpModelData = dataModel;
195 }
196 }
197
199 isInitialised = true;
200}
201
202//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
203
205 const G4ParticleDefinition* p,
206 G4double ekin, G4double /*emin*/,
207 G4double /*emax*/)
208{
209 // Get the name of the current particle
210 G4String particleName = p->GetParticleName();
211 const std::size_t& MatID = material->GetIndex();
212 // initialise variables
213 G4double lowLim;
214 G4double highLim;
215 G4double sigma = 0;
216
217 // Get the low energy limit for the current particle
218 lowLim = fpModelData->GetLowELimit(MatID, p);
219
220 // Get the high energy limit for the current particle
221 highLim = fpModelData->GetHighELimit(MatID, p);
222
223 // Check that we are in the correct energy range
224 if (ekin >= lowLim && ekin < highLim) {
225 // Get the map with all the data tables
226 auto Data = fpModelData->GetData();
227
228 if ((*Data)[MatID][p] == nullptr) {
229 G4Exception("G4DNAPTBExcitationModel::CrossSectionPerVolume", "em00236", FatalException,
230 "No model is registered");
231 }
232 // Retrieve the cross section value
233 sigma = (*Data)[MatID][p]->FindValue(ekin);
234
235 if (verboseLevel > 2) {
236 G4cout << "__________________________________" << G4endl;
237 G4cout << "°°° G4DNAPTBExcitationModel - XS INFO START" << G4endl;
238 G4cout << "°°° Kinetic energy(eV)=" << ekin / eV << " particle : " << particleName << G4endl;
239 G4cout << "°°° Cross section per " << MatID << " ID molecule (cm^2)=" << sigma / cm / cm
240 << G4endl;
241 G4cout << "°°° G4DNAPTBExcitationModel - XS INFO END" << G4endl;
242 }
243 }
244
245 // Return the cross section value
246 auto MolDensity =
248 return sigma * MolDensity;
249}
250
251//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
252
253void G4DNAPTBExcitationModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
254 const G4MaterialCutsCouple* couple,
255 const G4DynamicParticle* aDynamicParticle,
256 G4double /*tmin*/, G4double /*tmax*/)
257{
258 const std::size_t& materialID = (std::size_t)couple->GetIndex();
259
260 // Get the incident particle kinetic energy
261 G4double k = aDynamicParticle->GetKineticEnergy();
262 // Get the particle name
263 const auto& particle = aDynamicParticle->GetDefinition();
264 // Get the energy limits
265 G4double lowLim = fpModelData->GetLowELimit(materialID, particle);
266 G4double highLim = fpModelData->GetHighELimit(materialID, particle);
267
268 // Check if we are in the correct energy range
269 if (k >= lowLim && k < highLim) {
270 if (fpN2 != nullptr && materialID == fpN2->GetIndex()) {
271 // Retrieve the excitation energy for the current material
272 G4int level = fpModelData->RandomSelectShell(k, particle, materialID);
273 G4double excitationEnergy = ptbExcitationStructure.ExcitationEnergy(level, fpN2->GetIndex());
274
275 // Calculate the new energy of the particle
276 G4double newEnergy = k - excitationEnergy;
277
278 // Check that the new energy is above zero before applying it the particle.
279 // Otherwise, do nothing.
280 if (newEnergy > 0) {
284 G4double ioniThres = ptbIonisationStructure.IonisationEnergy(0, fpN2->GetIndex());
285 // if excitation energy greater than ionisation threshold, then autoionisaiton
286 if ((excitationEnergy > ioniThres) && (G4UniformRand() < 0.5)) {
288 // energy of ejected electron
289 G4double secondaryKinetic = excitationEnergy - ioniThres;
290 // random direction
291 G4double cosTheta = 2 * G4UniformRand() - 1., phi = CLHEP::twopi * G4UniformRand();
292 G4double sinTheta = std::sqrt(1. - cosTheta * cosTheta);
293 G4double ux = sinTheta * std::cos(phi), uy = sinTheta * std::sin(phi), uz = cosTheta;
294 G4ThreeVector deltaDirection(ux, uy, uz);
295 // Create the new particle with its characteristics
296 auto dp = new G4DynamicParticle(G4Electron::Electron(), deltaDirection, secondaryKinetic);
297 fvect->push_back(dp);
298 }
299 }
300 else {
301 G4ExceptionDescription description;
302 description << "Kinetic energy <= 0 at " << fpN2->GetName() << " material !!!";
303 G4Exception("G4DNAPTBExcitationModel::SampleSecondaries", "", FatalException, description);
304 }
305 }
306 else if (fpG4_WATER == nullptr || materialID != fpG4_WATER->GetIndex()) {
307 // Retrieve the excitation energy for the current material
308 G4double excitationEnergy = fTableMeanEnergyPTB[materialID];
309 // Calculate the new energy of the particle
310 G4double newEnergy = k - excitationEnergy;
311 // Check that the new energy is above zero before applying it the particle.
312 // Otherwise, do nothing.
313 if (newEnergy > 0) {
317 }
318 else {
319 G4ExceptionDescription description;
320 description << "Kinetic energy <= 0 at " << materialID << " index material !!!";
321 G4Exception("G4DNAPTBExcitationModel::SampleSecondaries", "", FatalException, description);
322 }
323 }
324 else {
325 G4int level = RandomSelectShell(k, particle, materialID);
326 G4double excitationEnergy = waterStructure.ExcitationEnergy(level);
327 G4double newEnergy = k - excitationEnergy;
328
329 if (newEnergy > 0) {
333 const G4Track* theIncomingTrack = fParticleChangeForGamma->GetCurrentTrack();
335 theIncomingTrack);
336 }
337 else {
338 G4ExceptionDescription description;
339 description << "Kinetic energy <= 0 at " << materialID << " ID material !!!";
340 G4Exception("G4DNAPTBExcitationModel::SampleSecondaries", "", FatalException, description);
341 }
342 }
343 }
344}
@ eExcitedMolecule
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
double G4double
Definition G4Types.hh:83
int G4int
Definition G4Types.hh:85
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout
#define G4UniformRand()
Definition Randomize.hh:52
static G4DNAChemistryManager * Instance()
void CreateWaterMolecule(ElectronicModification, G4int, const G4Track *)
static G4DNAMaterialManager * Instance()
void SetMasterDataModel(const DNAModelType &t, G4VEmModel *m)
G4VEmModel * GetModel(const DNAModelType &t)
const std::vector< G4double > * GetNumMolPerVolTableFor(const G4Material *) const
Retrieve a table of molecular densities (number of molecules per unit volume) in the G4 unit system f...
static G4DNAMolecularMaterial * Instance()
G4double CrossSectionPerVolume(const G4Material *material, const G4ParticleDefinition *p, G4double ekin, G4double emin, G4double emax) override
CrossSectionPerVolume Retrieve the cross section corresponding to the current material,...
void SampleSecondaries(std::vector< G4DynamicParticle * > *, const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double tmin, G4double tmax) override
SampleSecondaries If the model is selected for the ModelInterface then the SampleSecondaries method w...
G4ParticleChangeForGamma * fParticleChangeForGamma
void Initialise(const G4ParticleDefinition *particle, const G4DataVector &) override
Initialise Set the materials for which the model can be used and defined the energy limits.
G4DNAPTBExcitationModel(const G4String &applyToMaterial="all", const G4ParticleDefinition *p=nullptr, const G4String &nam="DNAPTBExcitationModel")
G4DNAPTBExcitationModel Constructor.
G4double ExcitationEnergy(const G4int &ExcLevel, const size_t &materialID)
G4double IonisationEnergy(G4int level, const size_t &materialName)
const G4ThreeVector & GetMomentumDirection() const
G4ParticleDefinition * GetDefinition() const
G4double GetKineticEnergy() const
static G4Electron * ElectronDefinition()
Definition G4Electron.cc:86
static G4Electron * Electron()
Definition G4Electron.cc:91
std::size_t GetIndex() const
const G4String & GetName() const
static G4Material * GetMaterial(const G4String &name, G4bool warning=true)
void SetProposedKineticEnergy(G4double proposedKinEnergy)
void ProposeMomentumDirection(const G4ThreeVector &Pfinal)
const G4String & GetParticleName() const
The G4VDNAModel class.
void LoadCrossSectionData(const G4ParticleDefinition *particleName)
LoadCrossSectionData Method to loop on all the registered materials in the model and load the corresp...
void SetLowELimit(const size_t &materialID, const G4ParticleDefinition *particle, G4double lim)
SetLowEnergyLimit.
void SetHighELimit(const size_t &materialID, const G4ParticleDefinition *particle, G4double lim)
SetHighEnergyLimit.
G4double GetHighELimit(const size_t &materialID, const G4ParticleDefinition *particle)
GetHighEnergyLimit.
G4int RandomSelectShell(const G4double &k, const G4ParticleDefinition *particle, const size_t &materialName)
RandomSelectShell Method to randomely select a shell from the data table uploaded....
void AddCrossSectionData(const size_t &materialName, const G4ParticleDefinition *particleName, const G4String &fileCS, const G4String &fileDiffCS, const G4double &scaleFactor)
AddCrossSectionData Method used during the initialization of the model class to add a new material....
G4double GetLowELimit(const size_t &materialID, const G4ParticleDefinition *particle)
GetLowEnergyLimit.
MaterialParticleMapData * GetData()
GetTableData.
G4bool isInitialised
G4ParticleChangeForGamma * GetParticleChangeForGamma()
G4bool IsLocked() const
const G4Track * GetCurrentTrack() const
void ProposeLocalEnergyDeposit(G4double anEnergyPart)