Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/electromagnetic/lowenergy/src/G4MicroElecInelasticModel.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/G4MicroElecInelasticModel.cc (Version 11.3.0) and /processes/electromagnetic/lowenergy/src/G4MicroElecInelasticModel.cc (Version 10.1.p3)


  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 //                                                 26 //
 27 // G4MicroElecInelasticModel.cc, 2011/08/29 A.     27 // G4MicroElecInelasticModel.cc, 2011/08/29 A.Valentin, M. Raine
 28 //                                                 28 //
 29 // Based on the following publications             29 // Based on the following publications
 30 //                                                 30 //
 31 //          - Inelastic cross-sections of low      31 //          - Inelastic cross-sections of low energy electrons in silicon
 32 //      for the simulation of heavy ion tracks     32 //      for the simulation of heavy ion tracks with theGeant4-DNA toolkit,
 33 //      NSS Conf. Record 2010, pp. 80-85.          33 //      NSS Conf. Record 2010, pp. 80-85.
 34 //      - Geant4 physics processes for microdo     34 //      - Geant4 physics processes for microdosimetry simulation:
 35 //      very low energy electromagnetic models     35 //      very low energy electromagnetic models for electrons in Si,
 36 //      NIM B, vol. 288, pp. 66 - 73, 2012.        36 //      NIM B, vol. 288, pp. 66 - 73, 2012.
 37 //      - Geant4 physics processes for microdo     37 //      - Geant4 physics processes for microdosimetry simulation:
 38 //      very low energy electromagnetic models     38 //      very low energy electromagnetic models for protons and
 39 //      heavy ions in Si, NIM B, vol. 287, pp.     39 //      heavy ions in Si, NIM B, vol. 287, pp. 124 - 129, 2012.
 40 //                                                 40 //
 41 //....oooOO0OOooo........oooOO0OOooo........oo     41 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 42                                                    42 
 43 #include "G4MicroElecInelasticModel.hh"            43 #include "G4MicroElecInelasticModel.hh"
 44                                                    44 
 45 #include "globals.hh"                              45 #include "globals.hh"
 46 #include "G4PhysicalConstants.hh"                  46 #include "G4PhysicalConstants.hh"
 47 #include "G4SystemOfUnits.hh"                      47 #include "G4SystemOfUnits.hh"
 48 #include "G4ios.hh"                                48 #include "G4ios.hh"
 49 #include "G4UnitsTable.hh"                         49 #include "G4UnitsTable.hh"
 50 #include "G4UAtomicDeexcitation.hh"                50 #include "G4UAtomicDeexcitation.hh"
 51 #include "G4MicroElecSiStructure.hh"           << 
 52 #include "G4LossTableManager.hh"                   51 #include "G4LossTableManager.hh"
 53 #include "G4ionEffectiveCharge.hh"                 52 #include "G4ionEffectiveCharge.hh"
 54 #include "G4MicroElecCrossSectionDataSet.hh"   <<  53 
 55 #include "G4Electron.hh"                       << 
 56 #include "G4Proton.hh"                         << 
 57 #include "G4GenericIon.hh"                     << 
 58 #include "G4ParticleDefinition.hh"             << 
 59 #include "G4NistManager.hh"                    << 
 60 #include "G4LogLogInterpolation.hh"            << 
 61 #include "G4DeltaAngle.hh"                         54 #include "G4DeltaAngle.hh"
 62                                                    55 
 63 //....oooOO0OOooo........oooOO0OOooo........oo     56 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 64                                                    57 
 65 using namespace std;                               58 using namespace std;
 66                                                    59 
 67 //....oooOO0OOooo........oooOO0OOooo........oo     60 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 68                                                    61 
 69 G4MicroElecInelasticModel::G4MicroElecInelasti     62 G4MicroElecInelasticModel::G4MicroElecInelasticModel(const G4ParticleDefinition*,
 70                                                    63                                                      const G4String& nam)
 71 :G4VEmModel(nam),isInitialised(false)          <<  64 :G4VEmModel(nam),fAtomDeexcitation(0),isInitialised(false)
 72 {                                                  65 {
 73   nistSi = G4NistManager::Instance()->FindOrBu     66   nistSi = G4NistManager::Instance()->FindOrBuildMaterial("G4_Si");
 74                                                    67   
 75   verboseLevel= 0;                                 68   verboseLevel= 0;
 76   // Verbosity scale:                              69   // Verbosity scale:
 77   // 0 = nothing                                   70   // 0 = nothing
 78   // 1 = warning for energy non-conservation       71   // 1 = warning for energy non-conservation
 79   // 2 = details of energy budget                  72   // 2 = details of energy budget
 80   // 3 = calculation of cross sections, file o     73   // 3 = calculation of cross sections, file openings, sampling of atoms
 81   // 4 = entering in methods                       74   // 4 = entering in methods
 82                                                    75   
 83   if( verboseLevel>0 )                             76   if( verboseLevel>0 )
 84   {                                                77   {
 85     G4cout << "MicroElec inelastic model is co     78     G4cout << "MicroElec inelastic model is constructed " << G4endl;
 86   }                                                79   }
 87                                                    80   
 88   //Mark this model as "applicable" for atomic     81   //Mark this model as "applicable" for atomic deexcitation
 89   SetDeexcitationFlag(true);                       82   SetDeexcitationFlag(true);
 90   fAtomDeexcitation = nullptr;                 <<  83   fParticleChangeForGamma = 0;
 91   fParticleChangeForGamma = nullptr;           << 
 92                                                    84   
 93   // default generator                             85   // default generator
 94   SetAngularDistribution(new G4DeltaAngle());      86   SetAngularDistribution(new G4DeltaAngle());
 95                                                << 
 96   // Selection of computation method           << 
 97   fasterCode = true; //false;                  << 
 98 }                                                  87 }
 99                                                    88 
