ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4PenelopeIonisationCrossSection.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4PenelopeIonisationCrossSection.cc
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 //
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 
62 }
63 
64 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
65 
67 {
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",
92  FatalException,ed);
93  return cross;
94  }
95 
98 
100 
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 =
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....
164 std::vector<G4double>
166  G4double kinEnergy,
167  G4double, G4double,
168  const G4Material* mat)
169 {
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 
180 std::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 
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
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 }