Geant4 10.7.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4PenelopeIonisationCrossSection.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//
27// Author: Luciano Pandola
28//
29// History:
30// --------
31// 14 Mar 2012 L Pandola First complete implementation for e-
32//
33//
34//! NOTICE: working only for e- at the moment (no interface available for
35//! e+)
36//
38#include "G4SystemOfUnits.hh"
42#include "G4Electron.hh"
44
46 G4VhShellCrossSection("Penelope"),shellIDTable(0),
47 theCrossSectionHandler(0)
48{
50 nMaxLevels = 9;
51
52 // Verbosity scale:
53 // 0 = nothing
54 // 1 = calculation of cross sections, file openings, sampling of atoms
55 // 2 = entering in methods
56 verboseLevel = 0;
57
58 fLowEnergyLimit = 10.0*eV;
59 fHighEnergyLimit = 100.0*GeV;
60
61 transitionManager = G4AtomicTransitionManager::Instance();
62}
63
64//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
65
67{
68 if (theCrossSectionHandler)
69 delete theCrossSectionHandler;
70}
71
72//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
73
76 G4double incidentEnergy,
77 G4double ,
78 const G4Material* material)
79{
80 if (verboseLevel > 1)
81 G4cout << "Entering in method G4PenelopeIonisationCrossSection::CrossSection()" << G4endl;
82
83 G4double cross = 0.;
84
85 //Material pointer is not available
86 if (!material)
87 {
88 //CRASH!
90 ed << "The method has been called with a null G4Material pointer" << G4endl;
91 G4Exception("G4PenelopeIonisationCrossSection::CrossSection()","em2042",
93 return cross;
94 }
95
96 if (!theCrossSectionHandler)
97 theCrossSectionHandler = new G4PenelopeIonisationXSHandler();
98
99 theCrossSectionHandler->BuildXSTable(material,0.,G4Electron::Electron());
100
101 G4int nmax = std::min(nMaxLevels,transitionManager->NumberOfShells(Z));
102
103 if(G4int(shell) < nmax &&
104 incidentEnergy >= fLowEnergyLimit && incidentEnergy <= fHighEnergyLimit)
105 {
106 //The shells in Penelope are organized per *material*, rather than per
107 //element, so given a material one has to find the proper index for the
108 //given Z and shellID. An appropriate lookup table is used to avoid
109 //recalculation.
110 G4int index = FindShellIDIndex(material,Z,shell);
111
112 //Index is not available!
113 if (index < 0)
114 return cross;
115
116 const G4PenelopeCrossSection* theXS =
117 theCrossSectionHandler->GetCrossSectionTableForCouple(G4Electron::Electron(),
118 material,
119 0.);
120
121 //Cross check that everything is fine:
122 G4PenelopeOscillator* theOsc = oscManager->GetOscillatorIonisation(material,index);
123 if (theOsc->GetParentZ() != Z || theOsc->GetShellFlag()-1 != G4int(shell))
124 {
125 //something went wrong!
127 ed << "There is something wrong here: it looks like the index is wrong" << G4endl;
128 ed << "Requested: shell " << G4int(shell) << " and Z = " << Z << G4endl;
129 ed << "Retrieved: " << theOsc->GetShellFlag()-1 << " and Z = " << theOsc->GetParentZ() << G4endl;
130 G4Exception("G4PenelopeIonisationCrossSection::CrossSection()","em2043",
131 JustWarning,ed);
132 return cross;
133 }
134
135
136 G4double crossPerMolecule = (theXS) ? theXS->GetShellCrossSection(index,incidentEnergy) : 0.;
137
138 //Now it must be converted in cross section per atom. I need the number of
139 //atoms of the given Z per molecule.
140 G4double atomsPerMolec = oscManager->GetNumberOfZAtomsPerMolecule(material,Z);
141 if (atomsPerMolec)
142 cross = crossPerMolecule/atomsPerMolec;
143
144
145 if (verboseLevel > 0)
146 {
147 G4cout << "Cross section of shell " << G4int(shell) << " and Z= " << Z;
148 G4cout << " of material: " << material->GetName() << " and energy = " << incidentEnergy/keV << " keV" << G4endl;
149 G4cout << "--> " << cross/barn << " barn" << G4endl;
150 G4cout << "Shell binding energy: " << theOsc->GetIonisationEnergy()/eV << " eV;" ;
151 G4cout << " resonance energy: " << theOsc->GetResonanceEnergy()/eV << "eV" << G4endl;
152 if (verboseLevel > 2)
153 {
154 G4cout << "Cross section per molecule: " << crossPerMolecule/barn << " barn" << G4endl;
155 G4cout << "Atoms " << Z << " per molecule: " << atomsPerMolec << G4endl;
156 }
157 }
158 }
159
160 return cross;
161}
162
163//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
164std::vector<G4double>
166 G4double kinEnergy,
168 const G4Material* mat)
169{
170 G4int nmax = std::min(nMaxLevels,transitionManager->NumberOfShells(Z));
171 std::vector<G4double> vec(nmax,0.0);
172 for(G4int i=0; i<nmax; ++i) {
173 vec[i] = CrossSection(Z, G4AtomicShellEnumerator(i), kinEnergy,0.,mat);
174 }
175 return vec;
176}
177
178//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
179
180std::vector<G4double>
182 G4double kinEnergy,
183 G4double,
184 G4double,
185 const G4Material* mat)
186{
187 std::vector<G4double> vec = GetCrossSection(Z, kinEnergy,0,0,mat);
188 size_t n = vec.size();
189 size_t i=0;
190 G4double sum = 0.0;
191 for(i=0; i<n; ++i) { sum += vec[i]; }
192 if(sum > 0.0) {
193 sum = 1.0/sum;
194 for(i=0; i<n; ++i) { vec[i] = vec[i]*sum; }
195 }
196 return vec;
197}
198
199//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
200
201G4int G4PenelopeIonisationCrossSection::FindShellIDIndex(const G4Material* mat,
202 G4int Z,
204{
205 if (verboseLevel > 1)
206 G4cout << "Entering in method G4PenelopeIonisationCrossSection::FindShellIDIndex()" << G4endl;
207
208 if (!shellIDTable)
209 shellIDTable = new std::map< std::pair<const G4Material*,G4int>, G4DataVector*>;
210
211 std::pair<const G4Material*,G4int> theKey = std::make_pair(mat,Z);
212 G4int result = -1;
213 G4int ishell = G4int(shell);
214
215 if (shellIDTable->count(theKey)) //table already built, and containing the element
216 {
217 if (verboseLevel > 2)
218 G4cout << "FindShellIDIndex: Table already built for " << mat->GetName() << G4endl;
219 G4DataVector* theVec = shellIDTable->find(theKey)->second;
220
221 if (ishell>=0 && ishell < (G4int) theVec->size()) //check we are not off-boundary
222 result = (G4int) (*theVec)[ishell];
223 else
224 {
226 ed << "Shell ID: " << ishell << " not available for material " << mat->GetName() << " and Z = " <<
227 Z << G4endl;
228 G4Exception("G4PenelopeIonisationCrossSection::FindShellIDIndex()","em2041",JustWarning,
229 ed);
230 return -1;
231 }
232 }
233 else
234 {
235 if (verboseLevel > 2)
236 G4cout << "FindShellIDIndex: Table to be built for " << mat->GetName() << G4endl;
237 //Not contained: look for it
238 G4PenelopeOscillatorTable* theTable = oscManager->GetOscillatorTableIonisation(mat);
239 size_t numberOfOscillators = theTable->size();
240
241 //oscillator loop
242 //initialize everything at -1
243 G4DataVector* dat = new G4DataVector(nMaxLevels,-1);
244 for (size_t iosc=0;iosc<numberOfOscillators;iosc++)
245 {
246 G4PenelopeOscillator* theOsc = (*theTable)[iosc];
247 //level is found!
248 if (theOsc->GetParentZ() == Z)
249 {
250 //individual shells relative to the given material
251 G4int shFlag = theOsc->GetShellFlag();
252 //Notice: GetShellFlag() starts from 1, the G4AtomicShellEnumerator from 0
253 if (shFlag < 30)
254 (*dat)[shFlag-1] = (G4double) iosc; //index of the given shell
255 if ((shFlag-1) == ishell) // this is what we were looking for
256 result = (G4int) iosc;
257 }
258 }
259 shellIDTable->insert(std::make_pair(theKey,dat));
260 }
261
262 if (verboseLevel > 1)
263 G4cout << "Leaving method G4PenelopeIonisationCrossSection::FindShellIDIndex() with index = " << result << G4endl;
264
265 return result;
266
267}
G4AtomicShellEnumerator
@ JustWarning
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
std::ostringstream G4ExceptionDescription
Definition: G4Exception.hh:40
std::vector< G4PenelopeOscillator * > G4PenelopeOscillatorTable
double G4double
Definition: G4Types.hh:83
int G4int
Definition: G4Types.hh:85
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
static G4AtomicTransitionManager * Instance()
static G4Electron * Electron()
Definition: G4Electron.cc:93
const G4String & GetName() const
Definition: G4Material.hh:175
G4double GetShellCrossSection(size_t shellID, G4double energy) const
Returns the hard cross section for the given shell (per molecule)
~G4PenelopeIonisationCrossSection()
Destructor. Clean all tables.
std::vector< G4double > GetCrossSection(G4int Z, G4double incidentEnergy, G4double mass, G4double deltaEnergy, const G4Material *mat)
std::vector< G4double > Probabilities(G4int Z, G4double incidentEnergy, G4double mass, G4double deltaEnergy, const G4Material *mat)
G4double CrossSection(G4int Z, G4AtomicShellEnumerator shell, G4double incidentEnergy, G4double mass, const G4Material *mat)
void BuildXSTable(const G4Material *, G4double cut, const G4ParticleDefinition *, G4bool isMaster=true)
This can be inkoved only by the master.
const G4PenelopeCrossSection * GetCrossSectionTableForCouple(const G4ParticleDefinition *, const G4Material *, const G4double cut) const
G4double GetNumberOfZAtomsPerMolecule(const G4Material *, G4int Z)
static G4PenelopeOscillatorManager * GetOscillatorManager()
G4PenelopeOscillatorTable * GetOscillatorTableIonisation(const G4Material *)
G4PenelopeOscillator * GetOscillatorIonisation(const G4Material *, G4int)
G4double GetResonanceEnergy() const