Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/electromagnetic/lowenergy/src/G4PenelopeIonisationCrossSection.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  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 //
 37 #include "G4PenelopeOscillatorManager.hh"
 38 #include "G4SystemOfUnits.hh"
 39 #include "G4PenelopeIonisationCrossSection.hh"
 40 #include "G4PenelopeIonisationXSHandler.hh"
 41 #include "G4PenelopeCrossSection.hh"
 42 #include "G4Electron.hh"
 43 #include "G4AtomicTransitionManager.hh"
 44 
 45 G4PenelopeIonisationCrossSection::G4PenelopeIonisationCrossSection() : 
 46   G4VhShellCrossSection("Penelope"),fShellIDTable(nullptr),
 47   fCrossSectionHandler(nullptr)
 48 { 
 49   fOscManager = G4PenelopeOscillatorManager::GetOscillatorManager();
 50   fNMaxLevels = 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   fVerboseLevel = 0;
 57 
 58   fLowEnergyLimit  = 10.0*eV;
 59   fHighEnergyLimit = 100.0*GeV;
 60 
 61   fTransitionManager = G4AtomicTransitionManager::Instance();
 62 }
 63 
 64 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 65  
 66 G4PenelopeIonisationCrossSection::~G4PenelopeIonisationCrossSection()
 67 {
 68   if (fCrossSectionHandler)
 69     delete fCrossSectionHandler;
 70 }
 71 
 72 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 73 
 74 G4double G4PenelopeIonisationCrossSection::CrossSection(G4int Z,
 75               G4AtomicShellEnumerator shell,
 76               G4double incidentEnergy,
 77               G4double ,
 78               const G4Material* material)
 79 {
 80   if (fVerboseLevel > 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!
 89       G4ExceptionDescription ed;
 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 
 96   if (!fCrossSectionHandler)
 97     fCrossSectionHandler = new G4PenelopeIonisationXSHandler();
 98 
 99   fCrossSectionHandler->BuildXSTable(material,0.,G4Electron::Electron());
100 
101   G4int nmax = std::min(fNMaxLevels,fTransitionManager->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 fShellID. 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   fCrossSectionHandler->GetCrossSectionTableForCouple(G4Electron::Electron(),
118                     material,
119                     0.);
120 
121       //Cross check that everything is fine:
122       G4PenelopeOscillator* theOsc = fOscManager->GetOscillatorIonisation(material,index);
123       if (theOsc->GetParentZ() != Z || theOsc->GetShellFlag()-1 != G4int(shell))
124   {
125     //something went wrong!
126     G4ExceptionDescription ed;
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       G4double crossPerMolecule = (theXS) ? theXS->GetShellCrossSection(index,incidentEnergy) : 0.;
136 
137       //Now it must be converted in cross section per atom. I need the number of 
138       //atoms of the given Z per molecule.
139       G4double atomsPerMolec = fOscManager->GetNumberOfZAtomsPerMolecule(material,Z);
140       if (atomsPerMolec)
141   cross = crossPerMolecule/atomsPerMolec;
142      
143       if (fVerboseLevel > 0)
144   {
145     G4cout << "Cross section of shell " << G4int(shell) << " and Z= " << Z;
146     G4cout << " of material: " << material->GetName() << " and energy = " << incidentEnergy/keV << " keV" << G4endl;
147     G4cout << "--> " << cross/barn << " barn" << G4endl;
148     G4cout << "Shell binding energy: " << theOsc->GetIonisationEnergy()/eV << " eV;" ;
149     G4cout << " resonance energy: " << theOsc->GetResonanceEnergy()/eV << "eV" << G4endl;
150      if (fVerboseLevel > 2)
151        {
152          G4cout << "Cross section per molecule: " << crossPerMolecule/barn << " barn" << G4endl;
153          G4cout << "Atoms " << Z << " per molecule: " << atomsPerMolec << G4endl;
154        }
155   }     
156     }  
157   
158   return cross;
159 }
160 
161 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
162 std::vector<G4double> 
163 G4PenelopeIonisationCrossSection::GetCrossSection(G4int Z,
164               G4double kinEnergy,
165               G4double, G4double, 
166               const G4Material* mat)
167 {
168   G4int nmax = std::min(fNMaxLevels,fTransitionManager->NumberOfShells(Z));
169   std::vector<G4double> vec(nmax,0.0); 
170   for(G4int i=0; i<nmax; ++i) {
171     vec[i] = CrossSection(Z, G4AtomicShellEnumerator(i), kinEnergy,0.,mat); 
172   }
173   return vec;
174 }
175 
176 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
177 
178 std::vector<G4double> 
179 G4PenelopeIonisationCrossSection::Probabilities(G4int Z,
180                                                  G4double kinEnergy,
181                                                  G4double,
182                                                  G4double,
183                                                  const G4Material* mat)
184 {
185   std::vector<G4double> vec = GetCrossSection(Z, kinEnergy,0,0,mat);
186   size_t n = vec.size();
187   size_t i=0;
188   G4double sum = 0.0;
189   for(i=0; i<n; ++i) { sum += vec[i]; }
190   if(sum > 0.0) { 
191     sum = 1.0/sum; 
192     for(i=0; i<n; ++i) { vec[i] = vec[i]*sum; }
193   }
194   return vec;
195 }
196 
197 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
198 
199 G4int G4PenelopeIonisationCrossSection::FindShellIDIndex(const G4Material* mat,
200                G4int Z,
201                G4AtomicShellEnumerator shell)
202 {
203    if (fVerboseLevel > 1)    
204      G4cout << "Entering in method G4PenelopeIonisationCrossSection::FindShellIDIndex()" << G4endl;
205 
206   if (!fShellIDTable)
207     fShellIDTable = new std::map< std::pair<const G4Material*,G4int>, G4DataVector*>;
208  
209   std::pair<const G4Material*,G4int> theKey = std::make_pair(mat,Z);
210   G4int result = -1;
211   G4int ishell = G4int(shell);
212   
213   if (fShellIDTable->count(theKey)) //table already built, and containing the element
214     {   
215       if (fVerboseLevel > 2)
216   G4cout << "FindShellIDIndex: Table already built for " << mat->GetName() << G4endl;
217       G4DataVector* theVec = fShellIDTable->find(theKey)->second;
218          
219       if (ishell>=0 && ishell < (G4int) theVec->size()) //check we are not off-boundary
220   result = (G4int) (*theVec)[ishell];    
221       else
222   {
223     G4ExceptionDescription ed;
224     ed << "Shell ID: " << ishell << " not available for material " << mat->GetName() << " and Z = " << 
225       Z << G4endl;
226     G4Exception("G4PenelopeIonisationCrossSection::FindShellIDIndex()","em2041",JustWarning,
227           ed);
228     return -1;
229   }          
230     }
231   else
232     {
233       if (fVerboseLevel > 2)
234   G4cout << "FindShellIDIndex: Table to be built for " << mat->GetName() << G4endl;
235       //Not contained: look for it
236       G4PenelopeOscillatorTable* theTable = fOscManager->GetOscillatorTableIonisation(mat);
237       size_t numberOfOscillators = theTable->size();
238           
239       //oscillator loop
240       //initialize everything at -1
241       G4DataVector* dat = new G4DataVector(fNMaxLevels,-1);
242       for (size_t iosc=0;iosc<numberOfOscillators;iosc++)
243   {      
244     G4PenelopeOscillator* theOsc = (*theTable)[iosc];
245     //level is found!
246     if (theOsc->GetParentZ() == Z)
247       {
248         //individual shells relative to the given material      
249         G4int shFlag = theOsc->GetShellFlag();    
250         //Notice: GetShellFlag() starts from 1, the G4AtomicShellEnumerator from 0
251         if (shFlag < 30)
252     (*dat)[shFlag-1] = (G4double) iosc; //index of the given shell
253         if ((shFlag-1) == ishell) // this is what we were looking for
254     result = (G4int) iosc;
255       }      
256   }
257       fShellIDTable->insert(std::make_pair(theKey,dat));
258     }
259 
260   if (fVerboseLevel > 1)    
261     G4cout << "Leaving method G4PenelopeIonisationCrossSection::FindShellIDIndex() with index = " 
262      << result << G4endl;
263 
264   return result;  
265 }
266