Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/electromagnetic/lowenergy/src/G4LivermorePhotoElectricModel.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 ]

Diff markup

Differences between /processes/electromagnetic/lowenergy/src/G4LivermorePhotoElectricModel.cc (Version 11.3.0) and /processes/electromagnetic/lowenergy/src/G4LivermorePhotoElectricModel.cc (Version 9.2.p2)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
                                                   >>  26 // $Id: G4LivermorePhotoElectricModel.cc,v 1.1 2008/10/30 14:16:35 sincerti Exp $
                                                   >>  27 // GEANT4 tag $Name: geant4-09-02-patch-01 $
 26 //                                                 28 //
 27 // Author: Sebastien Incerti                   << 
 28 //         30 October 2008                     << 
 29 //         on base of G4LowEnergyPhotoElectric << 
 30 //                                             << 
 31 // 22 Oct 2012   A & V Ivanchenko Migration da << 
 32 // 1 June 2017   M Bandieramonte: New model ba << 
 33 //               evaluated data - parameteriza << 
 34                                                    29 
 35 #include "G4LivermorePhotoElectricModel.hh"        30 #include "G4LivermorePhotoElectricModel.hh"
 36                                                    31 
 37 #include "G4AtomicShell.hh"                    << 
 38 #include "G4AutoLock.hh"                       << 
 39 #include "G4CrossSectionHandler.hh"            << 
 40 #include "G4Electron.hh"                       << 
 41 #include "G4Gamma.hh"                          << 
 42 #include "G4LossTableManager.hh"               << 
 43 #include "G4ParticleChangeForGamma.hh"         << 
 44 #include "G4PhysicsFreeVector.hh"              << 
 45 #include "G4SauterGavrilaAngularDistribution.h << 
 46 #include "G4SystemOfUnits.hh"                  << 
 47 #include "G4VAtomDeexcitation.hh"              << 
 48 #include "G4EmParameters.hh"                   << 
 49 #include <thread>                              << 
 50                                                << 
 51 //....oooOO0OOooo........oooOO0OOooo........oo     32 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 52                                                    33 
 53 G4ElementData* G4LivermorePhotoElectricModel:: <<  34 using namespace std;
 54 G4ElementData* G4LivermorePhotoElectricModel:: << 
 55 std::vector<G4double>* G4LivermorePhotoElectri << 
 56 std::vector<G4double>* G4LivermorePhotoElectri << 
 57 G4int G4LivermorePhotoElectricModel::fNShells[ << 
 58 G4int G4LivermorePhotoElectricModel::fNShellsU << 
 59 G4Material* G4LivermorePhotoElectricModel::fWa << 
 60 G4double G4LivermorePhotoElectricModel::fWater << 
 61 G4String G4LivermorePhotoElectricModel::fDataD << 
 62                                                << 
 63 static std::once_flag applyOnce;               << 
 64                                                << 
 65 namespace                                      << 
 66 {                                              << 
 67   G4Mutex livPhotoeffMutex = G4MUTEX_INITIALIZ << 
 68 }                                              << 
 69                                                    35 
 70 //....oooOO0OOooo........oooOO0OOooo........oo     36 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 71                                                    37 
 72 G4LivermorePhotoElectricModel::G4LivermorePhot <<  38 G4LivermorePhotoElectricModel::G4LivermorePhotoElectricModel(const G4ParticleDefinition*,
 73 {                                              <<  39                                              const G4String& nam)
 74   verboseLevel = 0;                            <<  40 :G4VEmModel(nam),isInitialised(false)
                                                   >>  41 {
                                                   >>  42   lowEnergyLimit = 250 * eV; // SI - Could be 10 eV ?
                                                   >>  43   highEnergyLimit = 100 * GeV;
                                                   >>  44   SetLowEnergyLimit(lowEnergyLimit);
                                                   >>  45   SetHighEnergyLimit(highEnergyLimit);
                                                   >>  46   
                                                   >>  47   G4cout << "Livermore Compton is constructed " << G4endl
                                                   >>  48          << "Energy range: "
                                                   >>  49          << lowEnergyLimit / keV << " keV - "
                                                   >>  50          << highEnergyLimit / GeV << " GeV"
                                                   >>  51          << G4endl;
                                                   >>  52  
                                                   >>  53   verboseLevel= 0;
 75   // Verbosity scale:                              54   // Verbosity scale:
 76   // 0 = nothing                               <<  55   // 0 = nothing 
 77   // 1 = warning for energy non-conservation   <<  56   // 1 = warning for energy non-conservation 
 78   // 2 = details of energy budget                  57   // 2 = details of energy budget
 79   // 3 = calculation of cross sections, file o     58   // 3 = calculation of cross sections, file openings, sampling of atoms
 80   // 4 = entering in methods                       59   // 4 = entering in methods
 81                                                << 
 82   theGamma = G4Gamma::Gamma();                 << 
 83   theElectron = G4Electron::Electron();        << 
 84                                                << 
 85   // default generator                         << 
 86   SetAngularDistribution(new G4SauterGavrilaAn << 
 87                                                << 
 88   if (verboseLevel > 0) {                      << 
 89     G4cout << "Livermore PhotoElectric is cons << 
 90            << " nShellLimit= " << nShellLimit  << 
 91   }                                            << 
 92                                                << 
 93   // Mark this model as "applicable" for atomi << 
 94   SetDeexcitationFlag(true);                   << 
 95                                                << 
 96   // For water                                 << 
 97   fSandiaCof.resize(4, 0.0);                   << 
 98 }                                                  60 }
 99                                                    61 
100 //....oooOO0OOooo........oooOO0OOooo........oo     62 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
101                                                    63 
102 G4LivermorePhotoElectricModel::~G4LivermorePho     64 G4LivermorePhotoElectricModel::~G4LivermorePhotoElectricModel()
103 {                                              <<  65 {  
104   if (isInitializer) {                         <<  66   delete meanFreePathTable;
105     for (G4int i = 0; i < ZMAXPE; ++i) {       <<  67   delete crossSectionHandler;
106       if (fParamHigh[i]) {                     <<  68   delete shellCrossSectionHandler;
107         delete fParamHigh[i];                  <<  69   delete ElectronAngularGenerator;
108         fParamHigh[i] = nullptr;               << 
109       }                                        << 
110       if (fParamLow[i]) {                      << 
111         delete fParamLow[i];                   << 
112         fParamLow[i] = nullptr;                << 
113       }                                        << 
114     }                                          << 
115   }                                            << 
116 }                                                  70 }
117                                                    71 
118 //....oooOO0OOooo........oooOO0OOooo........oo     72 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
119                                                    73 
120 void G4LivermorePhotoElectricModel::Initialise <<  74 void G4LivermorePhotoElectricModel::Initialise(const G4ParticleDefinition* particle,
121                  const G4DataVector&)          <<  75                                        const G4DataVector& cuts)
122 {                                              <<  76 {
123   if (verboseLevel > 1) {                      <<  77   if (verboseLevel > 3)
124     G4cout << "Calling G4LivermorePhotoElectri <<  78     G4cout << "Calling G4LivermorePhotoElectricModel::Initialise()" << G4endl;
125   }                                            <<  79 
126                                                <<  80   InitialiseElementSelectors(particle,cuts);
127   // initialise static tables only once        <<  81 
128   std::call_once(applyOnce, [this]() { isIniti <<  82   // Energy limits
129                                                <<  83   
130   if (isInitializer) {                         <<  84   if (LowEnergyLimit() < lowEnergyLimit)
131     G4AutoLock l(&livPhotoeffMutex);           <<  85   {
132     FindDirectoryPath();                       <<  86       G4cout << "G4LivermorePhotoElectricModel: low energy limit increased from " <<
133     if (fWater == nullptr) {                   <<  87         LowEnergyLimit()/eV << " eV to " << lowEnergyLimit << " eV" << 
134       fWater = G4Material::GetMaterial("G4_WAT <<  88   G4endl;
135       if (fWater == nullptr) {                 <<  89       SetLowEnergyLimit(lowEnergyLimit);
136         fWater = G4Material::GetMaterial("Wate <<  90   }
137       }                                        <<  91  
138       if (fWater != nullptr) {                 <<  92   if (HighEnergyLimit() > highEnergyLimit)
139         fWaterEnergyLimit = 13.6 * CLHEP::eV;  <<  93   {
140       }                                        <<  94       G4cout << "G4LivermorePhotoElectricModel: high energy limit decreased from " <<
141     }                                          <<  95         HighEnergyLimit()/GeV << " GeV to " << highEnergyLimit << " GeV" 
142                                                <<  96        << G4endl;
143     if (fCrossSection == nullptr) {            <<  97       SetHighEnergyLimit(highEnergyLimit);
144       fCrossSection = new G4ElementData(ZMAXPE <<  98   }
145       fCrossSection->SetName("PhotoEffXS");    <<  99 
146       fCrossSectionLE = new G4ElementData(ZMAX << 100   // Read data tables for all materials
147       fCrossSectionLE->SetName("PhotoEffLowXS" << 101   
148     }                                          << 102   crossSectionHandler = new G4CrossSectionHandler();
149                                                << 103   crossSectionHandler->Clear();
150     const G4ElementTable* elemTable = G4Elemen << 104   G4String crossSectionFile = "phot/pe-cs-";
151     std::size_t numElems = (*elemTable).size() << 105   crossSectionHandler->LoadData(crossSectionFile);
152     for (std::size_t ie = 0; ie < numElems; ++ << 106 
153       const G4Element* elem = (*elemTable)[ie] << 107   meanFreePathTable = 0;
154       G4int Z = elem->GetZasInt();             << 108   meanFreePathTable = crossSectionHandler->BuildMeanFreePathForMaterials();
155       if (Z < ZMAXPE) {                        << 109 
156   if (fCrossSection->GetElementData(Z) == null << 110   shellCrossSectionHandler = new G4CrossSectionHandler();
157     ReadData(Z);                               << 111   shellCrossSectionHandler->Clear();
158   }                                            << 112   G4String shellCrossSectionFile = "phot/pe-ss-cs-";
159       }                                        << 113   shellCrossSectionHandler->LoadShellData(shellCrossSectionFile);
160     }                                          << 114   
161     l.unlock();                                << 115   // SI - Buggy default ?
162   }                                            << 116   //generatorName = "geant4.6.2";
                                                   >> 117   //ElectronAngularGenerator = new G4PhotoElectricAngularGeneratorSimple("GEANTSimpleGenerator");              // default generator
                                                   >> 118 
                                                   >> 119   //
                                                   >> 120   
                                                   >> 121   if (verboseLevel > 2) 
                                                   >> 122     G4cout << "Loaded cross section files for Livermore PhotoElectric model" << G4endl;
                                                   >> 123 
                                                   >> 124   G4cout << "Livermore PhotoElectric model is initialized " << G4endl
                                                   >> 125          << "Energy range: "
                                                   >> 126          << LowEnergyLimit() / keV << " keV - "
                                                   >> 127          << HighEnergyLimit() / GeV << " GeV"
                                                   >> 128          << G4endl;
163                                                   129 
164   if (verboseLevel > 1) {                      << 130   if(isInitialised) return;
165     G4cout << "Loaded cross section files for  << 
166   }                                            << 
167   if (nullptr == fParticleChange) {            << 
168     fParticleChange = GetParticleChangeForGamm << 
169     fAtomDeexcitation = G4LossTableManager::In << 
170   }                                            << 
171                                                   131 
172   fDeexcitationActive = false;                 << 132   if(pParticleChange)
173   if (nullptr != fAtomDeexcitation) {          << 133     fParticleChange = reinterpret_cast<G4ParticleChangeForGamma*>(pParticleChange);
174     fDeexcitationActive = fAtomDeexcitation->I << 134   else
175   }                                            << 135     fParticleChange = new G4ParticleChangeForGamma();
176                                                   136 
177   if (verboseLevel > 1) {                      << 137   isInitialised = true;
178     G4cout << "LivermorePhotoElectric model is << 
179   }                                            << 
180 }                                                 138 }
181                                                   139 
182 //....oooOO0OOooo........oooOO0OOooo........oo    140 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
183                                                   141 
184 G4double                                       << 142 G4double G4LivermorePhotoElectricModel::ComputeCrossSectionPerAtom(
185 G4LivermorePhotoElectricModel::CrossSectionPer << 143                                        const G4ParticleDefinition*,
186                                                << 144                                              G4double GammaEnergy,
187                                                << 145                                              G4double Z, G4double,
188                  G4double, G4double)           << 146                                              G4double, G4double)
189 {                                                 147 {
190   fCurrSection = 0.0;                          << 148   if (verboseLevel > 3)
191   if (fWater && (material == fWater || materia << 149     G4cout << "Calling ComputeCrossSectionPerAtom() of G4LivermorePhotoElectricModel" << G4endl;
192     if (energy <= fWaterEnergyLimit) {         << 
193       fWater->GetSandiaTable()->GetSandiaCofWa << 
194                                                << 
195       G4double energy2 = energy * energy;      << 
196       G4double energy3 = energy * energy2;     << 
197       G4double energy4 = energy2 * energy2;    << 
198                                                << 
199       fCurrSection = material->GetDensity()    << 
200                      * (fSandiaCof[0] / energy << 
201       fSandiaCof[2] / energy3 + fSandiaCof[3]  << 
202     }                                          << 
203   }                                            << 
204   if (0.0 == fCurrSection) {                   << 
205     fCurrSection = G4VEmModel::CrossSectionPer << 
206   }                                            << 
207   return fCurrSection;                         << 
208 }                                              << 
209                                                << 
210 //....oooOO0OOooo........oooOO0OOooo........oo << 
211                                                   150 
212 G4double                                       << 151   G4double cs = crossSectionHandler->FindValue(G4int(Z), GammaEnergy);
213 G4LivermorePhotoElectricModel::ComputeCrossSec << 
214                                                << 
215                 G4double ZZ, G4double,         << 
216                 G4double, G4double)            << 
217 {                                              << 
218   if (verboseLevel > 3) {                      << 
219     G4cout << "\n G4LivermorePhotoElectricMode << 
220            << " Z= " << ZZ << "  R(keV)= " <<  << 
221   }                                            << 
222   G4double cs = 0.0;                           << 
223   G4int Z = G4lrint(ZZ);                       << 
224   if (Z >= ZMAXPE || Z <= 0) {                 << 
225     return cs;                                 << 
226   }                                            << 
227   // if element was not initialised            << 
228                                                << 
229   // do initialisation safely for MT mode      << 
230   if (fCrossSection->GetElementData(Z) == null << 
231     InitialiseOnFly(Z);                        << 
232     if (fCrossSection->GetElementData(Z) == nu << 
233   }                                            << 
234                                                << 
235   // 7: rows in the parameterization file; 5:  << 
236   G4int idx = fNShells[Z] * 7 - 5;             << 
237                                                << 
238   energy = std::max(energy, (*(fParamHigh[Z])) << 
239                                                << 
240   G4double x1 = 1.0 / energy;                  << 
241   G4double x2 = x1 * x1;                       << 
242   G4double x3 = x2 * x1;                       << 
243                                                << 
244   // high energy parameterisation              << 
245   if (energy >= (*(fParamHigh[Z]))[0]) {       << 
246     G4double x4 = x2 * x2;                     << 
247     G4double x5 = x4 * x1;                     << 
248                                                << 
249     cs = x1 *                                  << 
250       ((*(fParamHigh[Z]))[idx] + x1 * (*(fPara << 
251        + x2 * (*(fParamHigh[Z]))[idx + 2] + x3 << 
252        + x4 * (*(fParamHigh[Z]))[idx + 4] + x5 << 
253   }                                            << 
254   // low energy parameterisation               << 
255   else if (energy >= (*(fParamLow[Z]))[0]) {   << 
256     G4double x4 = x2 * x2;                     << 
257     G4double x5 = x4 * x1;  // this variable u << 
258     cs = x1 *                                  << 
259       ((*(fParamLow[Z]))[idx] + x1 * (*(fParam << 
260        + x2 * (*(fParamLow[Z]))[idx + 2] + x3  << 
261        + x4 * (*(fParamLow[Z]))[idx + 4] + x5  << 
262   }                                            << 
263   // Tabulated values above k-shell ionization << 
264   else if (energy >= (*(fParamHigh[Z]))[1]) {  << 
265     cs = x3 * (fCrossSection->GetElementData(Z << 
266   }                                            << 
267   // Tabulated values below k-shell ionization << 
268   else {                                       << 
269     cs = x3 * (fCrossSectionLE->GetElementData << 
270   }                                            << 
271   if (verboseLevel > 1) {                      << 
272     G4cout << "G4LivermorePhotoElectricModel:  << 
273            << " cross(barn)= " << cs / barn << << 
274   }                                            << 
275   return cs;                                      152   return cs;
276 }                                                 153 }
277                                                   154 
278 //....oooOO0OOooo........oooOO0OOooo........oo    155 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
279                                                   156 
280 void G4LivermorePhotoElectricModel::SampleSeco    157 void G4LivermorePhotoElectricModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
281                                                << 158                 const G4MaterialCutsCouple* couple,
282                                                << 159                 const G4DynamicParticle* aDynamicGamma,
283                                                << 160                 G4double,
284 {                                              << 161                 G4double)
285   G4double gammaEnergy = aDynamicGamma->GetKin << 162 {
286   if (verboseLevel > 3) {                      << 163 
287     G4cout << "G4LivermorePhotoElectricModel:: << 164   // Fluorescence generated according to:
288            << gammaEnergy / keV << G4endl;     << 165   // J. Stepanek ,"A program to determine the radiation spectra due to a single atomic
289   }                                            << 166   // subshell ionisation by a particle or due to deexcitation or decay of radionuclides", 
290                                                << 167   // Comp. Phys. Comm. 1206 pp 1-1-9 (1997)
291   // kill incident photon                      << 168  
292   fParticleChange->ProposeTrackStatus(fStopAnd << 169   if (verboseLevel > 3)
293   fParticleChange->SetProposedKineticEnergy(0. << 170     G4cout << "Calling SampleSecondaries() of G4LivermorePhotoElectricModel" << G4endl;
294                                                << 171 
295   // low-energy photo-effect in water - full a << 172   G4double photonEnergy = aDynamicGamma->GetKineticEnergy();
296   const G4Material* material = couple->GetMate << 173   
297   if (fWater && (material == fWater || materia << 174   if (photonEnergy <= lowEnergyLimit)
298     if (gammaEnergy <= fWaterEnergyLimit) {    << 175     {
299       fParticleChange->ProposeLocalEnergyDepos << 176       fParticleChange->ProposeTrackStatus(fStopAndKill);
300       return;                                  << 177       fParticleChange->SetProposedKineticEnergy(0.);
                                                   >> 178       fParticleChange->ProposeLocalEnergyDeposit(photonEnergy);
                                                   >> 179       // SI - IS THE FOLLOWING RETURN NECESSARY ?
                                                   >> 180       return ;
301     }                                             181     }
302   }                                            << 182  
303                                                << 183   G4ThreeVector photonDirection = aDynamicGamma->GetMomentumDirection(); // Returns the normalized direction of the momentum
304   // Returns the normalized direction of the m << 
305   G4ThreeVector photonDirection = aDynamicGamm << 
306                                                   184 
307   // Select randomly one element in the curren    185   // Select randomly one element in the current material
308   const G4Element* elm = SelectRandomAtom(mate << 186   G4int Z = crossSectionHandler->SelectRandomAtom(couple,photonEnergy);
309   G4int Z = elm->GetZasInt();                  << 
310                                                   187 
311   // Select the ionised shell in the current a << 188   // Select the ionised shell in the current atom according to shell cross sections
312   // cross sections                            << 189   size_t shellIndex = shellCrossSectionHandler->SelectRandomShell(Z,photonEnergy);
313                                                   190 
314   // If element was not initialised gamma shou << 191   // Retrieve the corresponding identifier and binding energy of the selected shell
315   if (Z >= ZMAXPE || fCrossSection->GetElement << 192   const G4AtomicTransitionManager* transitionManager = G4AtomicTransitionManager::Instance();
316     fParticleChange->ProposeLocalEnergyDeposit << 193   const G4AtomicShell* shell = transitionManager->Shell(Z,shellIndex);
317     return;                                    << 194   G4double bindingEnergy = shell->BindingEnergy();
318   }                                            << 195   G4int shellId = shell->ShellId();
                                                   >> 196 
                                                   >> 197   // Create lists of pointers to DynamicParticles (photons and electrons)
                                                   >> 198   // (Is the electron vector necessary? To be checked)
                                                   >> 199   std::vector<G4DynamicParticle*>* photonVector = 0;
                                                   >> 200   std::vector<G4DynamicParticle*> electronVector;
319                                                   201 
320   // SAMPLING OF THE SHELL INDEX               << 202   G4double energyDeposit = 0.0;
321   std::size_t shellIdx = 0;                    << 203 
322   std::size_t nn = fNShellsUsed[Z];            << 204   // Primary outcoming electron
323   if (nn > 1) {                                << 205   G4double eKineticEnergy = photonEnergy - bindingEnergy;
324     if (gammaEnergy >= (*(fParamHigh[Z]))[0])  << 206 
325       G4double x1 = 1.0 / gammaEnergy;         << 207   // There may be cases where the binding energy of the selected shell is > photon energy
326       G4double x2 = x1 * x1;                   << 208   // In such cases do not generate secondaries
327       G4double x3 = x2 * x1;                   << 209   if (eKineticEnergy > 0.)
328       G4double x4 = x3 * x1;                   << 210     {
329       G4double x5 = x4 * x1;                   << 211       // SI - Removed safety
330       std::size_t idx = nn * 7 - 5;            << 212       
331       // when do sampling common factors are n << 213       // Generate the electron only if with large enough range w.r.t. cuts and safety
332       // so cross section is not real          << 214       //G4double safety = aStep.GetPostStepPoint()->GetSafety();
333                                                << 215 
334       G4double rand = G4UniformRand();         << 216       //if (rangeTest->Escape(G4Electron::Electron(),couple,eKineticEnergy,safety))
335       G4double cs0 = rand *                    << 217   {
336         ((*(fParamHigh[Z]))[idx] + x1 * (*(fPa << 218 
337         + x2 * (*(fParamHigh[Z]))[idx + 2] + x << 219     // Calculate direction of the photoelectron
338         + x4 * (*(fParamHigh[Z]))[idx + 4] + x << 220     G4ThreeVector gammaPolarization = aDynamicGamma->GetPolarization();
339                                                << 221     G4ThreeVector electronDirection = ElectronAngularGenerator->GetPhotoElectronDirection(photonDirection,eKineticEnergy,gammaPolarization,shellId);
340       for (shellIdx = 0; shellIdx < nn; ++shel << 222 
341         idx = shellIdx * 7 + 2;                << 223     // The electron is created ...
342         if (gammaEnergy > (*(fParamHigh[Z]))[i << 224     G4DynamicParticle* electron = new G4DynamicParticle (G4Electron::Electron(),
343           G4double cs = (*(fParamHigh[Z]))[idx << 225                      electronDirection,
344             + x2 * (*(fParamHigh[Z]))[idx + 2] << 226                      eKineticEnergy);
345             + x4 * (*(fParamHigh[Z]))[idx + 4] << 227     electronVector.push_back(electron);
346                                                << 228   }
347           if (cs >= cs0) {                     << 229       /*else
348             break;                             << 230   {
349           }                                    << 231     energyDeposit += eKineticEnergy;
350         }                                      << 232   }*/
351       }                                        << 233     }
352       if (shellIdx >= nn) {                    << 234   else
353         shellIdx = nn - 1;                     << 235     {
354       }                                        << 236       bindingEnergy = photonEnergy;
                                                   >> 237     }
                                                   >> 238 
                                                   >> 239   G4int nElectrons = electronVector.size();
                                                   >> 240   size_t nTotPhotons = 0;
                                                   >> 241   G4int nPhotons=0;
                                                   >> 242   const G4ProductionCutsTable* theCoupleTable=
                                                   >> 243         G4ProductionCutsTable::GetProductionCutsTable();
                                                   >> 244 
                                                   >> 245   size_t index = couple->GetIndex();
                                                   >> 246   G4double cutg = (*(theCoupleTable->GetEnergyCutsVector(0)))[index];
                                                   >> 247   cutg = std::min(cutForLowEnergySecondaryPhotons,cutg);
                                                   >> 248   
                                                   >> 249   G4double cute = (*(theCoupleTable->GetEnergyCutsVector(1)))[index];
                                                   >> 250   cute = std::min(cutForLowEnergySecondaryPhotons,cute);
                                                   >> 251 
                                                   >> 252   G4DynamicParticle* aPhoton;
                                                   >> 253 
                                                   >> 254   // Generation of fluorescence
                                                   >> 255   // Data in EADL are available only for Z > 5
                                                   >> 256   // Protection to avoid generating photons in the unphysical case of
                                                   >> 257   // shell binding energy > photon energy
                                                   >> 258   if (Z > 5  && (bindingEnergy > cutg || bindingEnergy > cute))
                                                   >> 259     {
                                                   >> 260       photonVector = deexcitationManager.GenerateParticles(Z,shellId);
                                                   >> 261       nTotPhotons = photonVector->size();
                                                   >> 262       for (size_t k=0; k<nTotPhotons; k++)
                                                   >> 263   {
                                                   >> 264     aPhoton = (*photonVector)[k];
                                                   >> 265     if (aPhoton)
                                                   >> 266       {
                                                   >> 267               G4double itsCut = cutg;
                                                   >> 268               if(aPhoton->GetDefinition() == G4Electron::Electron()) itsCut = cute;
                                                   >> 269         G4double itsEnergy = aPhoton->GetKineticEnergy();
                                                   >> 270 
                                                   >> 271         if (itsEnergy > itsCut && itsEnergy <= bindingEnergy)
                                                   >> 272     {
                                                   >> 273       nPhotons++;
                                                   >> 274       // Local energy deposit is given as the sum of the
                                                   >> 275       // energies of incident photons minus the energies
                                                   >> 276       // of the outcoming fluorescence photons
                                                   >> 277       bindingEnergy -= itsEnergy;
                                                   >> 278 
                                                   >> 279     }
                                                   >> 280         else
                                                   >> 281     {
                                                   >> 282                   delete aPhoton;
                                                   >> 283                   (*photonVector)[k] = 0;
                                                   >> 284                 }
                                                   >> 285       }
                                                   >> 286   }
355     }                                             287     }
356     else if (gammaEnergy >= (*(fParamLow[Z]))[ << 288 
357       G4double x1 = 1.0 / gammaEnergy;         << 289   energyDeposit += bindingEnergy;
358       G4double x2 = x1 * x1;                   << 290 
359       G4double x3 = x2 * x1;                   << 291   // Final state
360       G4double x4 = x3 * x1;                   << 292   
361       G4double x5 = x4 * x1;                   << 293   for (G4int l = 0; l<nElectrons; l++ )
362       std::size_t idx = nn * 7 - 5;            << 294     {
363       // when do sampling common factors are n << 295       aPhoton = electronVector[l];
364       // so cross section is not real          << 296       if(aPhoton) {
365       G4double cs0 = G4UniformRand() *         << 297         fvect->push_back(aPhoton);
366         ((*(fParamLow[Z]))[idx] + x1 * (*(fPar << 
367         + x2 * (*(fParamLow[Z]))[idx + 2] + x3 << 
368         + x4 * (*(fParamLow[Z]))[idx + 4] + x5 << 
369       for (shellIdx = 0; shellIdx < nn; ++shel << 
370         idx = shellIdx * 7 + 2;                << 
371         if (gammaEnergy > (*(fParamLow[Z]))[id << 
372           G4double cs = (*(fParamLow[Z]))[idx] << 
373             + x2 * (*(fParamLow[Z]))[idx + 2]  << 
374             + x4 * (*(fParamLow[Z]))[idx + 4]  << 
375           if (cs >= cs0) {                     << 
376             break;                             << 
377           }                                    << 
378         }                                      << 
379       }                                        << 
380       if (shellIdx >= nn) {                    << 
381         shellIdx = nn - 1;                     << 
382       }                                           298       }
383     }                                             299     }
384     else {                                     << 300   for ( size_t ll = 0; ll < nTotPhotons; ll++)
385       // when do sampling common factors are n << 301     {
386       // so cross section is not real          << 302       aPhoton = (*photonVector)[ll];
387       G4double cs = G4UniformRand();           << 303       if(aPhoton) {
388                                                << 304         fvect->push_back(aPhoton);
389       if (gammaEnergy >= (*(fParamHigh[Z]))[1] << 
390         // above K-shell binding energy        << 
391         cs *= fCrossSection->GetElementData(Z) << 
392       }                                        << 
393       else {                                   << 
394         // below K-shell binding energy        << 
395         cs *= fCrossSectionLE->GetElementData( << 
396       }                                        << 
397                                                << 
398       for (G4int j = 0; j < (G4int)nn; ++j) {  << 
399         shellIdx = (std::size_t)fCrossSection- << 
400         if (gammaEnergy > (*(fParamLow[Z]))[7  << 
401           cs -= fCrossSection->GetValueForComp << 
402         }                                      << 
403         if (cs <= 0.0 || j + 1 == (G4int)nn) { << 
404           break;                               << 
405         }                                      << 
406       }                                           305       }
407     }                                             306     }
408   }                                            << 
409   // END: SAMPLING OF THE SHELL                << 
410                                                << 
411   G4double bindingEnergy = (*(fParamHigh[Z]))[ << 
412   const G4AtomicShell* shell = nullptr;        << 
413                                                << 
414   // no de-excitation from the last shell      << 
415   if (fDeexcitationActive && shellIdx + 1 < nn << 
416     auto as = G4AtomicShellEnumerator(shellIdx << 
417     shell = fAtomDeexcitation->GetAtomicShell( << 
418   }                                            << 
419                                                   307 
420   // If binding energy of the selected shell i << 308   delete photonVector;
421   //    do not generate secondaries            << 
422   if (gammaEnergy < bindingEnergy) {           << 
423     fParticleChange->ProposeLocalEnergyDeposit << 
424     return;                                    << 
425   }                                            << 
426                                                   309 
427   // Primary outcoming electron                << 310   if (energyDeposit < 0)
428   G4double eKineticEnergy = gammaEnergy - bind << 311     {
429   G4double edep = bindingEnergy;               << 312       G4cout << "WARNING - "
430                                                << 313        << "G4LowEnergyPhotoElectric::PostStepDoIt - Negative energy deposit"
431   // Calculate direction of the photoelectron  << 314        << G4endl;
432   G4ThreeVector electronDirection = GetAngular << 315       energyDeposit = 0;
433     aDynamicGamma, eKineticEnergy, (G4int)shel << 
434                                                << 
435   // The electron is created                   << 
436   auto electron =                              << 
437     new G4DynamicParticle(theElectron, electro << 
438   fvect->push_back(electron);                  << 
439                                                << 
440   // Sample deexcitation                       << 
441   if (nullptr != shell) {                      << 
442     G4int index = couple->GetIndex();          << 
443     if (fAtomDeexcitation->CheckDeexcitationAc << 
444       std::size_t nbefore = fvect->size();     << 
445                                                << 
446       fAtomDeexcitation->GenerateParticles(fve << 
447       std::size_t nafter = fvect->size();      << 
448       if (nafter > nbefore) {                  << 
449         G4double esec = 0.0;                   << 
450         for (std::size_t j = nbefore; j < naft << 
451           G4double e = ((*fvect)[j])->GetKinet << 
452           if (esec + e > edep) {               << 
453             // correct energy in order to have << 
454             e = edep - esec;                   << 
455             ((*fvect)[j])->SetKineticEnergy(e) << 
456             esec += e;                         << 
457             // delete the rest of secondaries  << 
458             for (std::size_t jj = nafter - 1;  << 
459               delete (*fvect)[jj];             << 
460               fvect->pop_back();               << 
461             }                                  << 
462             break;                             << 
463           }                                    << 
464           esec += e;                           << 
465         }                                      << 
466         edep -= esec;                          << 
467       }                                        << 
468     }                                             316     }
469   }                                            << 317 
470   // energy balance - excitation energy left   << 318   // kill incident photon
471   if (edep > 0.0) {                            << 319   fParticleChange->ProposeMomentumDirection( 0., 0., 0. );
472     fParticleChange->ProposeLocalEnergyDeposit << 320   fParticleChange->SetProposedKineticEnergy(0.);
473   }                                            << 321   fParticleChange->ProposeTrackStatus(fStopAndKill);   
                                                   >> 322   fParticleChange->ProposeLocalEnergyDeposit(energyDeposit);
474 }                                                 323 }
475                                                   324 
476 //....oooOO0OOooo........oooOO0OOooo........oo    325 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
477                                                   326 
478 const G4String& G4LivermorePhotoElectricModel: << 327 void G4LivermorePhotoElectricModel::SetCutForLowEnSecPhotons(G4double cut)
479 {                                                 328 {
480   // no check in this method - environment var << 329   cutForLowEnergySecondaryPhotons = cut;
481   if (fDataDirectory.empty()) {                << 330   deexcitationManager.SetCutForSecondaryPhotons(cut);
482     auto param = G4EmParameters::Instance();   << 
483     std::ostringstream ost;                    << 
484     if (param->LivermoreDataDir() == "livermor << 
485       ost << param->GetDirLEDATA() << "/liverm << 
486     }                                          << 
487     else {                                     << 
488       ost << param->GetDirLEDATA() << "/epics2 << 
489     }                                          << 
490     fDataDirectory = ost.str();                << 
491   }                                            << 
492   return fDataDirectory;                       << 
493 }                                                 331 }
494                                                   332 
495 //....oooOO0OOooo........oooOO0OOooo........oo    333 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
496                                                   334 
497 void G4LivermorePhotoElectricModel::ReadData(G << 335 void G4LivermorePhotoElectricModel::SetCutForLowEnSecElectrons(G4double cut)
498 {                                                 336 {
499   if (Z <= 0 || Z >= ZMAXPE) {                 << 337   cutForLowEnergySecondaryElectrons = cut;
500     G4cout << "G4LivermorePhotoElectricModel:: << 338   deexcitationManager.SetCutForAugerElectrons(cut);
501      << Z << " is out of range - request ignor << 339 }
502     return;                                    << 
503   }                                            << 
504   if (verboseLevel > 1) {                      << 
505     G4cout << "G4LivermorePhotoElectricModel:: << 
506   }                                            << 
507                                                   340 
508   if (fCrossSection->GetElementData(Z) != null << 341 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
509     return;                                    << 
510   }                                            << 
511                                                   342 
512   // spline for photoeffect total x-section ab << 343 void G4LivermorePhotoElectricModel::ActivateAuger(G4bool val)
513   // but below the parameterized ones          << 344 {
                                                   >> 345   deexcitationManager.ActivateAugerElectronProduction(val);
                                                   >> 346 }
514                                                   347 
515   G4bool spline = (G4EmParameters::Instance()- << 348 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
516   G4int number = G4EmParameters::Instance()->N << 
517   auto pv = new G4PhysicsFreeVector(spline);   << 
518                                                << 
519   // fDataDirectory will be defined after thes << 
520   std::ostringstream ost;                      << 
521   ost << FindDirectoryPath() << "pe-cs-" << Z  << 
522   std::ifstream fin(ost.str().c_str());        << 
523   if (!fin.is_open()) {                        << 
524     G4ExceptionDescription ed;                 << 
525     ed << "G4LivermorePhotoElectricModel data  << 
526        << ost.str().c_str() << "> is not opene << 
527     G4Exception("G4LivermorePhotoElectricModel << 
528                 "G4LEDATA version should be G4 << 
529     return;                                    << 
530   }                                            << 
531   if (verboseLevel > 3) {                      << 
532     G4cout << "File " << ost.str().c_str() <<  << 
533            << G4endl;                          << 
534   }                                            << 
535   pv->Retrieve(fin, true);                     << 
536   pv->ScaleVector(MeV, barn);                  << 
537   pv->FillSecondDerivatives();                 << 
538   pv->EnableLogBinSearch(number);              << 
539   fCrossSection->InitialiseForElement(Z, pv);  << 
540   fin.close();                                 << 
541                                                << 
542   // read high-energy fit parameters           << 
543   fParamHigh[Z] = new std::vector<G4double>;   << 
544   G4int n1 = 0;                                << 
545   G4int n2 = 0;                                << 
546   G4double x;                                  << 
547   std::ostringstream ost1;                     << 
548   ost1 << fDataDirectory << "pe-high-" << Z << << 
549   std::ifstream fin1(ost1.str().c_str());      << 
550   if (!fin1.is_open()) {                       << 
551     G4ExceptionDescription ed;                 << 
552     ed << "G4LivermorePhotoElectricModel data  << 
553        << ost1.str().c_str() << "> is not open << 
554     G4Exception("G4LivermorePhotoElectricModel << 
555                 "G4LEDATA version should be G4 << 
556     return;                                    << 
557   }                                            << 
558   if (verboseLevel > 3) {                      << 
559     G4cout << "File " << ost1.str().c_str() << << 
560            << G4endl;                          << 
561   }                                            << 
562   fin1 >> n1;                                  << 
563   if (fin1.fail()) {                           << 
564     return;                                    << 
565   }                                            << 
566   if (0 > n1 || n1 >= INT_MAX) {               << 
567     n1 = 0;                                    << 
568   }                                            << 
569                                                   349 
570   fin1 >> n2;                                  << 350 void G4LivermorePhotoElectricModel::SetAngularGenerator(G4VPhotoElectricAngularDistribution* distribution)
571   if (fin1.fail()) {                           << 351 {
572     return;                                    << 352   ElectronAngularGenerator = distribution;
573   }                                            << 353   ElectronAngularGenerator->PrintGeneratorInformation();
574   if (0 > n2 || n2 >= INT_MAX) {               << 354 }
575     n2 = 0;                                    << 
576   }                                            << 
577                                                   355 
578   fin1 >> x;                                   << 356 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
579   if (fin1.fail()) {                           << 
580     return;                                    << 
581   }                                            << 
582                                                   357 
583   fNShells[Z] = n1;                            << 358 void G4LivermorePhotoElectricModel::SetAngularGenerator(const G4String& name)
584   fParamHigh[Z]->reserve(7 * n1 + 1);          << 359 {
585   fParamHigh[Z]->push_back(x * MeV);           << 360   if (name == "default") 
586   for (G4int i = 0; i < n1; ++i) {             << 361     {
587     for (G4int j = 0; j < 7; ++j) {            << 362       delete ElectronAngularGenerator;
588       fin1 >> x;                               << 363       ElectronAngularGenerator = new G4PhotoElectricAngularGeneratorSimple("GEANT4LowEnergySimpleGenerator");
589       if (0 == j) {                            << 364       generatorName = name;
590         x *= MeV;                              << 
591       }                                        << 
592       else {                                   << 
593         x *= barn;                             << 
594       }                                        << 
595       fParamHigh[Z]->push_back(x);             << 
596     }                                             365     }
597   }                                            << 366   else if (name == "standard")
598   fin1.close();                                << 367     {
599                                                << 368       delete ElectronAngularGenerator;
600   // read low-energy fit parameters            << 369       ElectronAngularGenerator = new G4PhotoElectricAngularGeneratorSauterGavrila("GEANT4SauterGavrilaGenerator");
601   fParamLow[Z] = new std::vector<G4double>;    << 370       generatorName = name;
602   G4int n1_low = 0;                            << 
603   G4int n2_low = 0;                            << 
604   G4double x_low;                              << 
605   std::ostringstream ost1_low;                 << 
606   ost1_low << fDataDirectory << "pe-low-" << Z << 
607   std::ifstream fin1_low(ost1_low.str().c_str( << 
608   if (!fin1_low.is_open()) {                   << 
609     G4ExceptionDescription ed;                 << 
610     ed << "G4LivermorePhotoElectricModel data  << 
611        << "> is not opened!" << G4endl;        << 
612     G4Exception("G4LivermorePhotoElectricModel << 
613                 "G4LEDATA version should be G4 << 
614     return;                                    << 
615   }                                            << 
616   if (verboseLevel > 3) {                      << 
617     G4cout << "File " << ost1_low.str().c_str( << 
618            << G4endl;                          << 
619   }                                            << 
620   fin1_low >> n1_low;                          << 
621   if (fin1_low.fail()) {                       << 
622     return;                                    << 
623   }                                            << 
624   if (0 > n1_low || n1_low >= INT_MAX) {       << 
625     n1_low = 0;                                << 
626   }                                            << 
627                                                << 
628   fin1_low >> n2_low;                          << 
629   if (fin1_low.fail()) {                       << 
630     return;                                    << 
631   }                                            << 
632   if (0 > n2_low || n2_low >= INT_MAX) {       << 
633     n2_low = 0;                                << 
634   }                                            << 
635                                                << 
636   fin1_low >> x_low;                           << 
637   if (fin1_low.fail()) {                       << 
638     return;                                    << 
639   }                                            << 
640                                                << 
641   fNShells[Z] = n1_low;                        << 
642   fParamLow[Z]->reserve(7 * n1_low + 1);       << 
643   fParamLow[Z]->push_back(x_low * MeV);        << 
644   for (G4int i = 0; i < n1_low; ++i) {         << 
645     for (G4int j = 0; j < 7; ++j) {            << 
646       fin1_low >> x_low;                       << 
647       if (0 == j) {                            << 
648         x_low *= MeV;                          << 
649       }                                        << 
650       else {                                   << 
651         x_low *= barn;                         << 
652       }                                        << 
653       fParamLow[Z]->push_back(x_low);          << 
654     }                                             371     }
655   }                                            << 372   else if (name == "polarized")
656   fin1_low.close();                            << 373     {
657                                                << 374       delete ElectronAngularGenerator;
658   // there is a possibility to use only main s << 375       ElectronAngularGenerator = new G4PhotoElectricAngularGeneratorPolarized("GEANT4LowEnergyPolarizedGenerator");
659   if (nShellLimit < n2) {                      << 376       generatorName = name;
660     n2 = nShellLimit;                          << 377     }
661   }                                            << 378   else
662   fCrossSection->InitialiseForComponent(Z, n2) << 379     {
663   fNShellsUsed[Z] = n2;                        << 380       G4Exception("G4LowEnergyPhotoElectric::SetAngularGenerator - generator does not exist");
664                                                << 
665   if (1 < n2) {                                << 
666     std::ostringstream ost2;                   << 
667     ost2 << fDataDirectory << "pe-ss-cs-" << Z << 
668     std::ifstream fin2(ost2.str().c_str());    << 
669     if (!fin2.is_open()) {                     << 
670       G4ExceptionDescription ed;               << 
671       ed << "G4LivermorePhotoElectricModel dat << 
672          << G4endl;                            << 
673       G4Exception("G4LivermorePhotoElectricMod << 
674                   "G4LEDATA version should be  << 
675       return;                                  << 
676     }                                          << 
677     if (verboseLevel > 3) {                    << 
678       G4cout << "File " << ost2.str().c_str()  << 
679              << G4endl;                        << 
680     }                                          << 
681                                                << 
682     G4int n3, n4;                              << 
683     G4double y;                                << 
684     for (G4int i = 0; i < n2; ++i) {           << 
685       fin2 >> x >> y >> n3 >> n4;              << 
686       auto v = new G4PhysicsFreeVector(n3, x,  << 
687       for (G4int j = 0; j < n3; ++j) {         << 
688         fin2 >> x >> y;                        << 
689         v->PutValues(j, x * CLHEP::MeV, y * CL << 
690       }                                        << 
691       v->EnableLogBinSearch(number);           << 
692       fCrossSection->AddComponent(Z, n4, v);   << 
693     }                                             381     }
694     fin2.close();                              << 
695   }                                            << 
696                                                   382 
697   // no spline for photoeffect total x-section << 383   ElectronAngularGenerator->PrintGeneratorInformation();
698   if (1 < fNShells[Z]) {                       << 
699     auto pv1 = new G4PhysicsFreeVector(false); << 
700     std::ostringstream ost3;                   << 
701     ost3 << fDataDirectory << "pe-le-cs-" << Z << 
702     std::ifstream fin3(ost3.str().c_str());    << 
703     if (!fin3.is_open()) {                     << 
704       G4ExceptionDescription ed;               << 
705       ed << "G4LivermorePhotoElectricModel dat << 
706          << G4endl;                            << 
707       G4Exception("G4LivermorePhotoElectricMod << 
708                   "G4LEDATA version should be  << 
709       return;                                  << 
710     }                                          << 
711     if (verboseLevel > 3) {                    << 
712       G4cout << "File " << ost3.str().c_str()  << 
713              << G4endl;                        << 
714     }                                          << 
715     pv1->Retrieve(fin3, true);                 << 
716     pv1->ScaleVector(CLHEP::MeV, CLHEP::barn); << 
717     pv1->EnableLogBinSearch(number);           << 
718     fCrossSectionLE->InitialiseForElement(Z, p << 
719     fin3.close();                              << 
720   }                                            << 
721 }                                                 384 }
722                                                   385 
723 //....oooOO0OOooo........oooOO0OOooo........oo    386 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
724                                                   387 
725 G4double G4LivermorePhotoElectricModel::GetBin << 388 G4double G4LivermorePhotoElectricModel::GetMeanFreePath(const G4Track& track,
                                                   >> 389                G4double, // previousStepSize
                                                   >> 390                  G4ForceCondition*)
726 {                                                 391 {
727   if (Z < 1 || Z >= ZMAXPE) {                  << 392   const G4DynamicParticle* photon = track.GetDynamicParticle();
728     return -1;                                 << 393   G4double energy = photon->GetKineticEnergy();
729   }  // If Z is out of the supported return 0  << 394   G4Material* material = track.GetMaterial();
730                                                << 395   //  size_t materialIndex = material->GetIndex();
731   InitialiseOnFly(Z);                          << 
732   if (fCrossSection->GetElementData(Z) == null << 
733       shell < 0 || shell >= fNShellsUsed[Z]) { << 
734     return -1;                                 << 
735   }                                            << 
736                                                   396 
737   if (Z > 2) {                                 << 397   G4double meanFreePath = DBL_MAX;
738     return fCrossSection->GetComponentDataByIn << 
739   }                                            << 
740   else {                                       << 
741     return fCrossSection->GetElementData(Z)->E << 
742   }                                            << 
743 }                                              << 
744                                                << 
745 //....oooOO0OOooo........oooOO0OOooo........oo << 
746                                                   398 
747 void                                           << 399   //  if (energy > highEnergyLimit) 
748 G4LivermorePhotoElectricModel::InitialiseForEl << 400   //    meanFreePath = meanFreePathTable->FindValue(highEnergyLimit,materialIndex);
749 {                                              << 401   //  else if (energy < lowEnergyLimit) meanFreePath = DBL_MAX;
750   if (fCrossSection == nullptr) {              << 402   //  else meanFreePath = meanFreePathTable->FindValue(energy,materialIndex);
751     fCrossSection = new G4ElementData(ZMAXPE); << 
752     fCrossSection->SetName("PhotoEffXS");      << 
753     fCrossSectionLE = new G4ElementData(ZMAXPE << 
754     fCrossSectionLE->SetName("PhotoEffLowXS"); << 
755   }                                            << 
756   ReadData(Z);                                 << 
757 }                                              << 
758                                                   403 
759 //....oooOO0OOooo........oooOO0OOooo........oo << 404   G4double cross = shellCrossSectionHandler->ValueForMaterial(material,energy);
                                                   >> 405   if(cross > 0.0) meanFreePath = 1.0/cross;
760                                                   406 
761 void G4LivermorePhotoElectricModel::Initialise << 407   return meanFreePath;
762 {                                              << 
763   if (fCrossSection->GetElementData(Z) == null << 
764     G4AutoLock l(&livPhotoeffMutex);           << 
765     if (fCrossSection->GetElementData(Z) == nu << 
766       ReadData(Z);                             << 
767     }                                          << 
768     l.unlock();                                << 
769   }                                            << 
770 }                                                 408 }
771                                                   409 
772 //....oooOO0OOooo........oooOO0OOooo........oo << 
773                                                   410