100 //....oooOO0OOooo........oooOO0OOooo........oo     89 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
101                                                    90 
102 G4MicroElecInelasticModel::~G4MicroElecInelast     91 G4MicroElecInelasticModel::~G4MicroElecInelasticModel()
103 {                                                  92 {
104   // Cross section                                 93   // Cross section
105   for (auto & pos : tableData)                 <<  94   
                                                   >>  95   std::map< G4String,G4MicroElecCrossSectionDataSet*,std::less<G4String> >::iterator pos;
                                                   >>  96   for (pos = tableData.begin(); pos != tableData.end(); ++pos)
106   {                                                97   {
107     G4MicroElecCrossSectionDataSet* table = po <<  98     G4MicroElecCrossSectionDataSet* table = pos->second;
108     delete table;                                  99     delete table;
109   }                                               100   }
110                                                   101   
111   // Final state                                  102   // Final state
                                                   >> 103   
112   eVecm.clear();                                  104   eVecm.clear();
113   pVecm.clear();                                  105   pVecm.clear();
114                                                   106   
115 }                                                 107 }
116                                                   108 
117 //....oooOO0OOooo........oooOO0OOooo........oo    109 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
118                                                   110 
119 void G4MicroElecInelasticModel::Initialise(con    111 void G4MicroElecInelasticModel::Initialise(const G4ParticleDefinition* particle,
120                                            con    112                                            const G4DataVector& /*cuts*/)
121 {                                                 113 {
122                                                   114   
123   if (verboseLevel > 3)                           115   if (verboseLevel > 3)
124     G4cout << "Calling G4MicroElecInelasticMod    116     G4cout << "Calling G4MicroElecInelasticModel::Initialise()" << G4endl;
125                                                   117   
126   // Energy limits                                118   // Energy limits
127                                                   119   
128   G4String fileElectron("microelec/sigma_inela    120   G4String fileElectron("microelec/sigma_inelastic_e_Si");
129   G4String fileProton("microelec/sigma_inelast    121   G4String fileProton("microelec/sigma_inelastic_p_Si");
130                                                   122   
131   G4ParticleDefinition* electronDef = G4Electr    123   G4ParticleDefinition* electronDef = G4Electron::ElectronDefinition();
132   G4ParticleDefinition* protonDef = G4Proton::    124   G4ParticleDefinition* protonDef = G4Proton::ProtonDefinition();
133   G4String electron = electronDef->GetParticle << 125   
134   G4String proton = protonDef->GetParticleName << 126   G4String electron;
                                                   >> 127   G4String proton;
135                                                   128   
136   G4double scaleFactor = 1e-18 * cm *cm;          129   G4double scaleFactor = 1e-18 * cm *cm;
137                                                << 130   
138   const char* path = G4FindDataDir("G4LEDATA") << 131   char *path = getenv("G4LEDATA");
139                                                << 132   
140   // *** ELECTRON                                 133   // *** ELECTRON
141   tableFile[electron] = fileElectron;          << 134   electron = electronDef->GetParticleName();
                                                   >> 135   
                                                   >> 136   tableFile[electron] = fileElectron;
                                                   >> 137   
142   lowEnergyLimit[electron] = 16.7 * eV;           138   lowEnergyLimit[electron] = 16.7 * eV;
143   highEnergyLimit[electron] = 100.0 * MeV;        139   highEnergyLimit[electron] = 100.0 * MeV;
144                                                   140   
145   // Cross section                             << 141   // Cross section
                                                   >> 142   
146   G4MicroElecCrossSectionDataSet* tableE = new    143   G4MicroElecCrossSectionDataSet* tableE = new G4MicroElecCrossSectionDataSet(new G4LogLogInterpolation, eV,scaleFactor );
147   tableE->LoadData(fileElectron);                 144   tableE->LoadData(fileElectron);
148                                                   145   
149   tableData[electron] = tableE;                   146   tableData[electron] = tableE;
150                                                   147   
151   // Final state                                  148   // Final state
152                                                   149   
153   std::ostringstream eFullFileName;               150   std::ostringstream eFullFileName;
154                                                << 151   eFullFileName << path << "/microelec/sigmadiff_inelastic_e_Si.dat";
155   if (fasterCode) eFullFileName << path << "/m << 
156   else eFullFileName << path << "/microelec/si << 
157                                                << 
158   std::ifstream eDiffCrossSection(eFullFileNam    152   std::ifstream eDiffCrossSection(eFullFileName.str().c_str());
159                                                   153   
160   if (!eDiffCrossSection)                         154   if (!eDiffCrossSection)
161   {                                               155   {
162      if (fasterCode) G4Exception("G4MicroElecI << 156     G4Exception("G4MicroElecInelasticModel::Initialise","em0003",FatalException,"Missing data file:/microelec/sigmadiff_inelastic_e_Si.dat");
163      FatalException,"Missing data file:/microe << 
164                                                << 
165      else G4Exception("G4MicroElecInelasticMod << 
166      FatalException,"Missing data file:/microe << 
167   }                                               157   }
168                                                << 158   
                                                   >> 159   //
                                                   >> 160   
169   // Clear the arrays for re-initialization ca    161   // Clear the arrays for re-initialization case (MT mode)
170   // Octobre 22nd, 2014 - Melanie Raine        << 162   // Octobre 22nd, 2014 - Melanie Raine
                                                   >> 163   
171   eTdummyVec.clear();                             164   eTdummyVec.clear();
172   pTdummyVec.clear();                             165   pTdummyVec.clear();
173                                                   166   
174   eVecm.clear();                                  167   eVecm.clear();
175   pVecm.clear();                                  168   pVecm.clear();
176                                                   169   
177   for (int j=0; j<6; j++)                      << 170   eDiffCrossSectionData->clear();
178   {                                            << 171   pDiffCrossSectionData->clear();
179     eProbaShellMap[j].clear();                 << 
180     pProbaShellMap[j].clear();                 << 
181                                                << 
182     eDiffCrossSectionData[j].clear();          << 
183     pDiffCrossSectionData[j].clear();          << 
184                                                << 
185     eNrjTransfData[j].clear();                 << 
186     pNrjTransfData[j].clear();                 << 
187   }                                            << 
188                                                   172   
189   //                                              173   //
                                                   >> 174   
                                                   >> 175   
190   eTdummyVec.push_back(0.);                       176   eTdummyVec.push_back(0.);
191   while(!eDiffCrossSection.eof())                 177   while(!eDiffCrossSection.eof())
192   {                                               178   {
193     G4double tDummy;                           << 179     double tDummy;
194     G4double eDummy;                           << 180     double eDummy;
195     eDiffCrossSection>>tDummy>>eDummy;            181     eDiffCrossSection>>tDummy>>eDummy;
196     if (tDummy != eTdummyVec.back()) eTdummyVe    182     if (tDummy != eTdummyVec.back()) eTdummyVec.push_back(tDummy);
197                                                << 
198     G4double tmp;                              << 
199     for (int j=0; j<6; j++)                       183     for (int j=0; j<6; j++)
200     {                                             184     {
201       eDiffCrossSection>> tmp;                 << 185       eDiffCrossSection>>eDiffCrossSectionData[j][tDummy][eDummy];
202                                                << 
203       eDiffCrossSectionData[j][tDummy][eDummy] << 
204                                                   186       
205       if (fasterCode)                          << 
206       {                                        << 
207         eNrjTransfData[j][tDummy][eDiffCrossSe << 
208         eProbaShellMap[j][tDummy].push_back(eD << 
209       }                                        << 
210       else                                     << 
211       {                                        << 
212       // SI - only if eof is not reached !        187       // SI - only if eof is not reached !
213   if (!eDiffCrossSection.eof()) eDiffCrossSect << 188       if (!eDiffCrossSection.eof()) eDiffCrossSectionData[j][tDummy][eDummy]*=scaleFactor;
214   eVecm[tDummy].push_back(eDummy);             << 189       
215       }                                        << 190       eVecm[tDummy].push_back(eDummy);
216                                                   191       
217     }                                             192     }
218   }                                               193   }
219   //                                              194   //
220                                                   195   
221   // *** PROTON                                << 196   // *** PROTON
222   tableFile[proton] = fileProton;              << 197   
                                                   >> 198   proton = protonDef->GetParticleName();
                                                   >> 199   
                                                   >> 200   tableFile[proton] = fileProton;
                                                   >> 201   
223   lowEnergyLimit[proton] = 50. * keV;             202   lowEnergyLimit[proton] = 50. * keV;
224   highEnergyLimit[proton] = 10. * GeV;            203   highEnergyLimit[proton] = 10. * GeV;
225                                                   204   
226   // Cross section                                205   // Cross section
                                                   >> 206   
227   G4MicroElecCrossSectionDataSet* tableP = new    207   G4MicroElecCrossSectionDataSet* tableP = new G4MicroElecCrossSectionDataSet(new G4LogLogInterpolation, eV,scaleFactor );
228   tableP->LoadData(fileProton);                   208   tableP->LoadData(fileProton);
                                                   >> 209   
229   tableData[proton] = tableP;                     210   tableData[proton] = tableP;
230                                                   211   
231   // Final state                               << 212   // Final state
232   std::ostringstream pFullFileName;            << 
233                                                   213   
234   if (fasterCode) pFullFileName << path << "/m << 214   std::ostringstream pFullFileName;
235   else pFullFileName << path << "/microelec/si << 215   pFullFileName << path << "/microelec/sigmadiff_inelastic_p_Si.dat";
236                                                << 
237   std::ifstream pDiffCrossSection(pFullFileNam    216   std::ifstream pDiffCrossSection(pFullFileName.str().c_str());
238                                                   217   
239   if (!pDiffCrossSection)                         218   if (!pDiffCrossSection)
240   {                                               219   {
241     if (fasterCode) G4Exception("G4MicroElecIn << 220     G4Exception("G4MicroElecInelasticModel::Initialise","em0003",FatalException,"Missing data file:/microelec/sigmadiff_inelastic_p_Si.dat");
242       FatalException,"Missing data file:/micro << 
243                                                << 
244     else G4Exception("G4MicroElecInelasticMode << 
245       FatalException,"Missing data file:/micro << 
246   }                                               221   }
247                                                   222   
248   pTdummyVec.push_back(0.);                       223   pTdummyVec.push_back(0.);
249   while(!pDiffCrossSection.eof())                 224   while(!pDiffCrossSection.eof())
250   {                                               225   {
251     G4double tDummy;                           << 226     double tDummy;
252     G4double eDummy;                           << 227     double eDummy;
253     pDiffCrossSection>>tDummy>>eDummy;            228     pDiffCrossSection>>tDummy>>eDummy;
254     if (tDummy != pTdummyVec.back()) pTdummyVe    229     if (tDummy != pTdummyVec.back()) pTdummyVec.push_back(tDummy);
255     for (int j=0; j<6; j++)                       230     for (int j=0; j<6; j++)
256     {                                             231     {
257       pDiffCrossSection>>pDiffCrossSectionData    232       pDiffCrossSection>>pDiffCrossSectionData[j][tDummy][eDummy];
258                                                   233       
259       if (fasterCode)                          << 234       // SI - only if eof is not reached !
260       {                                        << 235       if (!pDiffCrossSection.eof()) pDiffCrossSectionData[j][tDummy][eDummy]*=scaleFactor;
261         pNrjTransfData[j][tDummy][pDiffCrossSe << 236       
262         pProbaShellMap[j][tDummy].push_back(pD << 237       pVecm[tDummy].push_back(eDummy);
263       }                                        << 
264       else                                     << 
265       {                                        << 
266   // SI - only if eof is not reached !         << 
267   if (!pDiffCrossSection.eof()) pDiffCrossSect << 
268   pVecm[tDummy].push_back(eDummy);             << 
269       }                                        << 
270     }                                             238     }
271   }                                               239   }
272                                                   240   
                                                   >> 241   
273   if (particle==electronDef)                      242   if (particle==electronDef)
274   {                                               243   {
275     SetLowEnergyLimit(lowEnergyLimit[electron]    244     SetLowEnergyLimit(lowEnergyLimit[electron]);
276     SetHighEnergyLimit(highEnergyLimit[electro    245     SetHighEnergyLimit(highEnergyLimit[electron]);
277   }                                               246   }
278                                                   247   
279   if (particle==protonDef)                        248   if (particle==protonDef)
280   {                                               249   {
281     SetLowEnergyLimit(lowEnergyLimit[proton]);    250     SetLowEnergyLimit(lowEnergyLimit[proton]);
282     SetHighEnergyLimit(highEnergyLimit[proton]    251     SetHighEnergyLimit(highEnergyLimit[proton]);
283   }                                               252   }
284                                                   253   
285   if( verboseLevel>0 )                            254   if( verboseLevel>0 )
286   {                                               255   {
287     G4cout << "MicroElec Inelastic model is in    256     G4cout << "MicroElec Inelastic model is initialized " << G4endl
288     << "Energy range: "                           257     << "Energy range: "
289     << LowEnergyLimit() / keV << " keV - "        258     << LowEnergyLimit() / keV << " keV - "
290     << HighEnergyLimit() / MeV << " MeV for "     259     << HighEnergyLimit() / MeV << " MeV for "
291     << particle->GetParticleName()                260     << particle->GetParticleName()
292      << " with mass (amu) " << particle->GetPD    261      << " with mass (amu) " << particle->GetPDGMass()/proton_mass_c2
293      << " and charge " << particle->GetPDGChar    262      << " and charge " << particle->GetPDGCharge()
294     << G4endl << G4endl ;                         263     << G4endl << G4endl ;
295   }                                               264   }
296                                                   265   
297   //                                              266   //
                                                   >> 267   
298   fAtomDeexcitation  = G4LossTableManager::Ins    268   fAtomDeexcitation  = G4LossTableManager::Instance()->AtomDeexcitation();
299                                                   269   
300   if (isInitialised) { return; }                  270   if (isInitialised) { return; }
301   fParticleChangeForGamma = GetParticleChangeF    271   fParticleChangeForGamma = GetParticleChangeForGamma();
302   isInitialised = true;                           272   isInitialised = true;
                                                   >> 273   
303 }                                                 274 }
304                                                   275 
305 //....oooOO0OOooo........oooOO0OOooo........oo    276 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
306                                                   277 
307 G4double G4MicroElecInelasticModel::CrossSecti    278 G4double G4MicroElecInelasticModel::CrossSectionPerVolume(const G4Material* material,
308                                                   279                                                           const G4ParticleDefinition* particleDefinition,
309                                                   280                                                           G4double ekin,
310                                                   281                                                           G4double,
311                                                   282                                                           G4double)
312 {                                                 283 {
313   if (verboseLevel > 3)                           284   if (verboseLevel > 3)
314     G4cout << "Calling CrossSectionPerVolume()    285     G4cout << "Calling CrossSectionPerVolume() of G4MicroElecInelasticModel" << G4endl;
315                                                   286   
316   G4double density = material->GetTotNbOfAtoms    287   G4double density = material->GetTotNbOfAtomsPerVolume();
317                                                   288   
318   // Calculate total cross section for model   << 289   /* if (
                                                   >> 290    particleDefinition != G4Proton::ProtonDefinition()
                                                   >> 291    &&
                                                   >> 292    particleDefinition != G4Electron::ElectronDefinition()
                                                   >> 293    &&
                                                   >> 294    particleDefinition != G4GenericIon::GenericIonDefinition()
                                                   >> 295    )
                                                   >> 296    
                                                   >> 297    return 0;*/
                                                   >> 298   
                                                   >> 299   // Calculate total cross section for model
                                                   >> 300   
319   G4double lowLim = 0;                            301   G4double lowLim = 0;
320   G4double highLim = 0;                           302   G4double highLim = 0;
321   G4double sigma=0;                               303   G4double sigma=0;
322                                                   304   
323   const G4String& particleName = particleDefin    305   const G4String& particleName = particleDefinition->GetParticleName();
324   G4String nameLocal = particleName ;             306   G4String nameLocal = particleName ;
325                                                   307   
326   G4double Zeff2 = 1.0;                           308   G4double Zeff2 = 1.0;
327   G4double Mion_c2 = particleDefinition->GetPD    309   G4double Mion_c2 = particleDefinition->GetPDGMass();
328                                                   310   
329   if (Mion_c2 > proton_mass_c2)                   311   if (Mion_c2 > proton_mass_c2)
330   {                                               312   {
331     G4ionEffectiveCharge EffCharge ;              313     G4ionEffectiveCharge EffCharge ;
332     G4double Zeff = EffCharge.EffectiveCharge(    314     G4double Zeff = EffCharge.EffectiveCharge(particleDefinition, material,ekin);
333     Zeff2 = Zeff*Zeff;                            315     Zeff2 = Zeff*Zeff;
334                                                   316     
335     if (verboseLevel > 3)                         317     if (verboseLevel > 3)
336       G4cout << "Before scaling : " << G4endl     318       G4cout << "Before scaling : " << G4endl
337       << "Particle : " << nameLocal << ", mass    319       << "Particle : " << nameLocal << ", mass : " << Mion_c2/proton_mass_c2 << "*mp, charge " << Zeff
338       << ", Ekin (eV) = " << ekin/eV << G4endl    320       << ", Ekin (eV) = " << ekin/eV << G4endl ;
339                                                   321     
340     ekin *= proton_mass_c2/Mion_c2 ;              322     ekin *= proton_mass_c2/Mion_c2 ;
341     nameLocal = "proton" ;                        323     nameLocal = "proton" ;
342                                                   324     
343     if (verboseLevel > 3)                         325     if (verboseLevel > 3)
344       G4cout << "After scaling : " << G4endl      326       G4cout << "After scaling : " << G4endl
345       << "Particle : " << nameLocal  << ", Eki    327       << "Particle : " << nameLocal  << ", Ekin (eV) = " << ekin/eV << G4endl ;
346   }                                               328   }
347                                                   329   
348   if (material == nistSi || material->GetBaseM    330   if (material == nistSi || material->GetBaseMaterial() == nistSi)
349   {                                            << 331   {
350     auto pos1 = lowEnergyLimit.find(nameLocal) << 332     
                                                   >> 333     std::map< G4String,G4double,std::less<G4String> >::iterator pos1;
                                                   >> 334     pos1 = lowEnergyLimit.find(nameLocal);
351     if (pos1 != lowEnergyLimit.end())             335     if (pos1 != lowEnergyLimit.end())
352     {                                             336     {
353       lowLim = pos1->second;                      337       lowLim = pos1->second;
354     }                                             338     }
355                                                   339     
356     auto pos2 = highEnergyLimit.find(nameLocal << 340     std::map< G4String,G4double,std::less<G4String> >::iterator pos2;
                                                   >> 341     pos2 = highEnergyLimit.find(nameLocal);
357     if (pos2 != highEnergyLimit.end())            342     if (pos2 != highEnergyLimit.end())
358     {                                             343     {
359       highLim = pos2->second;                     344       highLim = pos2->second;
360     }                                             345     }
361                                                   346     
362     if (ekin >= lowLim && ekin < highLim)         347     if (ekin >= lowLim && ekin < highLim)
363     {                                             348     {
364       auto pos = tableData.find(nameLocal);    << 349       std::map< G4String,G4MicroElecCrossSectionDataSet*,std::less<G4String> >::iterator pos;
                                                   >> 350       pos = tableData.find(nameLocal);
                                                   >> 351       
365       if (pos != tableData.end())                 352       if (pos != tableData.end())
366       {                                           353       {
367         G4MicroElecCrossSectionDataSet* table     354         G4MicroElecCrossSectionDataSet* table = pos->second;
368         if (table != nullptr)                  << 355         if (table != 0)
369         {                                         356         {
370           sigma = table->FindValue(ekin);         357           sigma = table->FindValue(ekin);
371         }                                         358         }
372       }                                           359       }
373       else                                        360       else
374       {                                           361       {
375         G4Exception("G4MicroElecInelasticModel << 362         G4Exception("G4MicroElecInelasticModel::CrossSectionPerVolume","em0002",FatalException,"Model not applicable to particle type.");
376         FatalException,"Model not applicable t << 
377       }                                           363       }
378     }                                             364     }
379     else                                          365     else
380     {                                             366     {
381       if (nameLocal!="e-")                        367       if (nameLocal!="e-")
382       {                                           368       {
383         // G4cout << "Particle : " << nameLoca    369         // G4cout << "Particle : " << nameLocal << ", Ekin (eV) = " << ekin/eV << G4endl;
384         // G4cout << "### Warning: particle en    370         // G4cout << "### Warning: particle energy out of bounds! ###" << G4endl;
385       }                                           371       }
386     }                                             372     }
387                                                   373     
388     if (verboseLevel > 3)                         374     if (verboseLevel > 3)
389     {                                             375     {
390       G4cout << "---> Kinetic energy (eV)=" <<    376       G4cout << "---> Kinetic energy (eV)=" << ekin/eV << G4endl;
391       G4cout << " - Cross section per Si atom     377       G4cout << " - Cross section per Si atom (cm^2)=" << sigma*Zeff2/cm2 << G4endl;
392       G4cout << " - Cross section per Si atom     378       G4cout << " - Cross section per Si atom (cm^-1)=" << sigma*density*Zeff2/(1./cm) << G4endl;
393     }                                             379     }
394                                                   380     
395   } // if (SiMaterial)                            381   } // if (SiMaterial)
396   return sigma*density*Zeff2;                  << 382   return sigma*density*Zeff2;
                                                   >> 383   
                                                   >> 384   
397 }                                                 385 }
398                                                   386 
399 //....oooOO0OOooo........oooOO0OOooo........oo    387 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
400                                                   388 
401 void G4MicroElecInelasticModel::SampleSecondar    389 void G4MicroElecInelasticModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
402                                                   390                                                   const G4MaterialCutsCouple* couple,
403                                                   391                                                   const G4DynamicParticle* particle,
404                                                   392                                                   G4double,
405                                                   393                                                   G4double)
406 {                                                 394 {
407                                                   395   
408   if (verboseLevel > 3)                           396   if (verboseLevel > 3)
409     G4cout << "Calling SampleSecondaries() of     397     G4cout << "Calling SampleSecondaries() of G4MicroElecInelasticModel" << G4endl;
410                                                   398   
411   G4double lowLim = 0;                            399   G4double lowLim = 0;
412   G4double highLim = 0;                           400   G4double highLim = 0;
413                                                   401   
414   G4double ekin = particle->GetKineticEnergy()    402   G4double ekin = particle->GetKineticEnergy();
415   G4double k = ekin ;                             403   G4double k = ekin ;
416                                                   404   
417   G4ParticleDefinition* PartDef = particle->Ge    405   G4ParticleDefinition* PartDef = particle->GetDefinition();
418   const G4String& particleName = PartDef->GetP    406   const G4String& particleName = PartDef->GetParticleName();
419   G4String nameLocal2 = particleName ;            407   G4String nameLocal2 = particleName ;
420   G4double particleMass = particle->GetDefinit    408   G4double particleMass = particle->GetDefinition()->GetPDGMass();
421                                                   409   
422   if (particleMass > proton_mass_c2)              410   if (particleMass > proton_mass_c2)
423   {                                               411   {
424     k *= proton_mass_c2/particleMass ;            412     k *= proton_mass_c2/particleMass ;
425     PartDef = G4Proton::ProtonDefinition();       413     PartDef = G4Proton::ProtonDefinition();
426     nameLocal2 = "proton" ;                       414     nameLocal2 = "proton" ;
427   }                                               415   }
428                                                   416   
429   auto pos1 = lowEnergyLimit.find(nameLocal2); << 417   std::map< G4String,G4double,std::less<G4String> >::iterator pos1;
                                                   >> 418   pos1 = lowEnergyLimit.find(nameLocal2);
                                                   >> 419   
430   if (pos1 != lowEnergyLimit.end())               420   if (pos1 != lowEnergyLimit.end())
431   {                                               421   {
432     lowLim = pos1->second;                        422     lowLim = pos1->second;
433   }                                               423   }
434                                                   424   
435   auto pos2 = highEnergyLimit.find(nameLocal2) << 425   std::map< G4String,G4double,std::less<G4String> >::iterator pos2;
                                                   >> 426   pos2 = highEnergyLimit.find(nameLocal2);
                                                   >> 427   
436   if (pos2 != highEnergyLimit.end())              428   if (pos2 != highEnergyLimit.end())
437   {                                               429   {
438     highLim = pos2->second;                       430     highLim = pos2->second;
439   }                                               431   }
440                                                   432   
441   if (k >= lowLim && k < highLim)                 433   if (k >= lowLim && k < highLim)
442   {                                               434   {
443     G4ParticleMomentum primaryDirection = part    435     G4ParticleMomentum primaryDirection = particle->GetMomentumDirection();
444     G4double totalEnergy = ekin + particleMass    436     G4double totalEnergy = ekin + particleMass;
445     G4double pSquare = ekin * (totalEnergy + p    437     G4double pSquare = ekin * (totalEnergy + particleMass);
446     G4double totalMomentum = std::sqrt(pSquare    438     G4double totalMomentum = std::sqrt(pSquare);
447                                                   439     
448     G4int Shell = 0;                           << 440     G4int Shell = RandomSelect(k,nameLocal2);
449                                                << 
450     /* if (!fasterCode)*/ Shell = RandomSelect << 
451                                                << 
452     // SI: The following protection is necessa << 
453     //  sigmadiff_ionisation_e_born.dat has no << 
454     //  sigmadiff_cumulated_ionisation_e_born. << 
455     //  this is due to the fact that the max a << 
456     //  strictly above this value have non zer << 
457                                                << 
458     G4double bindingEnergy = SiStructure.Energ    441     G4double bindingEnergy = SiStructure.Energy(Shell);
459                                                   442     
460     if (verboseLevel > 3)                         443     if (verboseLevel > 3)
461     {                                             444     {
462       G4cout << "---> Kinetic energy (eV)=" <<    445       G4cout << "---> Kinetic energy (eV)=" << k/eV << G4endl ;
463       G4cout << "Shell: " << Shell << ", energ    446       G4cout << "Shell: " << Shell << ", energy: " << bindingEnergy/eV << G4endl;
464     }                                             447     }
465                                                   448     
466     // sample deexcitation                        449     // sample deexcitation
467     std::size_t secNumberInit = 0;  // need to << 
468     std::size_t secNumberFinal = 0; // So I'll << 
469                                                   450     
470     //SI: additional protection if tcs interpo << 451     G4int secNumberInit = 0;  // need to know at a certain point the energy of secondaries
471     if (k<bindingEnergy) return;               << 452     G4int secNumberFinal = 0; // So I'll make the difference and then sum the energies
472                                                   453     
473     G4int Z = 14;                                 454     G4int Z = 14;
474                                                   455     
475     if(fAtomDeexcitation && Shell > 2) {          456     if(fAtomDeexcitation && Shell > 2) {
476                                                   457       
477       G4AtomicShellEnumerator as = fKShell;       458       G4AtomicShellEnumerator as = fKShell;
478                                                   459       
479       if (Shell == 4)                             460       if (Shell == 4)
480       {                                           461       {
481         as = G4AtomicShellEnumerator(1);          462         as = G4AtomicShellEnumerator(1);
482       }                                           463       }
483       else if (Shell == 3)                        464       else if (Shell == 3)
484       {                                           465       {
485         as = G4AtomicShellEnumerator(3);          466         as = G4AtomicShellEnumerator(3);
486       }                                           467       }
487                                                   468       
488       const G4AtomicShell* shell = fAtomDeexci    469       const G4AtomicShell* shell = fAtomDeexcitation->GetAtomicShell(Z, as);
489       secNumberInit = fvect->size();              470       secNumberInit = fvect->size();
490       fAtomDeexcitation->GenerateParticles(fve    471       fAtomDeexcitation->GenerateParticles(fvect, shell, Z, 0, 0);
491       secNumberFinal = fvect->size();             472       secNumberFinal = fvect->size();
492     }                                             473     }
493                                                   474     
494     G4double secondaryKinetic=-1000*eV;        << 475     G4double secondaryKinetic = RandomizeEjectedElectronEnergy(PartDef,k,Shell);
495                                                << 
496     if (!fasterCode)                           << 
497     {                                          << 
498       secondaryKinetic = RandomizeEjectedElect << 
499     }                                          << 
500     else                                       << 
501     {                                          << 
502       secondaryKinetic = RandomizeEjectedElect << 
503     }                                          << 
504                                                   476     
505     if (verboseLevel > 3)                         477     if (verboseLevel > 3)
506     {                                             478     {
507       G4cout << "Ionisation process" << G4endl    479       G4cout << "Ionisation process" << G4endl;
508       G4cout << "Shell: " << Shell << " Kin. e    480       G4cout << "Shell: " << Shell << " Kin. energy (eV)=" << k/eV
509       << " Sec. energy (eV)=" << secondaryKine    481       << " Sec. energy (eV)=" << secondaryKinetic/eV << G4endl;
510     }                                             482     }
511                                                   483     
512     G4ThreeVector deltaDirection =                484     G4ThreeVector deltaDirection =
513     GetAngularDistribution()->SampleDirectionF    485     GetAngularDistribution()->SampleDirectionForShell(particle, secondaryKinetic,
514                                                   486                                                       Z, Shell,
515                                                   487                                                       couple->GetMaterial());
516                                                   488     
517     if (particle->GetDefinition() == G4Electro << 489     //if (particle->GetDefinition() == G4Electron::ElectronDefinition())
518     {                                          << 490     //{
519       G4double deltaTotalMomentum = std::sqrt( << 491     G4double deltaTotalMomentum = std::sqrt(secondaryKinetic*(secondaryKinetic + 2.*electron_mass_c2 ));
520       G4double finalPx = totalMomentum*primary << 492     
521       G4double finalPy = totalMomentum*primary << 493     G4double finalPx = totalMomentum*primaryDirection.x() - deltaTotalMomentum*deltaDirection.x();
522       G4double finalPz = totalMomentum*primary << 494     G4double finalPy = totalMomentum*primaryDirection.y() - deltaTotalMomentum*deltaDirection.y();
523       G4double finalMomentum = std::sqrt(final << 495     G4double finalPz = totalMomentum*primaryDirection.z() - deltaTotalMomentum*deltaDirection.z();
524       finalPx /= finalMomentum;                << 496     G4double finalMomentum = std::sqrt(finalPx*finalPx + finalPy*finalPy + finalPz*finalPz);
525       finalPy /= finalMomentum;                << 497     finalPx /= finalMomentum;
526       finalPz /= finalMomentum;                << 498     finalPy /= finalMomentum;
527                                                << 499     finalPz /= finalMomentum;
528       G4ThreeVector direction;                 << 500     
529       direction.set(finalPx,finalPy,finalPz);  << 501     G4ThreeVector direction;
530                                                << 502     direction.set(finalPx,finalPy,finalPz);
531       fParticleChangeForGamma->ProposeMomentum << 503     
532     }                                          << 504     fParticleChangeForGamma->ProposeMomentumDirection(direction.unit()) ;
533     else                                       << 505     //}
534       fParticleChangeForGamma->ProposeMomentum << 506     //else fParticleChangeForGamma->ProposeMomentumDirection(primaryDirection) ;
535                                                   507     
536     // note that secondaryKinetic is the energ    508     // note that secondaryKinetic is the energy of the delta ray, not of all secondaries.
537     G4double deexSecEnergy = 0;                   509     G4double deexSecEnergy = 0;
538     for (std::size_t j=secNumberInit; j < secN << 510     for (G4int j=secNumberInit; j < secNumberFinal; j++) {
539       deexSecEnergy = deexSecEnergy + (*fvect)    511       deexSecEnergy = deexSecEnergy + (*fvect)[j]->GetKineticEnergy();}
540                                                   512     
541     fParticleChangeForGamma->SetProposedKineti    513     fParticleChangeForGamma->SetProposedKineticEnergy(ekin-bindingEnergy-secondaryKinetic);
542     fParticleChangeForGamma->ProposeLocalEnerg    514     fParticleChangeForGamma->ProposeLocalEnergyDeposit(bindingEnergy-deexSecEnergy);
543                                                   515     
544     if (secondaryKinetic>0)                    << 516     G4DynamicParticle* dp = new G4DynamicParticle (G4Electron::Electron(),deltaDirection,secondaryKinetic) ;
545     {                                          << 517     fvect->push_back(dp);
546       G4DynamicParticle* dp = new G4DynamicPar << 518     
547       fvect->push_back(dp);                    << 
548     }                                          << 
549   }                                               519   }
                                                   >> 520   
550 }                                                 521 }
551                                                   522 
552 //....oooOO0OOooo........oooOO0OOooo........oo    523 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
553                                                   524 
554 G4double G4MicroElecInelasticModel::RandomizeE    525 G4double G4MicroElecInelasticModel::RandomizeEjectedElectronEnergy(G4ParticleDefinition* particleDefinition,
555                                                   526                                                                    G4double k, G4int shell)
556 {                                                 527 {
557   if (particleDefinition == G4Electron::Electr    528   if (particleDefinition == G4Electron::ElectronDefinition())
558   {                                               529   {
559     G4double maximumEnergyTransfer=0.;            530     G4double maximumEnergyTransfer=0.;
560     if ((k+SiStructure.Energy(shell))/2. > k)     531     if ((k+SiStructure.Energy(shell))/2. > k) maximumEnergyTransfer=k;
561     else maximumEnergyTransfer = (k+SiStructur    532     else maximumEnergyTransfer = (k+SiStructure.Energy(shell))/2.;
562                                                   533     
563     G4double crossSectionMaximum = 0.;            534     G4double crossSectionMaximum = 0.;
564                                                   535     
565     G4double minEnergy = SiStructure.Energy(sh    536     G4double minEnergy = SiStructure.Energy(shell);
566     G4double maxEnergy = maximumEnergyTransfer    537     G4double maxEnergy = maximumEnergyTransfer;
567     G4int nEnergySteps = 100;                     538     G4int nEnergySteps = 100;
568                                                   539     
569     G4double value(minEnergy);                    540     G4double value(minEnergy);
570     G4double stpEnergy(std::pow(maxEnergy/valu    541     G4double stpEnergy(std::pow(maxEnergy/value, 1./static_cast<G4double>(nEnergySteps-1)));
571     G4int step(nEnergySteps);                     542     G4int step(nEnergySteps);
572     while (step>0)                                543     while (step>0)
573     {                                             544     {
574       step--;                                     545       step--;
575       G4double differentialCrossSection = Diff    546       G4double differentialCrossSection = DifferentialCrossSection(particleDefinition, k/eV, value/eV, shell);
576       if(differentialCrossSection >= crossSect    547       if(differentialCrossSection >= crossSectionMaximum) crossSectionMaximum = differentialCrossSection;
577       value*=stpEnergy;                           548       value*=stpEnergy;
578     }                                             549     }
579                                                   550     
                                                   >> 551     
580     G4double secondaryElectronKineticEnergy=0.    552     G4double secondaryElectronKineticEnergy=0.;
581     do                                            553     do
582     {                                             554     {
583       secondaryElectronKineticEnergy = G4Unifo    555       secondaryElectronKineticEnergy = G4UniformRand() * (maximumEnergyTransfer-SiStructure.Energy(shell));
584     } while(G4UniformRand()*crossSectionMaximu    556     } while(G4UniformRand()*crossSectionMaximum >
585             DifferentialCrossSection(particleD    557             DifferentialCrossSection(particleDefinition, k/eV,(secondaryElectronKineticEnergy+SiStructure.Energy(shell))/eV,shell));
586                                                   558     
587     return secondaryElectronKineticEnergy;     << 559     return secondaryElectronKineticEnergy;
                                                   >> 560     
588   }                                               561   }
589                                                   562   
590   if (particleDefinition == G4Proton::ProtonDe    563   if (particleDefinition == G4Proton::ProtonDefinition())
591   {                                               564   {
592     G4double maximumEnergyTransfer = 4.* (elec    565     G4double maximumEnergyTransfer = 4.* (electron_mass_c2 / proton_mass_c2) * k;
593     G4double crossSectionMaximum = 0.;            566     G4double crossSectionMaximum = 0.;
594                                                   567     
595     G4double minEnergy = SiStructure.Energy(sh    568     G4double minEnergy = SiStructure.Energy(shell);
596     G4double maxEnergy = maximumEnergyTransfer    569     G4double maxEnergy = maximumEnergyTransfer;
597     G4int nEnergySteps = 100;                     570     G4int nEnergySteps = 100;
598                                                   571     
599     G4double value(minEnergy);                    572     G4double value(minEnergy);
600     G4double stpEnergy(std::pow(maxEnergy/valu    573     G4double stpEnergy(std::pow(maxEnergy/value, 1./static_cast<G4double>(nEnergySteps-1)));
601     G4int step(nEnergySteps);                     574     G4int step(nEnergySteps);
602     while (step>0)                                575     while (step>0)
603     {                                             576     {
604       step--;                                     577       step--;
605       G4double differentialCrossSection = Diff    578       G4double differentialCrossSection = DifferentialCrossSection(particleDefinition, k/eV, value/eV, shell);
606       if(differentialCrossSection >= crossSect    579       if(differentialCrossSection >= crossSectionMaximum) crossSectionMaximum = differentialCrossSection;
607       value*=stpEnergy;                           580       value*=stpEnergy;
608     }                                             581     }
609                                                << 
610     G4double secondaryElectronKineticEnergy =     582     G4double secondaryElectronKineticEnergy = 0.;
611     do                                            583     do
612     {                                             584     {
613       secondaryElectronKineticEnergy = G4Unifo    585       secondaryElectronKineticEnergy = G4UniformRand() * (maximumEnergyTransfer-SiStructure.Energy(shell));
614                                                   586       
615     } while(G4UniformRand()*crossSectionMaximu    587     } while(G4UniformRand()*crossSectionMaximum >
616             DifferentialCrossSection(particleD    588             DifferentialCrossSection(particleDefinition, k/eV,(secondaryElectronKineticEnergy+SiStructure.Energy(shell))/eV,shell));
617     return secondaryElectronKineticEnergy;        589     return secondaryElectronKineticEnergy;
618   }                                               590   }
619                                                   591   
620   return 0;                                       592   return 0;
621 }                                                 593 }
622                                                   594 
623 //....oooOO0OOooo........oooOO0OOooo........oo    595 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
624                                                   596 
625 // The following section is not used anymore b    597 // The following section is not used anymore but is kept for memory
626 // GetAngularDistribution()->SampleDirectionFo    598 // GetAngularDistribution()->SampleDirectionForShell is used instead
627                                                   599 
628 /*void G4MicroElecInelasticModel::RandomizeEje    600 /*void G4MicroElecInelasticModel::RandomizeEjectedElectronDirection(G4ParticleDefinition* particleDefinition,
629  G4double k,                                      601  G4double k,
630  G4double secKinetic,                             602  G4double secKinetic,
631  G4double & cosTheta,                             603  G4double & cosTheta,
632  G4double & phi )                                 604  G4double & phi )
633  {                                                605  {
634  if (particleDefinition == G4Electron::Electro    606  if (particleDefinition == G4Electron::ElectronDefinition())
635  {                                                607  {
636  phi = twopi * G4UniformRand();                   608  phi = twopi * G4UniformRand();
637  G4double sin2O = (1.-secKinetic/k) / (1.+secK    609  G4double sin2O = (1.-secKinetic/k) / (1.+secKinetic/(2.*electron_mass_c2));
638  cosTheta = std::sqrt(1.-sin2O);                  610  cosTheta = std::sqrt(1.-sin2O);
639  }                                                611  }
640                                                   612  
641  if (particleDefinition == G4Proton::ProtonDef    613  if (particleDefinition == G4Proton::ProtonDefinition())
642  {                                                614  {
643  G4double maxSecKinetic = 4.* (electron_mass_c    615  G4double maxSecKinetic = 4.* (electron_mass_c2 / proton_mass_c2) * k;
644  phi = twopi * G4UniformRand();                   616  phi = twopi * G4UniformRand();
645  cosTheta = std::sqrt(secKinetic / maxSecKinet    617  cosTheta = std::sqrt(secKinetic / maxSecKinetic);
646  }                                                618  }
647                                                   619  
648  else                                             620  else
649  {                                                621  {
650  G4double maxSecKinetic = 4.* (electron_mass_c    622  G4double maxSecKinetic = 4.* (electron_mass_c2 / particleDefinition->GetPDGMass()) * k;
651  phi = twopi * G4UniformRand();                   623  phi = twopi * G4UniformRand();
652  cosTheta = std::sqrt(secKinetic / maxSecKinet    624  cosTheta = std::sqrt(secKinetic / maxSecKinetic);
653  }                                                625  }
654  }                                                626  }
655  */                                               627  */
656                                                   628 
657 //....oooOO0OOooo........oooOO0OOooo........oo    629 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
658                                                   630 
659 G4double G4MicroElecInelasticModel::Differenti << 631 double G4MicroElecInelasticModel::DifferentialCrossSection(G4ParticleDefinition * particleDefinition,
660                                                   632                                                            G4double k,
661                                                   633                                                            G4double energyTransfer,
662                                                   634                                                            G4int LevelIndex)
663 {                                                 635 {
664   G4double sigma = 0.;                            636   G4double sigma = 0.;
665                                                   637   
666   if (energyTransfer >= SiStructure.Energy(Lev    638   if (energyTransfer >= SiStructure.Energy(LevelIndex))
667   {                                               639   {
668     G4double valueT1 = 0;                         640     G4double valueT1 = 0;
669     G4double valueT2 = 0;                         641     G4double valueT2 = 0;
670     G4double valueE21 = 0;                        642     G4double valueE21 = 0;
671     G4double valueE22 = 0;                        643     G4double valueE22 = 0;
672     G4double valueE12 = 0;                        644     G4double valueE12 = 0;
673     G4double valueE11 = 0;                        645     G4double valueE11 = 0;
674                                                   646     
675     G4double xs11 = 0;                            647     G4double xs11 = 0;
676     G4double xs12 = 0;                            648     G4double xs12 = 0;
677     G4double xs21 = 0;                            649     G4double xs21 = 0;
678     G4double xs22 = 0;                            650     G4double xs22 = 0;
679                                                   651     
680     if (particleDefinition == G4Electron::Elec    652     if (particleDefinition == G4Electron::ElectronDefinition())
681     {                                             653     {
682       // k should be in eV and energy transfer << 654       // k should be in eV and energy transfer eV also
683       auto t2 = std::upper_bound(eTdummyVec.be << 655       
684       auto t1 = t2-1;                          << 656       std::vector<double>::iterator t2 = std::upper_bound(eTdummyVec.begin(),eTdummyVec.end(), k);
685       // The following condition avoids situat << 657       std::vector<double>::iterator t1 = t2-1;
                                                   >> 658       // SI : the following condition avoids situations where energyTransfer >last vector element
686       if (energyTransfer <= eVecm[(*t1)].back(    659       if (energyTransfer <= eVecm[(*t1)].back() && energyTransfer <= eVecm[(*t2)].back() )
687       {                                           660       {
688         auto e12 = std::upper_bound(eVecm[(*t1 << 661         std::vector<double>::iterator e12 = std::upper_bound(eVecm[(*t1)].begin(),eVecm[(*t1)].end(), energyTransfer);
689         auto e11 = e12-1;                      << 662         std::vector<double>::iterator e11 = e12-1;
690         auto e22 = std::upper_bound(eVecm[(*t2 << 663         
691         auto e21 = e22-1;                      << 664         std::vector<double>::iterator e22 = std::upper_bound(eVecm[(*t2)].begin(),eVecm[(*t2)].end(), energyTransfer);
                                                   >> 665         std::vector<double>::iterator e21 = e22-1;
692                                                   666         
693         valueT1  =*t1;                            667         valueT1  =*t1;
694         valueT2  =*t2;                            668         valueT2  =*t2;
695         valueE21 =*e21;                           669         valueE21 =*e21;
696         valueE22 =*e22;                           670         valueE22 =*e22;
697         valueE12 =*e12;                           671         valueE12 =*e12;
698         valueE11 =*e11;                           672         valueE11 =*e11;
699                                                   673         
700         xs11 = eDiffCrossSectionData[LevelInde    674         xs11 = eDiffCrossSectionData[LevelIndex][valueT1][valueE11];
701         xs12 = eDiffCrossSectionData[LevelInde    675         xs12 = eDiffCrossSectionData[LevelIndex][valueT1][valueE12];
702         xs21 = eDiffCrossSectionData[LevelInde    676         xs21 = eDiffCrossSectionData[LevelIndex][valueT2][valueE21];
703         xs22 = eDiffCrossSectionData[LevelInde    677         xs22 = eDiffCrossSectionData[LevelIndex][valueT2][valueE22];
704       }                                        << 678       }
                                                   >> 679       
705     }                                             680     }
706                                                   681     
707     if (particleDefinition == G4Proton::Proton    682     if (particleDefinition == G4Proton::ProtonDefinition())
708     {                                             683     {
709       // k should be in eV and energy transfer    684       // k should be in eV and energy transfer eV also
710       auto t2 = std::upper_bound(pTdummyVec.be << 685       std::vector<double>::iterator t2 = std::upper_bound(pTdummyVec.begin(),pTdummyVec.end(), k);
711       auto t1 = t2-1;                          << 686       std::vector<double>::iterator t1 = t2-1;
712       if (energyTransfer <= pVecm[(*t1)].back(    687       if (energyTransfer <= pVecm[(*t1)].back() && energyTransfer <= pVecm[(*t2)].back() )
713       {                                           688       {
714         auto e12 = std::upper_bound(pVecm[(*t1 << 689         std::vector<double>::iterator e12 = std::upper_bound(pVecm[(*t1)].begin(),pVecm[(*t1)].end(), energyTransfer);
715         auto e11 = e12-1;                      << 690         std::vector<double>::iterator e11 = e12-1;
716                                                   691         
717         auto e22 = std::upper_bound(pVecm[(*t2 << 692         std::vector<double>::iterator e22 = std::upper_bound(pVecm[(*t2)].begin(),pVecm[(*t2)].end(), energyTransfer);
718         auto e21 = e22-1;                      << 693         std::vector<double>::iterator e21 = e22-1;
719                                                   694         
720         valueT1  =*t1;                            695         valueT1  =*t1;
721         valueT2  =*t2;                            696         valueT2  =*t2;
722         valueE21 =*e21;                           697         valueE21 =*e21;
723         valueE22 =*e22;                           698         valueE22 =*e22;
724         valueE12 =*e12;                           699         valueE12 =*e12;
725         valueE11 =*e11;                           700         valueE11 =*e11;
726                                                   701         
727         xs11 = pDiffCrossSectionData[LevelInde    702         xs11 = pDiffCrossSectionData[LevelIndex][valueT1][valueE11];
728         xs12 = pDiffCrossSectionData[LevelInde    703         xs12 = pDiffCrossSectionData[LevelIndex][valueT1][valueE12];
729         xs21 = pDiffCrossSectionData[LevelInde    704         xs21 = pDiffCrossSectionData[LevelIndex][valueT2][valueE21];
730         xs22 = pDiffCrossSectionData[LevelInde    705         xs22 = pDiffCrossSectionData[LevelIndex][valueT2][valueE22];
731       }                                           706       }
732     }                                             707     }
733                                                   708     
734     sigma = QuadInterpolator(     valueE11, va << 709     G4double xsProduct = xs11 * xs12 * xs21 * xs22;
735           valueE21, valueE22,                  << 710     if (xsProduct != 0.)
736           xs11, xs12,                          << 711     {
737           xs21, xs22,                          << 712       sigma = QuadInterpolator(     valueE11, valueE12,
738           valueT1, valueT2,                    << 713                                valueE21, valueE22,
739           k, energyTransfer);                  << 714                                xs11, xs12,
                                                   >> 715                                xs21, xs22,
                                                   >> 716                                valueT1, valueT2,
                                                   >> 717                                k, energyTransfer);
                                                   >> 718     }
                                                   >> 719     
740   }                                               720   }
                                                   >> 721   
741   return sigma;                                   722   return sigma;
742 }                                                 723 }
743                                                   724 
744 //....oooOO0OOooo........oooOO0OOooo........oo    725 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
745                                                   726 
746 G4double G4MicroElecInelasticModel::Interpolat << 727 G4double G4MicroElecInelasticModel::LogLogInterpolate(G4double e1,
747                                                << 728                                                       G4double e2,
748                                                << 729                                                       G4double e,
749                                                << 730                                                       G4double xs1,
750                                                << 731                                                       G4double xs2)
751 {                                              << 732 {
752   G4double value = 0.;                         << 733   G4double a = (std::log10(xs2)-std::log10(xs1)) / (std::log10(e2)-std::log10(e1));
753                                                << 734   G4double b = std::log10(xs2) - a*std::log10(e2);
754   // Log-log interpolation by default          << 735   G4double sigma = a*std::log10(e) + b;
755   if (e1 != 0 && e2 != 0 && (std::log10(e2) -  << 736   G4double value = (std::pow(10.,sigma));
756       && !fasterCode)                          << 
757   {                                            << 
758     G4double a = (std::log10(xs2)-std::log10(x << 
759     G4double b = std::log10(xs2) - a*std::log1 << 
760     G4double sigma = a*std::log10(e) + b;      << 
761     value = (std::pow(10.,sigma));             << 
762                                                << 
763   }                                            << 
764                                                << 
765   // Switch to log-lin interpolation for faste << 
766   if ((e2 - e1) != 0 && xs1 != 0 && xs2 != 0 & << 
767   {                                            << 
768     G4double d1 = std::log10(xs1);             << 
769     G4double d2 = std::log10(xs2);             << 
770     value = std::pow(10., (d1 + (d2 - d1) * (e << 
771   }                                            << 
772                                                << 
773   // Switch to lin-lin interpolation for faste << 
774   // in case one of xs1 or xs2 (=cum proba) va << 
775   if ((e2 - e1) != 0 && (xs1 == 0 || xs2 == 0) << 
776   {                                            << 
777     G4double d1 = xs1;                         << 
778     G4double d2 = xs2;                         << 
779     value = (d1 + (d2 - d1) * (e - e1) / (e2 - << 
780   }                                            << 
781                                                << 
782   return value;                                   737   return value;
783 }                                                 738 }
784                                                   739 
785 //....oooOO0OOooo........oooOO0OOooo........oo    740 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
786                                                   741 
787 G4double G4MicroElecInelasticModel::QuadInterp    742 G4double G4MicroElecInelasticModel::QuadInterpolator(G4double e11, G4double e12,
788                                                   743                                                      G4double e21, G4double e22,
789                                                   744                                                      G4double xs11, G4double xs12,
790                                                   745                                                      G4double xs21, G4double xs22,
791                                                   746                                                      G4double t1, G4double t2,
792                                                   747                                                      G4double t, G4double e)
793 {                                                 748 {
794   G4double interpolatedvalue1 = Interpolate(e1 << 749   G4double interpolatedvalue1 = LogLogInterpolate(e11, e12, e, xs11, xs12);
795   G4double interpolatedvalue2 = Interpolate(e2 << 750   G4double interpolatedvalue2 = LogLogInterpolate(e21, e22, e, xs21, xs22);
796   G4double value = Interpolate(t1, t2, t, inte << 751   G4double value = LogLogInterpolate(t1, t2, t, interpolatedvalue1, interpolatedvalue2);
797   return value;                                   752   return value;
798 }                                                 753 }
799                                                   754 
800 //....oooOO0OOooo........oooOO0OOooo........oo    755 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
801                                                   756 
802 G4int G4MicroElecInelasticModel::RandomSelect(    757 G4int G4MicroElecInelasticModel::RandomSelect(G4double k, const G4String& particle )
803 {                                                 758 {
804   G4int level = 0;                                759   G4int level = 0;
805                                                << 760   
806   auto pos = tableData.find(particle);         << 761   std::map< G4String,G4MicroElecCrossSectionDataSet*,std::less<G4String> >::iterator pos;
807   if (pos != tableData.cend())                 << 762   pos = tableData.find(particle);
                                                   >> 763   
                                                   >> 764   if (pos != tableData.end())
808   {                                               765   {
809     G4MicroElecCrossSectionDataSet* table = po    766     G4MicroElecCrossSectionDataSet* table = pos->second;
810                                                   767     
811     if (table != nullptr)                      << 768     if (table != 0)
812     {                                             769     {
813       G4double* valuesBuffer = new G4double[ta    770       G4double* valuesBuffer = new G4double[table->NumberOfComponents()];
814       const G4int n = (G4int)table->NumberOfCo << 771       const size_t n(table->NumberOfComponents());
815       G4int i(n);                              << 772       size_t i(n);
816       G4double value = 0.;                        773       G4double value = 0.;
817                                                   774       
818       while (i>0)                                 775       while (i>0)
819       {                                           776       {
820         --i;                                   << 777         i--;
821         valuesBuffer[i] = table->GetComponent(    778         valuesBuffer[i] = table->GetComponent(i)->FindValue(k);
822         value += valuesBuffer[i];                 779         value += valuesBuffer[i];
823       }                                           780       }
824                                                   781       
825       value *= G4UniformRand();                   782       value *= G4UniformRand();
826                                                   783       
827       i = n;                                      784       i = n;
828                                                   785       
829       while (i > 0)                               786       while (i > 0)
830       {                                           787       {
831         --i;                                   << 788         i--;
832                                                   789         
833         if (valuesBuffer[i] > value)              790         if (valuesBuffer[i] > value)
834         {                                         791         {
835           delete[] valuesBuffer;                  792           delete[] valuesBuffer;
836           return i;                               793           return i;
837         }                                         794         }
838         value -= valuesBuffer[i];                 795         value -= valuesBuffer[i];
839       }                                           796       }
840                                                   797       
841       if (valuesBuffer) delete[] valuesBuffer;    798       if (valuesBuffer) delete[] valuesBuffer;
842                                                   799       
843     }                                             800     }
844   }                                               801   }
845   else                                            802   else
846   {                                               803   {
847     G4Exception("G4MicroElecInelasticModel::Ra    804     G4Exception("G4MicroElecInelasticModel::RandomSelect","em0002",FatalException,"Model not applicable to particle type.");
848   }                                               805   }
849                                                   806   
850   return level;                                   807   return level;
851 }                                                 808 }
852                                                   809 
853 //....oooOO0OOooo........oooOO0OOooo........oo    810 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
854                                                   811 
855 G4double G4MicroElecInelasticModel::RandomizeE << 
856                                                << 
857                                                << 
858 {                                              << 
859                                                << 
860   G4double secondaryElectronKineticEnergy = 0. << 
861   G4double random = G4UniformRand();           << 
862   secondaryElectronKineticEnergy = TransferedE << 
863                                                << 
864                                                << 
865                                                << 
866       - SiStructure.Energy(shell);             << 
867                                                << 
868   if (secondaryElectronKineticEnergy < 0.)     << 
869     return 0.;                                 << 
870   //                                           << 
871   return secondaryElectronKineticEnergy;       << 
872 }                                              << 
873                                                << 
874 //....oooOO0OOooo........oooOO0OOooo........oo << 
875                                                << 
876 G4double G4MicroElecInelasticModel::Transfered << 
877                                                << 
878                                                << 
879                                                << 
880 {                                              << 
881   G4double nrj = 0.;                           << 
882                                                << 
883   G4double valueK1 = 0;                        << 
884   G4double valueK2 = 0;                        << 
885   G4double valuePROB21 = 0;                    << 
886   G4double valuePROB22 = 0;                    << 
887   G4double valuePROB12 = 0;                    << 
888   G4double valuePROB11 = 0;                    << 
889                                                << 
890   G4double nrjTransf11 = 0;                    << 
891   G4double nrjTransf12 = 0;                    << 
892   G4double nrjTransf21 = 0;                    << 
893   G4double nrjTransf22 = 0;                    << 
894                                                << 
895   G4double maximumEnergyTransfer1 = 0;         << 
896   G4double maximumEnergyTransfer2 = 0;         << 
897   G4double maximumEnergyTransferP = 4.* (elect << 
898   G4double bindingEnergy = SiStructure.Energy( << 
899                                                << 
900   if (particleDefinition == G4Electron::Electr << 
901   {                                            << 
902     // k should be in eV                       << 
903     auto k2 = std::upper_bound(eTdummyVec.begi << 
904              eTdummyVec.end(),                 << 
905              k);                               << 
906     auto k1 = k2 - 1;                          << 
907                                                << 
908     /*                                         << 
909      G4cout << "----> k=" << k                 << 
910      << " " << *k1                             << 
911      << " " << *k2                             << 
912      << " " << random                          << 
913      << " " << ionizationLevelIndex            << 
914      << " " << eProbaShellMap[ionizationLevelI << 
915      << " " << eProbaShellMap[ionizationLevelI << 
916      << G4endl;                                << 
917      */                                        << 
918                                                << 
919     // SI : the following condition avoids sit << 
920     if (random <= eProbaShellMap[ionizationLev << 
921         && random <= eProbaShellMap[ionization << 
922     {                                          << 
923       auto prob12 =                            << 
924           std::upper_bound(eProbaShellMap[ioni << 
925                            eProbaShellMap[ioni << 
926                            random);            << 
927       auto prob11 = prob12 - 1;                << 
928       auto prob22 =                            << 
929           std::upper_bound(eProbaShellMap[ioni << 
930                            eProbaShellMap[ioni << 
931                            random);            << 
932       auto prob21 = prob22 - 1;                << 
933                                                << 
934       valueK1 = *k1;                           << 
935       valueK2 = *k2;                           << 
936       valuePROB21 = *prob21;                   << 
937       valuePROB22 = *prob22;                   << 
938       valuePROB12 = *prob12;                   << 
939       valuePROB11 = *prob11;                   << 
940                                                << 
941       // The following condition avoid getting << 
942       if(valuePROB11 == 0) nrjTransf11 = bindi << 
943       else nrjTransf11 = eNrjTransfData[ioniza << 
944       if(valuePROB12 == 1)                     << 
945       {                                        << 
946   if ((valueK1+bindingEnergy)/2. > valueK1) ma << 
947       else maximumEnergyTransfer1 = (valueK1+b << 
948                                                << 
949   nrjTransf12 = maximumEnergyTransfer1;        << 
950       }                                        << 
951       else nrjTransf12 = eNrjTransfData[ioniza << 
952                                                << 
953       if(valuePROB21 == 0) nrjTransf21 = bindi << 
954       else nrjTransf21 = eNrjTransfData[ioniza << 
955       if(valuePROB22 == 1)                     << 
956       {                                        << 
957   if ((valueK2+bindingEnergy)/2. > valueK2) ma << 
958       else maximumEnergyTransfer2 = (valueK2+b << 
959                                                << 
960   nrjTransf22 = maximumEnergyTransfer2;        << 
961       }                                        << 
962       else                                     << 
963   nrjTransf22 = eNrjTransfData[ionizationLevel << 
964     }                                          << 
965     // Avoids cases where cum xs is zero for k << 
966     if (random > eProbaShellMap[ionizationLeve << 
967     {                                          << 
968       auto prob22 =                            << 
969           std::upper_bound(eProbaShellMap[ioni << 
970                            eProbaShellMap[ioni << 
971                            random);            << 
972                                                << 
973       auto prob21 = prob22 - 1;                << 
974                                                << 
975       valueK1 = *k1;                           << 
976       valueK2 = *k2;                           << 
977       valuePROB21 = *prob21;                   << 
978       valuePROB22 = *prob22;                   << 
979                                                << 
980       nrjTransf21 = eNrjTransfData[ionizationL << 
981       nrjTransf22 = eNrjTransfData[ionizationL << 
982                                                << 
983       G4double interpolatedvalue2 = Interpolat << 
984                                                << 
985                                                << 
986                                                << 
987                                                << 
988                                                << 
989       // zeros are explicitly set              << 
990       G4double value = Interpolate(valueK1, va << 
991       return value;                            << 
992     }                                          << 
993   }                                            << 
994   //                                           << 
995   else if (particleDefinition == G4Proton::Pro << 
996   {                                            << 
997     // k should be in eV                       << 
998     auto k2 = std::upper_bound(pTdummyVec.begi << 
999              pTdummyVec.end(),                 << 
1000              k);                              << 
1001                                               << 
1002     auto k1 = k2 - 1;                         << 
1003                                               << 
1004     /*                                        << 
1005      G4cout << "----> k=" << k                << 
1006      << " " << *k1                            << 
1007      << " " << *k2                            << 
1008      << " " << random                         << 
1009      << " " << ionizationLevelIndex           << 
1010      << " " << pProbaShellMap[ionizationLevel << 
1011      << " " << pProbaShellMap[ionizationLevel << 
1012      << G4endl;                               << 
1013      */                                       << 
1014                                               << 
1015     // SI : the following condition avoids si << 
1016     //      for eg. when the last element is  << 
1017     if (random <= pProbaShellMap[ionizationLe << 
1018         && random <= pProbaShellMap[ionizatio << 
1019     {                                         << 
1020       auto prob12 =                           << 
1021           std::upper_bound(pProbaShellMap[ion << 
1022                            pProbaShellMap[ion << 
1023                            random);           << 
1024                                               << 
1025       auto prob11 = prob12 - 1;               << 
1026                                               << 
1027       auto prob22 =                           << 
1028   std::upper_bound(pProbaShellMap[ionizationL << 
1029        pProbaShellMap[ionizationLevelIndex][( << 
1030        random);                               << 
1031                                               << 
1032       auto prob21 = prob22 - 1;               << 
1033                                               << 
1034       valueK1 = *k1;                          << 
1035       valueK2 = *k2;                          << 
1036       valuePROB21 = *prob21;                  << 
1037       valuePROB22 = *prob22;                  << 
1038       valuePROB12 = *prob12;                  << 
1039       valuePROB11 = *prob11;                  << 
1040                                               << 
1041       // The following condition avoid gettin << 
1042       if(valuePROB11 == 0) nrjTransf11 = bind << 
1043       else nrjTransf11 = pNrjTransfData[ioniz << 
1044       if(valuePROB12 == 1) nrjTransf12 = maxi << 
1045       else nrjTransf12 = pNrjTransfData[ioniz << 
1046       if(valuePROB21 == 0) nrjTransf21 = bind << 
1047       else nrjTransf21 = pNrjTransfData[ioniz << 
1048       if(valuePROB22 == 1) nrjTransf22 = maxi << 
1049       else nrjTransf22 = pNrjTransfData[ioniz << 
1050                                               << 
1051     }                                         << 
1052                                               << 
1053     // Avoids cases where cum xs is zero for  << 
1054     if (random > pProbaShellMap[ionizationLev << 
1055     {                                         << 
1056       auto prob22 =                           << 
1057           std::upper_bound(pProbaShellMap[ion << 
1058                            pProbaShellMap[ion << 
1059                            random);           << 
1060                                               << 
1061       auto prob21 = prob22 - 1;               << 
1062                                               << 
1063       valueK1 = *k1;                          << 
1064       valueK2 = *k2;                          << 
1065       valuePROB21 = *prob21;                  << 
1066       valuePROB22 = *prob22;                  << 
1067                                               << 
1068       nrjTransf21 = pNrjTransfData[ionization << 
1069       nrjTransf22 = pNrjTransfData[ionization << 
1070                                               << 
1071       G4double interpolatedvalue2 = Interpola << 
1072                                               << 
1073                                               << 
1074                                               << 
1075                                               << 
1076                                               << 
1077       // zeros are explicitly set             << 
1078       G4double value = Interpolate(valueK1, v << 
1079                                               << 
1080       return value;                           << 
1081     }                                         << 
1082   }                                           << 
1083   // End electron and proton cases            << 
1084                                               << 
1085   G4double nrjTransfProduct = nrjTransf11 * n << 
1086       * nrjTransf22;                          << 
1087                                               << 
1088   if (nrjTransfProduct != 0.)                 << 
1089   {                                           << 
1090     nrj = QuadInterpolator(valuePROB11,       << 
1091                            valuePROB12,       << 
1092                            valuePROB21,       << 
1093                            valuePROB22,       << 
1094                            nrjTransf11,       << 
1095                            nrjTransf12,       << 
1096                            nrjTransf21,       << 
1097                            nrjTransf22,       << 
1098                            valueK1,           << 
1099                            valueK2,           << 
1100                            k,                 << 
1101                            random);           << 
1102   }                                           << 
1103                                               << 
1104   return nrj;                                 << 
1105 }                                             << 
1106                                                  812 
1107                                                  813 
1108                                                  814