Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/electromagnetic/lowenergy/src/G4MicroElecInelasticModel_new.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_new.cc (Version 11.3.0) and /processes/electromagnetic/lowenergy/src/G4MicroElecInelasticModel_new.cc (Version 11.1.3)


  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_new.cc, 2011/08/2     27 // G4MicroElecInelasticModel_new.cc, 2011/08/29 A.Valentin, M. Raine are with CEA [a]
 28 //                          2020/05/20 P. Caro     28 //                          2020/05/20 P. Caron, C. Inguimbert are with ONERA [b] 
 29 //                   Q. Gibaru is with CEA [a]     29 //                   Q. Gibaru is with CEA [a], ONERA [b] and CNES [c]
 30 //                   M. Raine and D. Lambert a     30 //                   M. Raine and D. Lambert are with CEA [a]
 31 //                                                 31 //
 32 // A part of this work has been funded by the      32 // A part of this work has been funded by the French space agency(CNES[c])
 33 // [a] CEA, DAM, DIF - 91297 ARPAJON, France       33 // [a] CEA, DAM, DIF - 91297 ARPAJON, France
 34 // [b] ONERA - DPHY, 2 avenue E.Belin, 31055 T     34 // [b] ONERA - DPHY, 2 avenue E.Belin, 31055 Toulouse, France
 35 // [c] CNES, 18 av.E.Belin, 31401 Toulouse CED     35 // [c] CNES, 18 av.E.Belin, 31401 Toulouse CEDEX, France
 36 //                                                 36 //
 37 // Based on the following publications             37 // Based on the following publications
 38 //  - A.Valentin, M. Raine,                        38 //  - A.Valentin, M. Raine, 
 39 //    Inelastic cross-sections of low energy e     39 //    Inelastic cross-sections of low energy electrons in silicon
 40 //        for the simulation of heavy ion trac     40 //        for the simulation of heavy ion tracks with the Geant4-DNA toolkit,
 41 //        NSS Conf. Record 2010, pp. 80-85         41 //        NSS Conf. Record 2010, pp. 80-85
 42 //             https://doi.org/10.1109/NSSMIC.     42 //             https://doi.org/10.1109/NSSMIC.2010.5873720
 43 //                                                 43 //
 44 //      - A.Valentin, M. Raine, M.Gaillardin,      44 //      - A.Valentin, M. Raine, M.Gaillardin, P.Paillet
 45 //        Geant4 physics processes for microdo     45 //        Geant4 physics processes for microdosimetry simulation:
 46 //        very low energy electromagnetic mode     46 //        very low energy electromagnetic models for electrons in Silicon,
 47 //             https://doi.org/10.1016/j.nimb.     47 //             https://doi.org/10.1016/j.nimb.2012.06.007
 48 //        NIM B, vol. 288, pp. 66-73, 2012, pa     48 //        NIM B, vol. 288, pp. 66-73, 2012, part A
 49 //        heavy ions in Si, NIM B, vol. 287, p     49 //        heavy ions in Si, NIM B, vol. 287, pp. 124-129, 2012, part B
 50 //             https://doi.org/10.1016/j.nimb.     50 //             https://doi.org/10.1016/j.nimb.2012.07.028
 51 //                                                 51 //
 52 //  - M. Raine, M. Gaillardin, P. Paillet          52 //  - M. Raine, M. Gaillardin, P. Paillet
 53 //        Geant4 physics processes for silicon     53 //        Geant4 physics processes for silicon microdosimetry simulation: 
 54 //        Improvements and extension of the en     54 //        Improvements and extension of the energy-range validity up to 10 GeV/nucleon
 55 //        NIM B, vol. 325, pp. 97-100, 2014        55 //        NIM B, vol. 325, pp. 97-100, 2014
 56 //             https://doi.org/10.1016/j.nimb.     56 //             https://doi.org/10.1016/j.nimb.2014.01.014
 57 //                                                 57 //
 58 //      - J. Pierron, C. Inguimbert, M. Belhaj     58 //      - J. Pierron, C. Inguimbert, M. Belhaj, T. Gineste, J. Puech, M. Raine
 59 //        Electron emission yield for low ener     59 //        Electron emission yield for low energy electrons: 
 60 //        Monte Carlo simulation and experimen     60 //        Monte Carlo simulation and experimental comparison for Al, Ag, and Si
 61 //        Journal of Applied Physics 121 (2017     61 //        Journal of Applied Physics 121 (2017) 215107. 
 62 //               https://doi.org/10.1063/1.498     62 //               https://doi.org/10.1063/1.4984761
 63 //                                                 63 //
 64 //      - P. Caron,                                64 //      - P. Caron,
 65 //        Study of Electron-Induced Single-Eve     65 //        Study of Electron-Induced Single-Event Upset in Integrated Memory Devices
 66 //        PHD, 16th October 2019                   66 //        PHD, 16th October 2019
 67 //                                                 67 //
 68 //  - Q.Gibaru, C.Inguimbert, P.Caron, M.Raine     68 //  - Q.Gibaru, C.Inguimbert, P.Caron, M.Raine, D.Lambert, J.Puech, 
 69 //        Geant4 physics processes for microdo     69 //        Geant4 physics processes for microdosimetry and secondary electron emission simulation : 
 70 //        Extension of MicroElec to very low e     70 //        Extension of MicroElec to very low energies and new materials
 71 //        NIM B, 2020, in review.                  71 //        NIM B, 2020, in review.
 72 //                                                 72 //
 73 //                                                 73 //
 74 //....oooOO0OOooo........oooOO0OOooo........oo     74 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 
 75                                                    75 
 76                                                    76 
 77 #include "globals.hh"                              77 #include "globals.hh"
 78 #include "G4MicroElecInelasticModel_new.hh"    <<  78 #include "G4MicroElecInelasticModel_new.hh"
 79 #include "G4PhysicalConstants.hh"                  79 #include "G4PhysicalConstants.hh"
 80 #include "G4SystemOfUnits.hh"                      80 #include "G4SystemOfUnits.hh"
 81 #include "G4ios.hh"                                81 #include "G4ios.hh"
 82 #include "G4UnitsTable.hh"                         82 #include "G4UnitsTable.hh"
 83 #include "G4UAtomicDeexcitation.hh"                83 #include "G4UAtomicDeexcitation.hh"
 84 #include "G4LossTableManager.hh"                   84 #include "G4LossTableManager.hh"
 85 #include "G4ionEffectiveCharge.hh"                 85 #include "G4ionEffectiveCharge.hh"
 86 #include "G4MicroElecMaterialStructure.hh"         86 #include "G4MicroElecMaterialStructure.hh"
 87 #include "G4DeltaAngle.hh"                         87 #include "G4DeltaAngle.hh"
 88                                                    88 
 89 #include <sstream>                                 89 #include <sstream>
 90                                                    90 
 91 //....oooOO0OOooo........oooOO0OOooo........oo     91 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 92                                                    92 
 93 using namespace std;                               93 using namespace std;
 94                                                    94 
 95 //....oooOO0OOooo........oooOO0OOooo........oo     95 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 96                                                    96 
 97 G4MicroElecInelasticModel_new::G4MicroElecInel     97 G4MicroElecInelasticModel_new::G4MicroElecInelasticModel_new(
 98        const G4ParticleDefinition*, const G4St     98        const G4ParticleDefinition*, const G4String& nam)
 99   :G4VEmModel(nam),isInitialised(false)            99   :G4VEmModel(nam),isInitialised(false)
100 {                                                 100 {
101                                                   101   
102   verboseLevel= 0;                                102   verboseLevel= 0;
103   // Verbosity scale:                             103   // Verbosity scale:
104   // 0 = nothing                                  104   // 0 = nothing
105   // 1 = warning for energy non-conservation      105   // 1 = warning for energy non-conservation
106   // 2 = details of energy budget                 106   // 2 = details of energy budget
107   // 3 = calculation of cross sections, file o    107   // 3 = calculation of cross sections, file openings, sampling of atoms
108   // 4 = entering in methods                      108   // 4 = entering in methods
109                                                   109   
110   if( verboseLevel>0 )                            110   if( verboseLevel>0 )
111   {                                               111   {
112     G4cout << "MicroElec inelastic model is co    112     G4cout << "MicroElec inelastic model is constructed " << G4endl;
113   }                                               113   }
114                                                   114   
115   //Mark this model as "applicable" for atomic    115   //Mark this model as "applicable" for atomic deexcitation
116   SetDeexcitationFlag(true);                      116   SetDeexcitationFlag(true);
117   fAtomDeexcitation = nullptr;                    117   fAtomDeexcitation = nullptr;
118   fParticleChangeForGamma = nullptr;              118   fParticleChangeForGamma = nullptr;
119                                                   119   
120   // default generator                            120   // default generator
121   SetAngularDistribution(new G4DeltaAngle());     121   SetAngularDistribution(new G4DeltaAngle());
122                                                   122 
123   // Selection of computation method              123   // Selection of computation method
124   fasterCode = true;                              124   fasterCode = true;
125   SEFromFermiLevel = false;                       125   SEFromFermiLevel = false;
126 }                                                 126 }
127                                                   127 
128 //....oooOO0OOooo........oooOO0OOooo........oo    128 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
129                                                   129 
130 G4MicroElecInelasticModel_new::~G4MicroElecIne    130 G4MicroElecInelasticModel_new::~G4MicroElecInelasticModel_new()
131 {                                                 131 {
132   // Cross section                                132   // Cross section  
133   // (0)                                          133   // (0)
134   for (auto const& p : tableTCS) {             << 134   TCSMap::iterator pos2;
135     MapData* tableData = p.second;             << 135   for (pos2 = tableTCS.begin(); pos2 != tableTCS.end(); ++pos2) {
136     for (auto const& pos : *tableData) { delet << 136     MapData* tableData = pos2->second;
                                                   >> 137     for (auto pos = tableData->begin(); pos != tableData->end(); ++pos)
                                                   >> 138       {
                                                   >> 139   G4MicroElecCrossSectionDataSet_new* table = pos->second;
                                                   >> 140   delete table;
                                                   >> 141       }
137     delete tableData;                             142     delete tableData;
138   }                                               143   }
139   tableTCS.clear();                               144   tableTCS.clear();
140                                                << 145     
                                                   >> 146   dataDiffCSMap::iterator iterator_proba;  
141   // (1)                                          147   // (1)
142   for (auto const & obj : eDiffDatatable) {    << 148   for (iterator_proba = eNrjTransStorage.begin(); iterator_proba != eNrjTransStorage.end(); ++iterator_proba) {
143     auto ptr = obj.second;                     << 149     vector<TriDimensionMap>* eNrjTransfData = iterator_proba->second;
144     ptr->clear();                              << 150     eNrjTransfData->clear();
145     delete ptr;                                << 151     delete eNrjTransfData;
146   }                                               152   }
                                                   >> 153   eNrjTransStorage.clear();
147                                                   154   
148   for (auto const & obj : pDiffDatatable) {    << 155   for (iterator_proba = pNrjTransStorage.begin(); iterator_proba != pNrjTransStorage.end(); ++iterator_proba) {
149     auto ptr = obj.second;                     << 156     vector<TriDimensionMap>* pNrjTransfData = iterator_proba->second;
150     ptr->clear();                              << 157     pNrjTransfData->clear();
151     delete ptr;                                << 158     delete pNrjTransfData;
152   }                                               159   }
153                                                << 160   pNrjTransStorage.clear();
                                                   >> 161   
154   // (2)                                          162   // (2)
155   for (auto const & obj : eNrjTransStorage) {  << 163   for (iterator_proba = eDiffDatatable.begin(); iterator_proba != eDiffDatatable.end(); ++iterator_proba) {
156     delete obj.second;                         << 164     vector<TriDimensionMap>* eDiffCrossSectionData = iterator_proba->second;
157   }                                            << 165     eDiffCrossSectionData->clear();
158   for (auto const & obj : pNrjTransStorage) {  << 166     delete eDiffCrossSectionData;
159     delete obj.second;                         << 
160   }                                               167   }
                                                   >> 168   eDiffDatatable.clear();
161                                                   169 
                                                   >> 170   for (iterator_proba = pDiffDatatable.begin(); iterator_proba != pDiffDatatable.end(); ++iterator_proba) {
                                                   >> 171     vector<TriDimensionMap>* pDiffCrossSectionData = iterator_proba->second;
                                                   >> 172     pDiffCrossSectionData->clear();
                                                   >> 173     delete pDiffCrossSectionData;
                                                   >> 174   }
                                                   >> 175   pDiffDatatable.clear();
                                                   >> 176   
162   // (3)                                          177   // (3)
163   for (auto const& p : eProbaShellStorage) {   << 178   dataProbaShellMap::iterator iterator_probaShell;
164     delete p.second;                           << 179   
                                                   >> 180   for (iterator_probaShell = eProbaShellStorage.begin(); iterator_probaShell != eProbaShellStorage.end(); ++iterator_probaShell) {
                                                   >> 181     vector<VecMap>* eProbaShellMap = iterator_probaShell->second;
                                                   >> 182     eProbaShellMap->clear();
                                                   >> 183     delete eProbaShellMap;
165   }                                               184   }
166                                                << 185   eProbaShellStorage.clear();
167   for (auto const& p : pProbaShellStorage) {   << 186   
168     delete p.second;                           << 187   for (iterator_probaShell = pProbaShellStorage.begin(); iterator_probaShell != pProbaShellStorage.end(); ++iterator_probaShell) {
                                                   >> 188     vector<VecMap>* pProbaShellMap = iterator_probaShell->second;
                                                   >> 189     pProbaShellMap->clear();
                                                   >> 190     delete pProbaShellMap;
169   }                                               191   }
                                                   >> 192   pProbaShellStorage.clear();
170                                                   193   
171   // (4)                                          194   // (4)
172   for (auto const& p : eIncidentEnergyStorage) << 195   TranfEnergyMap::iterator iterator_nrjtransf;
173     delete p.second;                           << 196   for (iterator_nrjtransf = eVecmStorage.begin(); iterator_nrjtransf != eVecmStorage.end(); ++iterator_nrjtransf) {
                                                   >> 197     VecMap* eVecm = iterator_nrjtransf->second;
                                                   >> 198     eVecm->clear();
                                                   >> 199     delete eVecm;
174   }                                               200   }
175                                                << 201   eVecmStorage.clear();
176   for (auto const& p : pIncidentEnergyStorage) << 202   for (iterator_nrjtransf = pVecmStorage.begin(); iterator_nrjtransf != pVecmStorage.end(); ++iterator_nrjtransf) {
177     delete p.second;                           << 203     VecMap* pVecm = iterator_nrjtransf->second;
                                                   >> 204     pVecm->clear();
                                                   >> 205     delete pVecm;
178   }                                               206   }
179                                                << 207   pVecmStorage.clear();
                                                   >> 208   
180   // (5)                                          209   // (5)
181   for (auto const& p : eVecmStorage) {         << 210   incidentEnergyMap::iterator iterator_energy;
182     delete p.second;                           << 211   for (iterator_energy = eIncidentEnergyStorage.begin(); iterator_energy != eIncidentEnergyStorage.end(); ++iterator_energy) {
                                                   >> 212     std::vector<G4double>* eTdummyVec = iterator_energy->second;
                                                   >> 213     eTdummyVec->clear();
                                                   >> 214     delete eTdummyVec;
183   }                                               215   }
184                                                << 216   eIncidentEnergyStorage.clear();
185   for (auto const& p : pVecmStorage) {         << 217   
186     delete p.second;                           << 218   for (iterator_energy = pIncidentEnergyStorage.begin(); iterator_energy != pIncidentEnergyStorage.end(); ++iterator_energy) {
                                                   >> 219     std::vector<G4double>* pTdummyVec = iterator_energy->second;
                                                   >> 220     pTdummyVec->clear();
                                                   >> 221     delete pTdummyVec;
187   }                                               222   }
188                                                << 223   pIncidentEnergyStorage.clear();
                                                   >> 224   
189   // (6)                                          225   // (6)
190   for (auto const& p : tableMaterialsStructure << 226   MapStructure::iterator iterator_matStructure;
191     delete p.second;                           << 227   for (iterator_matStructure = tableMaterialsStructures.begin(); 
                                                   >> 228        iterator_matStructure != tableMaterialsStructures.end(); ++iterator_matStructure) {
                                                   >> 229     currentMaterialStructure = iterator_matStructure->second;
                                                   >> 230     delete currentMaterialStructure;
192   }                                               231   }
                                                   >> 232   tableMaterialsStructures.clear();
                                                   >> 233   currentMaterialStructure = nullptr;
193 }                                                 234 }
194                                                   235 
195 //....oooOO0OOooo........oooOO0OOooo........oo    236 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
196                                                   237 
197 void G4MicroElecInelasticModel_new::Initialise    238 void G4MicroElecInelasticModel_new::Initialise(const G4ParticleDefinition* particle,
198             const G4DataVector& /*cuts*/)         239             const G4DataVector& /*cuts*/)
199 {                                                 240 {
200   if (isInitialised) { return; }                  241   if (isInitialised) { return; }
201                                                   242 
202   if (verboseLevel > 3)                           243   if (verboseLevel > 3)
203     G4cout << "Calling G4MicroElecInelasticMod    244     G4cout << "Calling G4MicroElecInelasticModel_new::Initialise()" << G4endl;
204                                                   245   
205   const char* path = G4FindDataDir("G4LEDATA")    246   const char* path = G4FindDataDir("G4LEDATA");
206   if (!path)                                      247   if (!path)
207     {                                             248     {
208       G4Exception("G4MicroElecElasticModel_new    249       G4Exception("G4MicroElecElasticModel_new::Initialise","em0006",FatalException,"G4LEDATA environment variable not set.");
209       return;                                     250       return;
210     }                                             251     }
211                                                   252   
212   G4String modelName = "mermin";                  253   G4String modelName = "mermin";
213   G4cout << "****************************" <<     254   G4cout << "****************************" << G4endl;
214   G4cout << modelName << " model loaded !" <<     255   G4cout << modelName << " model loaded !" << G4endl;
215                                                   256   
216   // Energy limits                                257   // Energy limits 
217   G4ParticleDefinition* electronDef = G4Electr    258   G4ParticleDefinition* electronDef = G4Electron::ElectronDefinition();
218   G4ParticleDefinition* protonDef = G4Proton::    259   G4ParticleDefinition* protonDef = G4Proton::ProtonDefinition();
219   G4String electron = electronDef->GetParticle    260   G4String electron = electronDef->GetParticleName();
220   G4String proton = protonDef->GetParticleName    261   G4String proton = protonDef->GetParticleName();
221                                                   262   
222   G4double scaleFactor = 1.0;                     263   G4double scaleFactor = 1.0;
223                                                   264   
224     // *** ELECTRON                               265     // *** ELECTRON 
225   lowEnergyLimit[electron] = 2 * eV;              266   lowEnergyLimit[electron] = 2 * eV;
226   highEnergyLimit[electron] = 10.0 * MeV;         267   highEnergyLimit[electron] = 10.0 * MeV;
227                                                   268   
228   // Cross section                                269   // Cross section
229   G4ProductionCutsTable* theCoupleTable = G4Pr    270   G4ProductionCutsTable* theCoupleTable = G4ProductionCutsTable::GetProductionCutsTable();
230   G4int numOfCouples = (G4int)theCoupleTable->    271   G4int numOfCouples = (G4int)theCoupleTable->GetTableSize();
231                                                   272   
232   for (G4int i = 0; i < numOfCouples; ++i) {      273   for (G4int i = 0; i < numOfCouples; ++i) {
233     const G4Material* material = theCoupleTabl    274     const G4Material* material = theCoupleTable->GetMaterialCutsCouple(i)->GetMaterial();
234     G4cout << "Material " << i + 1 << " / " <<    275     G4cout << "Material " << i + 1 << " / " << numOfCouples << " : " << material->GetName() << G4endl;
235     if (material->GetName() == "Vacuum") conti    276     if (material->GetName() == "Vacuum") continue;
236     G4String mat = material->GetName().substr(    277     G4String mat = material->GetName().substr(3, material->GetName().size()); 
237     MapData* tableData = new MapData;             278     MapData* tableData = new MapData;
238     currentMaterialStructure = new G4MicroElec    279     currentMaterialStructure = new G4MicroElecMaterialStructure(mat);
239                                                   280     
240     tableMaterialsStructures[mat] = currentMat    281     tableMaterialsStructures[mat] = currentMaterialStructure;
241     if (particle == electronDef) {                282     if (particle == electronDef) {
242       //TCS                                       283       //TCS
243       G4String fileElectron("Inelastic/" + mod    284       G4String fileElectron("Inelastic/" + modelName + "_sigma_inelastic_e-_" + mat);
244       G4cout << fileElectron << G4endl;           285       G4cout << fileElectron << G4endl;
245       G4MicroElecCrossSectionDataSet_new* tabl    286       G4MicroElecCrossSectionDataSet_new* tableE = new G4MicroElecCrossSectionDataSet_new(new G4LogLogInterpolation, MeV, scaleFactor);
246       tableE->LoadData(fileElectron);             287       tableE->LoadData(fileElectron);
247       tableData->insert(make_pair(electron, ta    288       tableData->insert(make_pair(electron, tableE));
248                                                   289       
249       // DCS                                      290       // DCS
250       std::ostringstream eFullFileName;           291       std::ostringstream eFullFileName;
251       if (fasterCode) {                           292       if (fasterCode) {
252   eFullFileName << path << "/microelec/Inelast    293   eFullFileName << path << "/microelec/Inelastic/cumulated_" + modelName + "_sigmadiff_inelastic_e-_" + mat + ".dat";
253   G4cout << "Faster code = true" << G4endl;       294   G4cout << "Faster code = true" << G4endl;
254   G4cout << "Inelastic/cumulated_" + modelName    295   G4cout << "Inelastic/cumulated_" + modelName + "_sigmadiff_inelastic_e-_" + mat + ".dat" << G4endl;
255       }                                           296       }
256       else {                                      297       else {
257   eFullFileName << path << "/microelec/Inelast    298   eFullFileName << path << "/microelec/Inelastic/" + modelName + "_sigmadiff_inelastic_e-_" + mat + ".dat";
258   G4cout << "Faster code = false" << G4endl;      299   G4cout << "Faster code = false" << G4endl;
259   G4cout << "Inelastic/" + modelName + "_sigma    300   G4cout << "Inelastic/" + modelName + "_sigmadiff_inelastic_e-_" + mat + ".dat" << G4endl;
260       }                                           301       }
261                                                   302       
262       std::ifstream eDiffCrossSection(eFullFil    303       std::ifstream eDiffCrossSection(eFullFileName.str().c_str());
263       if (!eDiffCrossSection)                     304       if (!eDiffCrossSection)
264   {                                               305   {
265     std::stringstream ss;                         306     std::stringstream ss;
266     ss << "Missing data " << eFullFileName.str    307     ss << "Missing data " << eFullFileName.str().c_str();
267     std::string sortieString = ss.str();          308     std::string sortieString = ss.str();
268                                                   309       
269     if (fasterCode) G4Exception("G4MicroElecIn    310     if (fasterCode) G4Exception("G4MicroElecInelasticModel_new::Initialise", "em0003",
270               FatalException, sortieString.c_s    311               FatalException, sortieString.c_str());
                                                   >> 312                             
271     else {                                        313     else {
272       G4Exception("G4MicroElecInelasticModel_n    314       G4Exception("G4MicroElecInelasticModel_new::Initialise", "em0003",
273       FatalException, "Missing data file:/micr    315       FatalException, "Missing data file:/microelec/sigmadiff_inelastic_e_Si.dat");
274     }                                             316     }   
275   }                                               317   }
276                                                   318       
277       // Clear the arrays for re-initializatio    319       // Clear the arrays for re-initialization case (MT mode)
278       // Octobre 22nd, 2014 - Melanie Raine       320       // Octobre 22nd, 2014 - Melanie Raine      
279       //Creating vectors of maps for DCS and C    321       //Creating vectors of maps for DCS and Cumulated DCS for the current material.
280       //Each vector is storing one map for eac    322       //Each vector is storing one map for each shell.      
281       G4bool isUsed1 = false;                  << 
282       vector<TriDimensionMap>* eDiffCrossSecti    323       vector<TriDimensionMap>* eDiffCrossSectionData = 
283   new vector<TriDimensionMap>; //Storage of [I    324   new vector<TriDimensionMap>; //Storage of [IncidentEnergy, TransfEnergy, DCS values], used in slower code
284       vector<TriDimensionMap>* eNrjTransfData     325       vector<TriDimensionMap>* eNrjTransfData = 
285   new vector<TriDimensionMap>; //Storage of po    326   new vector<TriDimensionMap>; //Storage of possible transfer energies by shell
286       vector<VecMap>* eProbaShellMap = new vec    327       vector<VecMap>* eProbaShellMap = new vector<VecMap>; //Storage of the vectors containing all cumulated DCS values for an initial energy, by shell
287       vector<G4double>* eTdummyVec = new vecto    328       vector<G4double>* eTdummyVec = new vector<G4double>; //Storage of incident energies for interpolation
288       VecMap* eVecm = new VecMap; //Transfered    329       VecMap* eVecm = new VecMap; //Transfered energy map for slower code
289                                                   330       
290       for (G4int j = 0; j < currentMaterialStr << 331       for (int j = 0; j < currentMaterialStructure->NumberOfLevels(); j++) //Filling the map vectors with an empty map for each shell
291   {                                               332   {
292     eDiffCrossSectionData->push_back(TriDimens    333     eDiffCrossSectionData->push_back(TriDimensionMap());
293     eNrjTransfData->push_back(TriDimensionMap(    334     eNrjTransfData->push_back(TriDimensionMap());
294     eProbaShellMap->push_back(VecMap());          335     eProbaShellMap->push_back(VecMap());
295   }                                               336   }
296                                                   337       
297       eTdummyVec->push_back(0.);                  338       eTdummyVec->push_back(0.);
298       while (!eDiffCrossSection.eof())            339       while (!eDiffCrossSection.eof())
299   {                                               340   {
300     G4double tDummy; //incident energy            341     G4double tDummy; //incident energy
301     G4double eDummy; //transfered energy          342     G4double eDummy; //transfered energy
302     eDiffCrossSection >> tDummy >> eDummy;        343     eDiffCrossSection >> tDummy >> eDummy;
303     if (tDummy != eTdummyVec->back()) eTdummyV    344     if (tDummy != eTdummyVec->back()) eTdummyVec->push_back(tDummy);
304                                                   345     
305     G4double tmp; //probability                   346     G4double tmp; //probability
306     for (G4int j = 0; j < currentMaterialStruc << 347     for (int j = 0; j < currentMaterialStructure->NumberOfLevels(); j++)
307       {                                           348       {
308         eDiffCrossSection >> tmp;                 349         eDiffCrossSection >> tmp;       
309         (*eDiffCrossSectionData)[j][tDummy][eD    350         (*eDiffCrossSectionData)[j][tDummy][eDummy] = tmp;
310                                                   351         
311         if (fasterCode)                           352         if (fasterCode)
312     {                                             353     {
313       (*eNrjTransfData)[j][tDummy][(*eDiffCros    354       (*eNrjTransfData)[j][tDummy][(*eDiffCrossSectionData)[j][tDummy][eDummy]] = eDummy;
314       (*eProbaShellMap)[j][tDummy].push_back((    355       (*eProbaShellMap)[j][tDummy].push_back((*eDiffCrossSectionData)[j][tDummy][eDummy]);
315     }                                             356     }
316         else {  // SI - only if eof is not rea    357         else {  // SI - only if eof is not reached !
317     (*eDiffCrossSectionData)[j][tDummy][eDummy << 358     if (!eDiffCrossSection.eof()) (*eDiffCrossSectionData)[j][tDummy][eDummy] *= scaleFactor;
318     (*eVecm)[tDummy].push_back(eDummy);           359     (*eVecm)[tDummy].push_back(eDummy);
319         }                                         360         }
320       }                                           361       }
321   }                                               362   }
322       //                                          363       //
323       //G4cout << "add to material vector" <<  << 364       G4cout << "add to material vector" << G4endl;
324                                                   365       
325       //Filing maps for the current material i    366       //Filing maps for the current material into the master maps
326       if (fasterCode) {                           367       if (fasterCode) {
327   isUsed1 = true;                              << 
328   eNrjTransStorage[mat] = eNrjTransfData;         368   eNrjTransStorage[mat] = eNrjTransfData;
329   eProbaShellStorage[mat] = eProbaShellMap;       369   eProbaShellStorage[mat] = eProbaShellMap;
330       }                                           370       }
331       else {                                      371       else {
332   eDiffDatatable[mat] = eDiffCrossSectionData;    372   eDiffDatatable[mat] = eDiffCrossSectionData;
333   eVecmStorage[mat] = eVecm;                      373   eVecmStorage[mat] = eVecm;
334       }                                           374       }
335       eIncidentEnergyStorage[mat] = eTdummyVec    375       eIncidentEnergyStorage[mat] = eTdummyVec;
336                                                   376 
337       //Cleanup support vectors                   377       //Cleanup support vectors
338       if (!isUsed1) {                          << 378       // delete eProbaShellMap;
339   delete eProbaShellMap;                       << 379       // delete eDiffCrossSectionData;
340         delete eNrjTransfData;                 << 380       // delete eNrjTransfData;
341       } else {                                 << 
342         delete eDiffCrossSectionData;          << 
343   delete eVecm;                                << 
344       }                                        << 
345     }                                             381     }
346                                                   382     
347     // *** PROTON                                 383     // *** PROTON
348     if (particle == protonDef)                    384     if (particle == protonDef)
349       {                                           385       {
350   // Cross section                                386   // Cross section
351   G4String fileProton("Inelastic/" + modelName    387   G4String fileProton("Inelastic/" + modelName + "_sigma_inelastic_p_" + mat); G4cout << fileProton << G4endl;
352   G4MicroElecCrossSectionDataSet_new* tableP =    388   G4MicroElecCrossSectionDataSet_new* tableP = new G4MicroElecCrossSectionDataSet_new(new G4LogLogInterpolation, MeV, scaleFactor);
353   tableP->LoadData(fileProton);                   389   tableP->LoadData(fileProton);
354   tableData->insert(make_pair(proton, tableP))    390   tableData->insert(make_pair(proton, tableP));
355                                                   391 
356   // DCS                                          392   // DCS
357   std::ostringstream pFullFileName;               393   std::ostringstream pFullFileName; 
358   if (fasterCode) {                               394   if (fasterCode) {
359     pFullFileName << path << "/microelec/Inela    395     pFullFileName << path << "/microelec/Inelastic/cumulated_" + modelName + "_sigmadiff_inelastic_p_" + mat + ".dat";
360     G4cout << "Faster code = true" << G4endl;     396     G4cout << "Faster code = true" << G4endl;
361     G4cout << "Inelastic/cumulated_" + modelNa    397     G4cout << "Inelastic/cumulated_" + modelName + "_sigmadiff_inelastic_p_" + mat + ".dat" << G4endl;
362   }                                               398   }
363   else {                                          399   else {
364     pFullFileName << path << "/microelec/Inela    400     pFullFileName << path << "/microelec/Inelastic/" + modelName + "_sigmadiff_inelastic_p_" + mat + ".dat";
365     G4cout << "Faster code = false" << G4endl;    401     G4cout << "Faster code = false" << G4endl;
366     G4cout << "Inelastic/" + modelName + "_sig    402     G4cout << "Inelastic/" + modelName + "_sigmadiff_inelastic_e-_" + mat + ".dat" << G4endl;
367   }                                               403   }
368                                                   404   
369   std::ifstream pDiffCrossSection(pFullFileNam    405   std::ifstream pDiffCrossSection(pFullFileName.str().c_str());
370   if (!pDiffCrossSection)                         406   if (!pDiffCrossSection)
371     {                                             407     {
372       if (fasterCode) G4Exception("G4MicroElec    408       if (fasterCode) G4Exception("G4MicroElecInelasticModel_new::Initialise", "em0003",
373           FatalException, "Missing data file:/    409           FatalException, "Missing data file:/microelec/sigmadiff_cumulated_inelastic_p_Si.dat");
374       else {                                      410       else {        
375         G4Exception("G4MicroElecInelasticModel    411         G4Exception("G4MicroElecInelasticModel_new::Initialise", "em0003",
376         FatalException, "Missing data file:/mi    412         FatalException, "Missing data file:/microelec/sigmadiff_inelastic_p_Si.dat");
377       }                                           413       }
378     }                                             414     }
379                                                   415   
380   //                                              416   //
381   // Clear the arrays for re-initialization ca    417   // Clear the arrays for re-initialization case (MT mode)
382   // Octobre 22nd, 2014 - Melanie Raine           418   // Octobre 22nd, 2014 - Melanie Raine
383   //Creating vectors of maps for DCS and Cumul    419   //Creating vectors of maps for DCS and Cumulated DCS for the current material.
384   //Each vector is storing one map for each sh    420   //Each vector is storing one map for each shell.
385                                                   421   
386   G4bool isUsed1 = false;                      << 
387   vector<TriDimensionMap>* pDiffCrossSectionDa    422   vector<TriDimensionMap>* pDiffCrossSectionData = 
388     new vector<TriDimensionMap>; //Storage of     423     new vector<TriDimensionMap>; //Storage of [IncidentEnergy, TransfEnergy, DCS values], used in slower code
389   vector<TriDimensionMap>* pNrjTransfData =       424   vector<TriDimensionMap>* pNrjTransfData = 
390     new vector<TriDimensionMap>; //Storage of     425     new vector<TriDimensionMap>; //Storage of possible transfer energies by shell
391   vector<VecMap>* pProbaShellMap =                426   vector<VecMap>* pProbaShellMap = 
392     new vector<VecMap>; //Storage of the vecto    427     new vector<VecMap>; //Storage of the vectors containing all cumulated DCS values for an initial energy, by shell
393   vector<G4double>* pTdummyVec =                  428   vector<G4double>* pTdummyVec = 
394     new vector<G4double>; //Storage of inciden    429     new vector<G4double>; //Storage of incident energies for interpolation
395   VecMap* pVecm = new VecMap; //Transfered ene << 430   VecMap* eVecm = new VecMap; //Transfered energy map for slower code
396                                                   431 
397   for (G4int j = 0; j < currentMaterialStructu << 432   for (int j = 0; j < currentMaterialStructure->NumberOfLevels(); ++j) 
398     //Filling the map vectors with an empty ma    433     //Filling the map vectors with an empty map for each shell
399     {                                             434     {
400       pDiffCrossSectionData->push_back(TriDime    435       pDiffCrossSectionData->push_back(TriDimensionMap());
401       pNrjTransfData->push_back(TriDimensionMa    436       pNrjTransfData->push_back(TriDimensionMap());
402       pProbaShellMap->push_back(VecMap());        437       pProbaShellMap->push_back(VecMap());
403     }                                             438     }
404                                                   439   
405   pTdummyVec->push_back(0.);                      440   pTdummyVec->push_back(0.);
406   while (!pDiffCrossSection.eof())                441   while (!pDiffCrossSection.eof())
407     {                                             442     {
408       G4double tDummy; //incident energy          443       G4double tDummy; //incident energy
409       G4double eDummy; //transfered energy        444       G4double eDummy; //transfered energy
410       pDiffCrossSection >> tDummy >> eDummy;      445       pDiffCrossSection >> tDummy >> eDummy;
411       if (tDummy != pTdummyVec->back()) pTdumm    446       if (tDummy != pTdummyVec->back()) pTdummyVec->push_back(tDummy);
412                                                   447       
413       G4double tmp; //probability                 448       G4double tmp; //probability
414       for (G4int j = 0; j < currentMaterialStr << 449       for (int j = 0; j < currentMaterialStructure->NumberOfLevels(); j++)
415         {                                         450         {
416     pDiffCrossSection >> tmp;                     451     pDiffCrossSection >> tmp; 
417     (*pDiffCrossSectionData)[j][tDummy][eDummy    452     (*pDiffCrossSectionData)[j][tDummy][eDummy] = tmp; 
418     // ArrayofMaps[j] -> fill with 3DMap(incid    453     // ArrayofMaps[j] -> fill with 3DMap(incidentEnergy, 
419     // 2Dmap (transferedEnergy,proba=tmp) ) ->    454     // 2Dmap (transferedEnergy,proba=tmp) ) -> fill map for shell j 
420     // with proba for transfered energy eDummy    455     // with proba for transfered energy eDummy
421                                                   456     
422     if (fasterCode)                               457     if (fasterCode)
423       {                                           458       {
424         (*pNrjTransfData)[j][tDummy][(*pDiffCr    459         (*pNrjTransfData)[j][tDummy][(*pDiffCrossSectionData)[j][tDummy][eDummy]] = eDummy;
425         (*pProbaShellMap)[j][tDummy].push_back    460         (*pProbaShellMap)[j][tDummy].push_back((*pDiffCrossSectionData)[j][tDummy][eDummy]);
426       }                                           461       }
427     else {  // SI - only if eof is not reached    462     else {  // SI - only if eof is not reached !
428       (*pDiffCrossSectionData)[j][tDummy][eDum << 463       if (!pDiffCrossSection.eof()) (*pDiffCrossSectionData)[j][tDummy][eDummy] *= scaleFactor;
429       (*pVecm)[tDummy].push_back(eDummy);      << 464       (*eVecm)[tDummy].push_back(eDummy);
430     }                                             465     }
431         }                                         466         }
432     }                                             467     }
433                                                   468   
434   //Filing maps for the current material into     469   //Filing maps for the current material into the master maps
435   if (fasterCode) {                               470   if (fasterCode) {
436     isUsed1 = true;                            << 
437     pNrjTransStorage[mat] = pNrjTransfData;       471     pNrjTransStorage[mat] = pNrjTransfData;
438     pProbaShellStorage[mat] = pProbaShellMap;     472     pProbaShellStorage[mat] = pProbaShellMap;
439   }                                               473   }
440   else {                                          474   else {
441     pDiffDatatable[mat] = pDiffCrossSectionDat    475     pDiffDatatable[mat] = pDiffCrossSectionData;
442     pVecmStorage[mat] = pVecm;                 << 476     pVecmStorage[mat] = eVecm;
443   }                                               477   }
444   pIncidentEnergyStorage[mat] = pTdummyVec;       478   pIncidentEnergyStorage[mat] = pTdummyVec;
445                                                << 479          
446   //Cleanup support vectors                       480   //Cleanup support vectors
447   if (!isUsed1) {                              << 481   // delete pNrjTransfData;
448     delete pProbaShellMap;                     << 482   // delete eVecm;
449     delete pNrjTransfData;                     << 483   // delete pDiffCrossSectionData;
450   } else {                                     << 484   // delete pProbaShellMap;
451     delete pDiffCrossSectionData;              << 
452     delete pVecm;                              << 
453   }                                            << 
454       }                                           485       }
455     tableTCS[mat] = tableData;                    486     tableTCS[mat] = tableData;
456   }                                            << 487 } 
457   if (particle==electronDef)                      488   if (particle==electronDef)
458     {                                             489     {
459       SetLowEnergyLimit(lowEnergyLimit[electro    490       SetLowEnergyLimit(lowEnergyLimit[electron]);
460       SetHighEnergyLimit(highEnergyLimit[elect    491       SetHighEnergyLimit(highEnergyLimit[electron]);
461     }                                             492     }
462                                                   493   
463   if (particle==protonDef)                        494   if (particle==protonDef)
464     {                                             495     {
465       SetLowEnergyLimit(100*eV);                  496       SetLowEnergyLimit(100*eV);
466       SetHighEnergyLimit(10*MeV);                 497       SetHighEnergyLimit(10*MeV);
467     }                                             498     }
468                                                   499   
469   if( verboseLevel>1 )                            500   if( verboseLevel>1 )
470     {                                             501     {
471       G4cout << "MicroElec Inelastic model is     502       G4cout << "MicroElec Inelastic model is initialized " << G4endl
472        << "Energy range: "                        503        << "Energy range: "
473        << LowEnergyLimit() / keV << " keV - "     504        << LowEnergyLimit() / keV << " keV - "
474        << HighEnergyLimit() / MeV << " MeV for    505        << HighEnergyLimit() / MeV << " MeV for "
475        << particle->GetParticleName()             506        << particle->GetParticleName()
476        << " with mass (amu) " << particle->Get    507        << " with mass (amu) " << particle->GetPDGMass()/proton_mass_c2
477        << " and charge " << particle->GetPDGCh    508        << " and charge " << particle->GetPDGCharge()
478        << G4endl << G4endl ;                      509        << G4endl << G4endl ;
479     }                                             510     }
480                                                   511   
481   fAtomDeexcitation  = G4LossTableManager::Ins    512   fAtomDeexcitation  = G4LossTableManager::Instance()->AtomDeexcitation();
482                                                << 513   
483   fParticleChangeForGamma = GetParticleChangeF    514   fParticleChangeForGamma = GetParticleChangeForGamma();
484   isInitialised = true;                           515   isInitialised = true;
485 }                                                 516 }
486                                                   517 
487 //....oooOO0OOooo........oooOO0OOooo........oo    518 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
488                                                   519 
489 G4double G4MicroElecInelasticModel_new::CrossS    520 G4double G4MicroElecInelasticModel_new::CrossSectionPerVolume(const G4Material* material,
490                const G4ParticleDefinition* par    521                const G4ParticleDefinition* particleDefinition,
491                G4double ekin,                     522                G4double ekin,
492                G4double,                          523                G4double,
493                G4double)                          524                G4double)
494 {                                                 525 {
495   if (verboseLevel > 3) G4cout << "Calling Cro    526   if (verboseLevel > 3) G4cout << "Calling CrossSectionPerVolume() of G4MicroElecInelasticModel" << G4endl;
496                                                   527   
497   G4double density = material->GetTotNbOfAtoms    528   G4double density = material->GetTotNbOfAtomsPerVolume();
498   currentMaterial = material->GetName().substr    529   currentMaterial = material->GetName().substr(3, material->GetName().size());
499                                                   530   
500   MapStructure::iterator structPos;               531   MapStructure::iterator structPos;
501   structPos = tableMaterialsStructures.find(cu    532   structPos = tableMaterialsStructures.find(currentMaterial);
502                                                   533   
503   // Calculate total cross section for model      534   // Calculate total cross section for model
504   TCSMap::iterator tablepos;                      535   TCSMap::iterator tablepos;
505   tablepos = tableTCS.find(currentMaterial);      536   tablepos = tableTCS.find(currentMaterial);
506                                                   537   
507   if (tablepos == tableTCS.end() )                538   if (tablepos == tableTCS.end() )
508     {                                             539     {
509       G4String str = "Material ";                 540       G4String str = "Material ";
510       str += currentMaterial + " TCS Table not    541       str += currentMaterial + " TCS Table not found!";
511       G4Exception("G4MicroElecInelasticModel_n    542       G4Exception("G4MicroElecInelasticModel_new::ComputeCrossSectionPerVolume", "em0002", FatalException, str);
512       return 0;                                   543       return 0;
513     }                                             544     }
514   else if(structPos == tableMaterialsStructure    545   else if(structPos == tableMaterialsStructures.end())
515     {                                             546     {
516       G4String str = "Material ";                 547       G4String str = "Material ";
517       str += currentMaterial + " Structure not    548       str += currentMaterial + " Structure not found!";
518       G4Exception("G4MicroElecInelasticModel_n    549       G4Exception("G4MicroElecInelasticModel_new::ComputeCrossSectionPerVolume", "em0002", FatalException, str);
519       return 0;                                   550       return 0;
520     }                                             551     }
521   else {                                          552   else {
522     MapData* tableData = tablepos->second;        553     MapData* tableData = tablepos->second;
523     currentMaterialStructure = structPos->seco    554     currentMaterialStructure = structPos->second;
524                                                   555     
525     G4double sigma = 0;                           556     G4double sigma = 0;
526                                                   557    
527     const G4String& particleName = particleDef    558     const G4String& particleName = particleDefinition->GetParticleName();
528     G4String nameLocal = particleName;            559     G4String nameLocal = particleName;
529     G4int pdg = particleDefinition->GetPDGEnco    560     G4int pdg = particleDefinition->GetPDGEncoding();
530     G4int Z = particleDefinition->GetAtomicNum    561     G4int Z = particleDefinition->GetAtomicNumber();
531                                                   562     
532     G4double Zeff = 1.0, Zeff2 = Zeff*Zeff;       563     G4double Zeff = 1.0, Zeff2 = Zeff*Zeff;
533     G4double Mion_c2 = particleDefinition->Get    564     G4double Mion_c2 = particleDefinition->GetPDGMass();
534                                                   565     
535     if (Mion_c2 > proton_mass_c2)                 566     if (Mion_c2 > proton_mass_c2)
536       {                                           567       {
537   ekin *= proton_mass_c2 / Mion_c2;               568   ekin *= proton_mass_c2 / Mion_c2;
538         nameLocal = "proton";                     569         nameLocal = "proton";
539       }                                           570       }
540                                                   571 
541     G4double lowLim = currentMaterialStructure    572     G4double lowLim = currentMaterialStructure->GetInelasticModelLowLimit(pdg);
542     G4double highLim = currentMaterialStructur    573     G4double highLim = currentMaterialStructure->GetInelasticModelHighLimit(pdg);
543                                                   574     
544     if (ekin >= lowLim && ekin < highLim)         575     if (ekin >= lowLim && ekin < highLim)
545       {                                           576       {
546   std::map< G4String, G4MicroElecCrossSectionD    577   std::map< G4String, G4MicroElecCrossSectionDataSet_new*, std::less<G4String> >::iterator pos;
547   pos = tableData->find(nameLocal); //find par    578   pos = tableData->find(nameLocal); //find particle type
548                                                   579   
549   if (pos != tableData->end())                    580   if (pos != tableData->end())
550     {                                             581     {
551       G4MicroElecCrossSectionDataSet_new* tabl    582       G4MicroElecCrossSectionDataSet_new* table = pos->second;
552       if (table != 0)                             583       if (table != 0)
553         {                                         584         {
554     sigma = table->FindValue(ekin);               585     sigma = table->FindValue(ekin);
555                                                   586         
556     if (Mion_c2 > proton_mass_c2) {               587     if (Mion_c2 > proton_mass_c2) {
557       sigma = 0.;                                 588       sigma = 0.;
558       for (G4int i = 0; i < currentMaterialStr    589       for (G4int i = 0; i < currentMaterialStructure->NumberOfLevels(); i++) {
559         Zeff = BKZ(ekin / (proton_mass_c2 / Mi    590         Zeff = BKZ(ekin / (proton_mass_c2 / Mion_c2), Mion_c2 / c_squared, Z, currentMaterialStructure->Energy(i)); // il faut garder le vrai ekin car le calcul à l'interieur de la methode convertie l'énergie en vitesse
560         Zeff2 = Zeff*Zeff;                        591         Zeff2 = Zeff*Zeff;
561         sigma += Zeff2*table->FindShellValue(e    592         sigma += Zeff2*table->FindShellValue(ekin, i); 
562 // il faut utiliser le ekin mis à l'echelle p    593 // il faut utiliser le ekin mis à l'echelle pour chercher la bonne 
563 // valeur dans les tables proton                  594 // valeur dans les tables proton
564                                                   595     
565       }                                           596       }
566     }                                             597     }
567     else {                                        598     else {
568       sigma = table->FindValue(ekin);             599       sigma = table->FindValue(ekin);
569     }                                             600     }
570         }                                         601         }
571     }                                             602     }
572   else                                            603   else
573     {                                             604     {
574       G4Exception("G4MicroElecInelasticModel_n    605       G4Exception("G4MicroElecInelasticModel_new::CrossSectionPerVolume", 
575                         "em0002", FatalExcepti    606                         "em0002", FatalException, 
576                         "Model not applicable     607                         "Model not applicable to particle type.");
577     }                                             608     }
578       }                                           609       }
579     else                                          610     else
580       {                                           611       {
581   return 1 / DBL_MAX;                             612   return 1 / DBL_MAX;
582       }                                           613       }
583                                                   614     
584     if (verboseLevel > 3)                         615     if (verboseLevel > 3)
585       {                                           616       {
586   G4cout << "---> Kinetic energy (eV)=" << eki    617   G4cout << "---> Kinetic energy (eV)=" << ekin / eV << G4endl;
587   G4cout << " - Cross section per Si atom (cm^    618   G4cout << " - Cross section per Si atom (cm^2)=" << sigma / cm2 << G4endl;
588   G4cout << " - Cross section per Si atom (cm^    619   G4cout << " - Cross section per Si atom (cm^-1)=" << sigma*density / (1. / cm) << G4endl;
589       }                                           620       }
590                                                   621         
591     return (sigma)*density;                    << 622     return (sigma)*density;} 
592   }                                            << 623  
593 }                                                 624 }
594                                                   625 
595 //....oooOO0OOooo........oooOO0OOooo........oo    626 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
596                                                   627 
597 void G4MicroElecInelasticModel_new::SampleSeco    628 void G4MicroElecInelasticModel_new::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
598                                                   629                                                   const G4MaterialCutsCouple* couple,
599                                                   630                                                   const G4DynamicParticle* particle,
600                                                   631                                                   G4double,
601                                                   632                                                   G4double)
602 {                                                 633 {
603                                                   634   
604   if (verboseLevel > 3)                           635   if (verboseLevel > 3)
605     G4cout << "Calling SampleSecondaries() of     636     G4cout << "Calling SampleSecondaries() of G4MicroElecInelasticModel" << G4endl;
606                                                   637   
607   G4int pdg = particle->GetParticleDefinition(    638   G4int pdg = particle->GetParticleDefinition()->GetPDGEncoding();
608   G4double lowLim = currentMaterialStructure->    639   G4double lowLim = currentMaterialStructure->GetInelasticModelLowLimit(pdg);
609   G4double highLim = currentMaterialStructure-    640   G4double highLim = currentMaterialStructure->GetInelasticModelHighLimit(pdg);
610                                                   641   
611   G4double ekin = particle->GetKineticEnergy()    642   G4double ekin = particle->GetKineticEnergy();
612   G4double k = ekin ;                             643   G4double k = ekin ;
613                                                   644   
614   G4ParticleDefinition* PartDef = particle->Ge    645   G4ParticleDefinition* PartDef = particle->GetDefinition();
615   const G4String& particleName = PartDef->GetP    646   const G4String& particleName = PartDef->GetParticleName();
616   G4String nameLocal2 = particleName ;            647   G4String nameLocal2 = particleName ;
617   G4double particleMass = particle->GetDefinit    648   G4double particleMass = particle->GetDefinition()->GetPDGMass();
618   G4double originalMass = particleMass; // a p    649   G4double originalMass = particleMass; // a passer en argument dans samplesecondaryenergy pour évaluer correctement Qmax
619   G4int originalZ = particle->GetDefinition()-    650   G4int originalZ = particle->GetDefinition()->GetAtomicNumber();
620                                                   651   
621   if (particleMass > proton_mass_c2)              652   if (particleMass > proton_mass_c2)
622     {                                             653     {
623       k *= proton_mass_c2/particleMass ;          654       k *= proton_mass_c2/particleMass ;
624       PartDef = G4Proton::ProtonDefinition();     655       PartDef = G4Proton::ProtonDefinition();
625       nameLocal2 = "proton" ;                     656       nameLocal2 = "proton" ;
626     }                                             657     }
627                                                   658    
628   if (k >= lowLim && k < highLim)                 659   if (k >= lowLim && k < highLim)
629     {                                             660     {
630       G4ParticleMomentum primaryDirection = pa    661       G4ParticleMomentum primaryDirection = particle->GetMomentumDirection();
631       G4double totalEnergy = ekin + particleMa    662       G4double totalEnergy = ekin + particleMass;
632       G4double pSquare = ekin * (totalEnergy +    663       G4double pSquare = ekin * (totalEnergy + particleMass);
633       G4double totalMomentum = std::sqrt(pSqua    664       G4double totalMomentum = std::sqrt(pSquare);
634                                                   665       
635       G4int Shell = 1;                            666       G4int Shell = 1;
636                                                   667       
637       Shell = RandomSelect(k,nameLocal2,origin    668       Shell = RandomSelect(k,nameLocal2,originalMass, originalZ);
638                                                   669             
639       G4double bindingEnergy = currentMaterial    670       G4double bindingEnergy = currentMaterialStructure->Energy(Shell);
640       G4double limitEnergy = currentMaterialSt    671       G4double limitEnergy = currentMaterialStructure->GetLimitEnergy(Shell);
641                                                << 
642     G4bool weaklyBound = currentMaterialStruct << 
643                                                   672       
644       if (verboseLevel > 3)                       673       if (verboseLevel > 3)
645   {                                               674   {
646     G4cout << "---> Kinetic energy (eV)=" << k    675     G4cout << "---> Kinetic energy (eV)=" << k/eV << G4endl ;
647     G4cout << "Shell: " << Shell << ", energy:    676     G4cout << "Shell: " << Shell << ", energy: " << bindingEnergy/eV << G4endl;
648   }                                               677   }
649                                                   678       
650                                                << 
651     if (k<limitEnergy) {                       << 
652     if (weaklyBound && k > currentMaterialStru << 
653       limitEnergy = currentMaterialStructure-> << 
654     }                                          << 
655     else return; }                             << 
656                                                << 
657       // sample deexcitation                      679       // sample deexcitation
658                                                   680       
659       std::size_t secNumberInit = 0;  // need     681       std::size_t secNumberInit = 0;  // need to know at a certain point the energy of secondaries
660       std::size_t secNumberFinal = 0; // So I'    682       std::size_t secNumberFinal = 0; // So I'll make the difference and then sum the energies
661                                                << 683       
                                                   >> 684       //SI: additional protection if tcs interpolation method is modified
                                                   >> 685       //if (k<bindingEnergy) return;
                                                   >> 686       if (k<limitEnergy) return;
662       //  G4cout << currentMaterial << G4endl;    687       //  G4cout << currentMaterial << G4endl;
663       G4int Z = currentMaterialStructure->GetZ    688       G4int Z = currentMaterialStructure->GetZ(Shell);     
664       G4int shellEnum = currentMaterialStructu    689       G4int shellEnum = currentMaterialStructure->GetEADL_Enumerator(Shell);
665       if (currentMaterialStructure->IsShellWea    690       if (currentMaterialStructure->IsShellWeaklyBound(Shell)) { shellEnum = -1; }
666                                                   691       
667       if(fAtomDeexcitation && shellEnum >=0)      692       if(fAtomDeexcitation && shellEnum >=0) 
668   {                                               693   {
669     //    G4cout << "enter if deex and shell 0    694     //    G4cout << "enter if deex and shell 0" << G4endl;
670     G4AtomicShellEnumerator as = G4AtomicShell    695     G4AtomicShellEnumerator as = G4AtomicShellEnumerator(shellEnum);
671     const G4AtomicShell* shell = fAtomDeexcita    696     const G4AtomicShell* shell = fAtomDeexcitation->GetAtomicShell(Z, as);
672     secNumberInit = fvect->size();                697     secNumberInit = fvect->size();
673     fAtomDeexcitation->GenerateParticles(fvect    698     fAtomDeexcitation->GenerateParticles(fvect, shell, Z, 0, 0);
674     secNumberFinal = fvect->size();               699     secNumberFinal = fvect->size();
675   }                                               700   }
676                                                   701             
677       G4double secondaryKinetic=-1000*eV;         702       G4double secondaryKinetic=-1000*eV;
678       SEFromFermiLevel = false;                   703       SEFromFermiLevel = false;
679       if (!fasterCode)                            704       if (!fasterCode)
680   {                                               705   {
681     secondaryKinetic = RandomizeEjectedElectro    706     secondaryKinetic = RandomizeEjectedElectronEnergy(PartDef, k, Shell, originalMass, originalZ);    
682   }                                               707   }
683       else                                        708       else 
684   {                                               709   {
685     secondaryKinetic = RandomizeEjectedElectro    710     secondaryKinetic = RandomizeEjectedElectronEnergyFromCumulatedDcs(PartDef, k, Shell) ;
686   }                                               711   }
687                                                   712 
688       if (verboseLevel > 3)                       713       if (verboseLevel > 3)
689   {                                               714   {
690     G4cout << "Ionisation process" << G4endl;     715     G4cout << "Ionisation process" << G4endl;
691     G4cout << "Shell: " << Shell << " Kin. ene    716     G4cout << "Shell: " << Shell << " Kin. energy (eV)=" << k/eV
692      << " Sec. energy (eV)=" << secondaryKinet    717      << " Sec. energy (eV)=" << secondaryKinetic/eV << G4endl;
693   }                                               718   }
694       G4ThreeVector deltaDirection =              719       G4ThreeVector deltaDirection =
695   GetAngularDistribution()->SampleDirectionFor    720   GetAngularDistribution()->SampleDirectionForShell(particle, secondaryKinetic,
696                 Z, Shell,                         721                 Z, Shell,
697                 couple->GetMaterial());           722                 couple->GetMaterial());
698                                                   723       
699       if (particle->GetDefinition() == G4Elect    724       if (particle->GetDefinition() == G4Electron::ElectronDefinition())
700   {                                               725   {
701     G4double deltaTotalMomentum = std::sqrt(se    726     G4double deltaTotalMomentum = std::sqrt(secondaryKinetic*(secondaryKinetic + 2.*electron_mass_c2 ));    
702                                                   727     
703     G4double finalPx = totalMomentum*primaryDi    728     G4double finalPx = totalMomentum*primaryDirection.x() - deltaTotalMomentum*deltaDirection.x();
704     G4double finalPy = totalMomentum*primaryDi    729     G4double finalPy = totalMomentum*primaryDirection.y() - deltaTotalMomentum*deltaDirection.y();
705     G4double finalPz = totalMomentum*primaryDi    730     G4double finalPz = totalMomentum*primaryDirection.z() - deltaTotalMomentum*deltaDirection.z();
706     G4double finalMomentum = std::sqrt(finalPx    731     G4double finalMomentum = std::sqrt(finalPx*finalPx + finalPy*finalPy + finalPz*finalPz);
707     finalPx /= finalMomentum;                     732     finalPx /= finalMomentum;
708     finalPy /= finalMomentum;                     733     finalPy /= finalMomentum;
709     finalPz /= finalMomentum;                     734     finalPz /= finalMomentum;
710                                                   735     
711     G4ThreeVector direction;                      736     G4ThreeVector direction;
712     direction.set(finalPx,finalPy,finalPz);       737     direction.set(finalPx,finalPy,finalPz);
713                                                   738     
714     fParticleChangeForGamma->ProposeMomentumDi    739     fParticleChangeForGamma->ProposeMomentumDirection(direction.unit());
715   }                                               740   }
716       else fParticleChangeForGamma->ProposeMom    741       else fParticleChangeForGamma->ProposeMomentumDirection(primaryDirection);
717                                                   742       
718       // note that secondaryKinetic is the ene    743       // note that secondaryKinetic is the energy of the delta ray, not of all secondaries.
719       G4double deexSecEnergy = 0;                 744       G4double deexSecEnergy = 0;
720       for (std::size_t j=secNumberInit; j < se    745       for (std::size_t j=secNumberInit; j < secNumberFinal; ++j) {
721         deexSecEnergy = deexSecEnergy + (*fvec    746         deexSecEnergy = deexSecEnergy + (*fvect)[j]->GetKineticEnergy();
722       }                                           747       }      
723       // correction CI 12/01/2023 limit energy << 748       if (SEFromFermiLevel) limitEnergy = currentMaterialStructure->GetEnergyGap();
724     //if (SEFromFermiLevel) limitEnergy = curr << 749       fParticleChangeForGamma->SetProposedKineticEnergy(ekin - secondaryKinetic - limitEnergy); //Ef = Ei-(Q-El)-El = Ei-Q
725       //fParticleChangeForGamma->SetProposedKi << 750       fParticleChangeForGamma->ProposeLocalEnergyDeposit(limitEnergy - deexSecEnergy);
726       //fParticleChangeForGamma->ProposeLocalE << 751            
727                                                << 
728     // correction CI 09/03/2022 limit energy   << 
729     //if (!SEFromFermiLevel && weaklyBound) li << 
730     //if (!SEFromFermiLevel && weaklyBound) li << 
731     fParticleChangeForGamma->SetProposedKineti << 
732     fParticleChangeForGamma->ProposeLocalEnerg << 
733                                                << 
734       if (secondaryKinetic>0)                     752       if (secondaryKinetic>0)
735   {                                               753   {  
736     G4DynamicParticle* dp = new G4DynamicParti    754     G4DynamicParticle* dp = new G4DynamicParticle(G4Electron::Electron(), deltaDirection, secondaryKinetic); //Esec = Q-El
737     fvect->push_back(dp);                         755     fvect->push_back(dp);
738   }                                               756   }      
739     }                                             757     }
740 }                                                 758 }
741                                                   759 
742 //....oooOO0OOooo........oooOO0OOooo........oo    760 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
743                                                   761 
744 G4double G4MicroElecInelasticModel_new::Random    762 G4double G4MicroElecInelasticModel_new::RandomizeEjectedElectronEnergy(
745          const G4ParticleDefinition* particleD    763          const G4ParticleDefinition* particleDefinition,
746    G4double k, G4int shell, G4double originalM    764    G4double k, G4int shell, G4double originalMass, G4int)
747 {                                                 765 {
748   G4double secondaryElectronKineticEnergy=0.;     766   G4double secondaryElectronKineticEnergy=0.;
749   if (particleDefinition == G4Electron::Electr    767   if (particleDefinition == G4Electron::ElectronDefinition())
750     {                                             768     {
751       G4double maximumEnergyTransfer=k;           769       G4double maximumEnergyTransfer=k;      
752       G4double crossSectionMaximum = 0.;          770       G4double crossSectionMaximum = 0.;
753       G4double minEnergy = currentMaterialStru    771       G4double minEnergy = currentMaterialStructure->GetLimitEnergy(shell);
754       G4double maxEnergy = maximumEnergyTransf    772       G4double maxEnergy = maximumEnergyTransfer;
755       G4int nEnergySteps = 100;                   773       G4int nEnergySteps = 100;
756                                                   774       
757       G4double value(minEnergy);                  775       G4double value(minEnergy);
758       G4double stpEnergy(std::pow(maxEnergy/va    776       G4double stpEnergy(std::pow(maxEnergy/value, 1./static_cast<G4double>(nEnergySteps-1)));
759       G4int step(nEnergySteps);                   777       G4int step(nEnergySteps);
760       while (step>0)                              778       while (step>0)
761   {                                               779   {
762     --step;                                       780     --step;
763     G4double differentialCrossSection =           781     G4double differentialCrossSection = 
764       DifferentialCrossSection(particleDefinit    782       DifferentialCrossSection(particleDefinition, k, value, shell);
765     crossSectionMaximum = std::max(crossSectio    783     crossSectionMaximum = std::max(crossSectionMaximum, differentialCrossSection);
766     value*=stpEnergy;                             784     value*=stpEnergy;
767   }                                               785   }
768                                                   786       
769       do                                          787       do
770   {                                               788   {
771     secondaryElectronKineticEnergy = G4Uniform    789     secondaryElectronKineticEnergy = G4UniformRand() * 
772       (maximumEnergyTransfer-currentMaterialSt    790       (maximumEnergyTransfer-currentMaterialStructure->GetLimitEnergy(shell));
773   } while(G4UniformRand()*crossSectionMaximum     791   } while(G4UniformRand()*crossSectionMaximum > 
774     DifferentialCrossSection(particleDefinitio    792     DifferentialCrossSection(particleDefinition, k,
775       (secondaryElectronKineticEnergy+currentM    793       (secondaryElectronKineticEnergy+currentMaterialStructure->GetLimitEnergy(shell)),shell));
776     // added 12/01/2023                        << 794     }
777   return secondaryElectronKineticEnergy;       << 
778   }                                            << 
779   else if (particleDefinition == G4Proton::Pro    795   else if (particleDefinition == G4Proton::ProtonDefinition())
780     {                                             796     {      
781       G4double maximumEnergyTransfer =            797       G4double maximumEnergyTransfer =
782   ComputeElasticQmax(k/(proton_mass_c2/origina    798   ComputeElasticQmax(k/(proton_mass_c2/originalMass), 
783          currentMaterialStructure->Energy(shel    799          currentMaterialStructure->Energy(shell), 
784          originalMass/c_squared, electron_mass    800          originalMass/c_squared, electron_mass_c2/c_squared);
785                                                   801       
786       G4double crossSectionMaximum = 0.;          802       G4double crossSectionMaximum = 0.;
787                                                   803       
788       G4double minEnergy = currentMaterialStru    804       G4double minEnergy = currentMaterialStructure->GetLimitEnergy(shell);
789       G4double maxEnergy = maximumEnergyTransf    805       G4double maxEnergy = maximumEnergyTransfer;
790       G4int nEnergySteps = 100;                   806       G4int nEnergySteps = 100;
791                                                   807       
792       G4double value(minEnergy);                  808       G4double value(minEnergy);
793       G4double stpEnergy(std::pow(maxEnergy/va    809       G4double stpEnergy(std::pow(maxEnergy/value, 1./static_cast<G4double>(nEnergySteps-1)));
794       G4int step(nEnergySteps);                   810       G4int step(nEnergySteps);
795                                                   811       
796       while (step>0)                              812       while (step>0)
797   {                                               813   {
798     --step;                                       814     --step;
799     G4double differentialCrossSection =           815     G4double differentialCrossSection = 
800       DifferentialCrossSection(particleDefinit    816       DifferentialCrossSection(particleDefinition, k, value, shell);
801     crossSectionMaximum = std::max(crossSectio    817     crossSectionMaximum = std::max(crossSectionMaximum, differentialCrossSection);
802     value*=stpEnergy;                             818     value*=stpEnergy;
803   }                                               819   }
804                                                   820       
805       G4double energyTransfer = 0.;               821       G4double energyTransfer = 0.;      
806       do                                          822       do
807   {                                               823   {
808     energyTransfer = G4UniformRand() * maximum    824     energyTransfer = G4UniformRand() * maximumEnergyTransfer;
809   } while(G4UniformRand()*crossSectionMaximum     825   } while(G4UniformRand()*crossSectionMaximum > 
810     DifferentialCrossSection(particleDefinitio    826     DifferentialCrossSection(particleDefinition, k,energyTransfer,shell));
811                                                   827       
812       secondaryElectronKineticEnergy =            828       secondaryElectronKineticEnergy = 
813   energyTransfer-currentMaterialStructure->Get    829   energyTransfer-currentMaterialStructure->GetLimitEnergy(shell);
814                                                   830       
815     }                                             831     }
816   return std::max(secondaryElectronKineticEner    832   return std::max(secondaryElectronKineticEnergy, 0.0);
817 }                                                 833 }
818                                                   834 
819 //....oooOO0OOooo........oooOO0OOooo........oo    835 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
820                                                   836 
821 G4double G4MicroElecInelasticModel_new::Random    837 G4double G4MicroElecInelasticModel_new::RandomizeEjectedElectronEnergyFromCumulatedDcs(
822          const G4ParticleDefinition* particleD    838          const G4ParticleDefinition* particleDefinition, G4double k, G4int shell)
823 {                                                 839 {
824   G4double secondaryElectronKineticEnergy = 0.    840   G4double secondaryElectronKineticEnergy = 0.;
825   G4double random = G4UniformRand();              841   G4double random = G4UniformRand();
826   G4bool weaklyBound = currentMaterialStructur << 842 
827   G4double transf = TransferedEnergy(particleD << 843   secondaryElectronKineticEnergy = TransferedEnergy(particleDefinition, k, shell, random)
828   if (!weaklyBound) {                          << 844     - currentMaterialStructure->GetLimitEnergy(shell) ;
829     secondaryElectronKineticEnergy = transf -  << 845 
830     if(secondaryElectronKineticEnergy <= 0.) { << 846   if (isnan(secondaryElectronKineticEnergy)) { secondaryElectronKineticEnergy = k - currentMaterialStructure->GetLimitEnergy(shell); }
831       secondaryElectronKineticEnergy = 0.0;    << 847 
832     }                                          << 848   if (secondaryElectronKineticEnergy < 0.) {
833   }                                            << 849     secondaryElectronKineticEnergy = k - currentMaterialStructure->GetEnergyGap();
834   else {                                       << 850     SEFromFermiLevel = true;
835     secondaryElectronKineticEnergy = transf -  << 851   }
836     // for weaklybound electrons = gap  + aver << 852   return secondaryElectronKineticEnergy;
837     if (secondaryElectronKineticEnergy <= 0.)  << 
838       secondaryElectronKineticEnergy = 0.0;    << 
839       SEFromFermiLevel = true;                 << 
840     }                                          << 
841   }                                            << 
842   //corrections CI 07/02/2022 - added          << 
843   return secondaryElectronKineticEnergy;       << 
844 }                                                 853 }
845                                                   854 
846 //....oooOO0OOooo........oooOO0OOooo........oo    855 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
847                                                   856 
848 G4double G4MicroElecInelasticModel_new::Transf    857 G4double G4MicroElecInelasticModel_new::TransferedEnergy(
849    const G4ParticleDefinition* particleDefinit    858    const G4ParticleDefinition* particleDefinition,
850    G4double k,                                    859    G4double k,
851    G4int ionizationLevelIndex,                    860    G4int ionizationLevelIndex,
852    G4double random)                               861    G4double random)
853 {                                                 862 {
854   G4double nrj = 0.;                              863   G4double nrj = 0.;
855   G4double valueK1 = 0;                           864   G4double valueK1 = 0;
856   G4double valueK2 = 0;                           865   G4double valueK2 = 0;
857   G4double valuePROB21 = 0;                       866   G4double valuePROB21 = 0;
858   G4double valuePROB22 = 0;                       867   G4double valuePROB22 = 0;
859   G4double valuePROB12 = 0;                       868   G4double valuePROB12 = 0;
860   G4double valuePROB11 = 0;                       869   G4double valuePROB11 = 0;
861   G4double nrjTransf11 = 0;                       870   G4double nrjTransf11 = 0;
862   G4double nrjTransf12 = 0;                       871   G4double nrjTransf12 = 0;
863   G4double nrjTransf21 = 0;                       872   G4double nrjTransf21 = 0;
864   G4double nrjTransf22 = 0;                       873   G4double nrjTransf22 = 0;
865                                                   874   
866   G4double maximumEnergyTransfer1 = 0;            875   G4double maximumEnergyTransfer1 = 0;
867   G4double maximumEnergyTransfer2 = 0;            876   G4double maximumEnergyTransfer2 = 0;
868   G4double maximumEnergyTransferP = 4.* (elect    877   G4double maximumEnergyTransferP = 4.* (electron_mass_c2 / proton_mass_c2) * k;
869   G4double bindingEnergy = currentMaterialStru    878   G4double bindingEnergy = currentMaterialStructure->GetLimitEnergy(ionizationLevelIndex);
870                                                   879   
871   if (particleDefinition == G4Electron::Electr    880   if (particleDefinition == G4Electron::ElectronDefinition())
872     {                                             881     {      
873       dataDiffCSMap::iterator iterator_Nrj;       882       dataDiffCSMap::iterator iterator_Nrj;
874       iterator_Nrj = eNrjTransStorage.find(cur    883       iterator_Nrj = eNrjTransStorage.find(currentMaterial);
875                                                   884       
876       dataProbaShellMap::iterator iterator_Pro    885       dataProbaShellMap::iterator iterator_Proba;
877       iterator_Proba = eProbaShellStorage.find    886       iterator_Proba = eProbaShellStorage.find(currentMaterial);
878                                                   887       
879       incidentEnergyMap::iterator iterator_Tdu    888       incidentEnergyMap::iterator iterator_Tdummy;
880       iterator_Tdummy = eIncidentEnergyStorage    889       iterator_Tdummy = eIncidentEnergyStorage.find(currentMaterial);
881                                                   890       
882       if(iterator_Nrj == eNrjTransStorage.end(    891       if(iterator_Nrj == eNrjTransStorage.end() || iterator_Proba == eProbaShellStorage.end() || 
883    iterator_Tdummy == eIncidentEnergyStorage.e    892    iterator_Tdummy == eIncidentEnergyStorage.end())
884   {                                               893   {
885     G4String str = "Material ";                   894     G4String str = "Material ";
886     str += currentMaterial + " not found!";       895     str += currentMaterial + " not found!";
887     G4Exception("G4MicroElecInelasticModel_new    896     G4Exception("G4MicroElecInelasticModel_new::TransferedEnergy", "em0002", 
888           FatalException, str);                   897           FatalException, str);
889   }                                               898   }
890       else {                                      899       else {
891   vector<TriDimensionMap>* eNrjTransfData = it    900   vector<TriDimensionMap>* eNrjTransfData = iterator_Nrj->second; //Storage of possible transfer energies
892   vector<VecMap>* eProbaShellMap = iterator_Pr    901   vector<VecMap>* eProbaShellMap = iterator_Proba->second; //Storage of probabilities for energy transfer
893   vector<G4double>* eTdummyVec = iterator_Tdum    902   vector<G4double>* eTdummyVec = iterator_Tdummy->second; //Incident energies for interpolation
894                                                   903   
895   // k should be in eV auto, :std::vector<doub << 904   // k should be in eV
896   auto k2 = std::upper_bound(eTdummyVec->begin    905   auto k2 = std::upper_bound(eTdummyVec->begin(),
897                   eTdummyVec->end(),              906                   eTdummyVec->end(),
898                   k);                             907                   k);
899   auto k1 = k2 - 1;                               908   auto k1 = k2 - 1;
900                                                   909 
901   // SI : the following condition avoids situa    910   // SI : the following condition avoids situations where random >last vector element
902   if (random <= (*eProbaShellMap)[ionizationLe    911   if (random <= (*eProbaShellMap)[ionizationLevelIndex][(*k1)].back()
903       && random <= (*eProbaShellMap)[ionizatio    912       && random <= (*eProbaShellMap)[ionizationLevelIndex][(*k2)].back())
904     {                                             913     {
905       auto prob12 =                               914       auto prob12 =
906         std::upper_bound((*eProbaShellMap)[ion    915         std::upper_bound((*eProbaShellMap)[ionizationLevelIndex][(*k1)].begin(),
907              (*eProbaShellMap)[ionizationLevel    916              (*eProbaShellMap)[ionizationLevelIndex][(*k1)].end(),
908              random);                             917              random);
909                                                   918       
910       auto prob11 = prob12 - 1;                   919       auto prob11 = prob12 - 1;
911                                                   920       
912       auto prob22 =                               921       auto prob22 =
913         std::upper_bound((*eProbaShellMap)[ion    922         std::upper_bound((*eProbaShellMap)[ionizationLevelIndex][(*k2)].begin(),
914              (*eProbaShellMap)[ionizationLevel    923              (*eProbaShellMap)[ionizationLevelIndex][(*k2)].end(),
915              random);                             924              random);
916                                                   925       
917       auto prob21 = prob22 - 1;                   926       auto prob21 = prob22 - 1;
918                                                   927       
919       valueK1 = *k1;                              928       valueK1 = *k1;
920       valueK2 = *k2;                              929       valueK2 = *k2;
921       valuePROB21 = *prob21;                      930       valuePROB21 = *prob21;
922       valuePROB22 = *prob22;                      931       valuePROB22 = *prob22;
923       valuePROB12 = *prob12;                      932       valuePROB12 = *prob12;
924       valuePROB11 = *prob11;                      933       valuePROB11 = *prob11;
925                                                   934       
926       // The following condition avoid getting    935       // The following condition avoid getting transfered energy < binding energy and forces cumxs = 1 for maximum energy transfer.
927       if (valuePROB11 == 0) nrjTransf11 = bind    936       if (valuePROB11 == 0) nrjTransf11 = bindingEnergy;
928       else nrjTransf11 = (*eNrjTransfData)[ion    937       else nrjTransf11 = (*eNrjTransfData)[ionizationLevelIndex][valueK1][valuePROB11];
929       if (valuePROB12 == 1)                       938       if (valuePROB12 == 1)
930         {                                         939         {
931     if ((valueK1 + bindingEnergy) / 2. > value    940     if ((valueK1 + bindingEnergy) / 2. > valueK1) 
932       maximumEnergyTransfer1 = valueK1;           941       maximumEnergyTransfer1 = valueK1;
933     else                                          942     else 
934       maximumEnergyTransfer1 = (valueK1 + bind    943       maximumEnergyTransfer1 = (valueK1 + bindingEnergy) / 2.;
935                                                   944     
936     nrjTransf12 = maximumEnergyTransfer1;         945     nrjTransf12 = maximumEnergyTransfer1;
937         }                                         946         }
938       else                                        947       else 
939         nrjTransf12 = (*eNrjTransfData)[ioniza    948         nrjTransf12 = (*eNrjTransfData)[ionizationLevelIndex][valueK1][valuePROB12];
940                                                   949       
941       if (valuePROB21 == 0) nrjTransf21 = bind    950       if (valuePROB21 == 0) nrjTransf21 = bindingEnergy;
942       else nrjTransf21 = (*eNrjTransfData)[ion    951       else nrjTransf21 = (*eNrjTransfData)[ionizationLevelIndex][valueK2][valuePROB21];
943       if (valuePROB22 == 1)                       952       if (valuePROB22 == 1)
944         {                                         953         {
945     if ((valueK2 + bindingEnergy) / 2. > value    954     if ((valueK2 + bindingEnergy) / 2. > valueK2) maximumEnergyTransfer2 = valueK2;
946     else maximumEnergyTransfer2 = (valueK2 + b    955     else maximumEnergyTransfer2 = (valueK2 + bindingEnergy) / 2.;
947                                                   956         
948     nrjTransf22 = maximumEnergyTransfer2;         957     nrjTransf22 = maximumEnergyTransfer2;
949         }                                         958         }
950       else nrjTransf22 = (*eNrjTransfData)[ion    959       else nrjTransf22 = (*eNrjTransfData)[ionizationLevelIndex][valueK2][valuePROB22];
951                                                   960       
952     }                                             961     }
953   // Avoids cases where cum xs is zero for k1     962   // Avoids cases where cum xs is zero for k1 and is not for k2 (with always k1<k2)
954   if (random > (*eProbaShellMap)[ionizationLev    963   if (random > (*eProbaShellMap)[ionizationLevelIndex][(*k1)].back())
955     {                                             964     {
956       auto prob22 =                               965       auto prob22 =
957         std::upper_bound((*eProbaShellMap)[ion    966         std::upper_bound((*eProbaShellMap)[ionizationLevelIndex][(*k2)].begin(),
958              (*eProbaShellMap)[ionizationLevel    967              (*eProbaShellMap)[ionizationLevelIndex][(*k2)].end(),
959              random);                             968              random);     
960       auto prob21 = prob22 - 1;                   969       auto prob21 = prob22 - 1;
961                                                   970       
962       valueK1 = *k1;                              971       valueK1 = *k1;
963       valueK2 = *k2;                              972       valueK2 = *k2;
964       valuePROB21 = *prob21;                      973       valuePROB21 = *prob21;
965       valuePROB22 = *prob22;                      974       valuePROB22 = *prob22;
966                                                   975             
967       nrjTransf21 = (*eNrjTransfData)[ionizati    976       nrjTransf21 = (*eNrjTransfData)[ionizationLevelIndex][valueK2][valuePROB21];
968       nrjTransf22 = (*eNrjTransfData)[ionizati    977       nrjTransf22 = (*eNrjTransfData)[ionizationLevelIndex][valueK2][valuePROB22];
969                                                   978       
970       G4double interpolatedvalue2 = Interpolat    979       G4double interpolatedvalue2 = Interpolate(valuePROB21,
971                   valuePROB22,                    980                   valuePROB22,
972                   random,                         981                   random,
973                   nrjTransf21,                    982                   nrjTransf21,
974                   nrjTransf22);                   983                   nrjTransf22);
975                                                   984       
976       // zeros are explicitly set                 985       // zeros are explicitly set
977       G4double value = Interpolate(valueK1, va    986       G4double value = Interpolate(valueK1, valueK2, k, 0., interpolatedvalue2);
978                                                   987       
979       return value;                               988       return value;
980     }                                             989     }
981       }                                           990       }
982     }                                             991     }
983   else if (particleDefinition == G4Proton::Pro    992   else if (particleDefinition == G4Proton::ProtonDefinition())
984     {                                             993     {
985       // k should be in eV                        994       // k should be in eV      
986       dataDiffCSMap::iterator iterator_Nrj;       995       dataDiffCSMap::iterator iterator_Nrj;
987       iterator_Nrj = pNrjTransStorage.find(cur    996       iterator_Nrj = pNrjTransStorage.find(currentMaterial);
988                                                   997       
989       dataProbaShellMap::iterator iterator_Pro    998       dataProbaShellMap::iterator iterator_Proba;
990       iterator_Proba = pProbaShellStorage.find    999       iterator_Proba = pProbaShellStorage.find(currentMaterial);
991                                                   1000       
992       incidentEnergyMap::iterator iterator_Tdu    1001       incidentEnergyMap::iterator iterator_Tdummy;
993       iterator_Tdummy = pIncidentEnergyStorage    1002       iterator_Tdummy = pIncidentEnergyStorage.find(currentMaterial);
994                                                   1003       
995     if (iterator_Nrj == pNrjTransStorage.end() << 1004       if (iterator_Nrj == pNrjTransStorage.end() || iterator_Proba == pProbaShellStorage.end() || 
996       iterator_Tdummy == pIncidentEnergyStorag << 1005     iterator_Tdummy == pIncidentEnergyStorage.end())
997     {                                          << 1006   {
998       G4String str = "Material ";              << 1007     G4String str = "Material ";
999       str += currentMaterial + " not found!";  << 1008     str += currentMaterial + " not found!";
1000       G4Exception("G4MicroElecInelasticModel_ << 1009     G4Exception("G4MicroElecInelasticModel_new::TransferedEnergy", "em0002", 
1001         FatalException, str);                 << 1010           FatalException, str);
1002     }                                         << 1011   }
1003       else                                       1012       else 
1004   {                                              1013   {
1005     vector<TriDimensionMap>* pNrjTransfData =    1014     vector<TriDimensionMap>* pNrjTransfData = iterator_Nrj->second; //Storage of possible transfer energies
1006     vector<VecMap>* pProbaShellMap = iterator    1015     vector<VecMap>* pProbaShellMap = iterator_Proba->second; //Storage of probabilities for energy transfer
1007     vector<G4double>* pTdummyVec = iterator_T    1016     vector<G4double>* pTdummyVec = iterator_Tdummy->second; //Incident energies for interpolation
1008                                                  1017     
1009     auto k2 = std::upper_bound(pTdummyVec->be    1018     auto k2 = std::upper_bound(pTdummyVec->begin(),
1010                     pTdummyVec->end(),           1019                     pTdummyVec->end(),
1011                     k);                          1020                     k);
1012                                                  1021     
1013     auto k1 = k2 - 1;                            1022     auto k1 = k2 - 1;
1014                                                  1023     
1015     // SI : the following condition avoids si    1024     // SI : the following condition avoids situations where random > last vector element,
1016     //      for eg. when the last element is     1025     //      for eg. when the last element is zero
1017     if (random <= (*pProbaShellMap)[ionizatio    1026     if (random <= (*pProbaShellMap)[ionizationLevelIndex][(*k1)].back()
1018         && random <= (*pProbaShellMap)[ioniza    1027         && random <= (*pProbaShellMap)[ionizationLevelIndex][(*k2)].back())
1019       {                                          1028       {
1020         auto prob12 =                            1029         auto prob12 =
1021     std::upper_bound((*pProbaShellMap)[ioniza    1030     std::upper_bound((*pProbaShellMap)[ionizationLevelIndex][(*k1)].begin(),
1022          (*pProbaShellMap)[ionizationLevelInd    1031          (*pProbaShellMap)[ionizationLevelIndex][(*k1)].end(),
1023          random);                                1032          random);
1024         auto prob11 = prob12 - 1;                1033         auto prob11 = prob12 - 1;       
1025         auto prob22 =                            1034         auto prob22 =
1026     std::upper_bound((*pProbaShellMap)[ioniza    1035     std::upper_bound((*pProbaShellMap)[ionizationLevelIndex][(*k2)].begin(),
1027          (*pProbaShellMap)[ionizationLevelInd    1036          (*pProbaShellMap)[ionizationLevelIndex][(*k2)].end(),
1028          random);                                1037          random);
1029         auto prob21 = prob22 - 1;                1038         auto prob21 = prob22 - 1;
1030                                                  1039         
1031         valueK1 = *k1;                           1040         valueK1 = *k1;
1032         valueK2 = *k2;                           1041         valueK2 = *k2;
1033         valuePROB21 = *prob21;                   1042         valuePROB21 = *prob21;
1034         valuePROB22 = *prob22;                   1043         valuePROB22 = *prob22;
1035         valuePROB12 = *prob12;                   1044         valuePROB12 = *prob12;
1036         valuePROB11 = *prob11;                   1045         valuePROB11 = *prob11;
1037                                                  1046         
1038         // The following condition avoid gett    1047         // The following condition avoid getting transfered energy < binding energy 
1039         // and forces cumxs = 1 for maximum e    1048         // and forces cumxs = 1 for maximum energy transfer.
1040         if (valuePROB11 == 0) nrjTransf11 = b    1049         if (valuePROB11 == 0) nrjTransf11 = bindingEnergy;
1041         else nrjTransf11 = (*pNrjTransfData)[    1050         else nrjTransf11 = (*pNrjTransfData)[ionizationLevelIndex][valueK1][valuePROB11];
1042                                                  1051         
1043         if (valuePROB12 == 1) nrjTransf12 = m    1052         if (valuePROB12 == 1) nrjTransf12 = maximumEnergyTransferP;
1044         else nrjTransf12 = (*pNrjTransfData)[    1053         else nrjTransf12 = (*pNrjTransfData)[ionizationLevelIndex][valueK1][valuePROB12];
1045                                                  1054         
1046         if (valuePROB21 == 0) nrjTransf21 = b    1055         if (valuePROB21 == 0) nrjTransf21 = bindingEnergy;
1047         else nrjTransf21 = (*pNrjTransfData)[    1056         else nrjTransf21 = (*pNrjTransfData)[ionizationLevelIndex][valueK2][valuePROB21];
1048                                                  1057         
1049         if (valuePROB22 == 1) nrjTransf22 = m    1058         if (valuePROB22 == 1) nrjTransf22 = maximumEnergyTransferP;
1050         else nrjTransf22 = (*pNrjTransfData)[    1059         else nrjTransf22 = (*pNrjTransfData)[ionizationLevelIndex][valueK2][valuePROB22];
1051                                                  1060         
1052       }                                          1061       }
1053                                                  1062     
1054     // Avoids cases where cum xs is zero for     1063     // Avoids cases where cum xs is zero for k1 and is not for k2 (with always k1<k2)   
1055     if (random > (*pProbaShellMap)[ionization    1064     if (random > (*pProbaShellMap)[ionizationLevelIndex][(*k1)].back())
1056       {                                          1065       {
1057         auto prob22 =                            1066         auto prob22 =
1058     std::upper_bound((*pProbaShellMap)[ioniza    1067     std::upper_bound((*pProbaShellMap)[ionizationLevelIndex][(*k2)].begin(),
1059          (*pProbaShellMap)[ionizationLevelInd    1068          (*pProbaShellMap)[ionizationLevelIndex][(*k2)].end(),
1060          random);                                1069          random);
1061                                                  1070         
1062         auto prob21 = prob22 - 1;                1071         auto prob21 = prob22 - 1;
1063                                                  1072         
1064         valueK1 = *k1;                           1073         valueK1 = *k1;
1065         valueK2 = *k2;                           1074         valueK2 = *k2;
1066         valuePROB21 = *prob21;                   1075         valuePROB21 = *prob21;
1067         valuePROB22 = *prob22;                   1076         valuePROB22 = *prob22;
1068                                                  1077         
1069         nrjTransf21 = (*pNrjTransfData)[ioniz    1078         nrjTransf21 = (*pNrjTransfData)[ionizationLevelIndex][valueK2][valuePROB21];
1070         nrjTransf22 = (*pNrjTransfData)[ioniz    1079         nrjTransf22 = (*pNrjTransfData)[ionizationLevelIndex][valueK2][valuePROB22];
1071                                                  1080         
1072         G4double interpolatedvalue2 = Interpo    1081         G4double interpolatedvalue2 = Interpolate(valuePROB21,
1073               valuePROB22,                       1082               valuePROB22,
1074               random,                            1083               random,
1075               nrjTransf21,                       1084               nrjTransf21,
1076               nrjTransf22);                      1085               nrjTransf22);
1077                                                  1086         
1078         // zeros are explicitly set              1087         // zeros are explicitly set       
1079         G4double value = Interpolate(valueK1, << 1088         G4double value = Interpolate(valueK1, valueK2, k, 0., interpolatedvalue2);        
1080         return value;                            1089         return value;
1081       }                                          1090       }
1082   }                                              1091   }
1083     }                                            1092     }
1084   // End electron and proton cases               1093   // End electron and proton cases
1085                                                  1094   
1086   G4double nrjTransfProduct = nrjTransf11 * n    1095   G4double nrjTransfProduct = nrjTransf11 * nrjTransf12 * nrjTransf21 * nrjTransf22;
1087                                                  1096   
1088   if (nrjTransfProduct != 0.)                    1097   if (nrjTransfProduct != 0.)
1089     {                                            1098     {
1090       nrj = QuadInterpolator(valuePROB11,        1099       nrj = QuadInterpolator(valuePROB11,
1091            valuePROB12,                          1100            valuePROB12,
1092            valuePROB21,                          1101            valuePROB21,
1093            valuePROB22,                          1102            valuePROB22,
1094            nrjTransf11,                          1103            nrjTransf11,
1095            nrjTransf12,                          1104            nrjTransf12,
1096            nrjTransf21,                          1105            nrjTransf21,
1097            nrjTransf22,                          1106            nrjTransf22,
1098            valueK1,                              1107            valueK1,
1099            valueK2,                              1108            valueK2,
1100            k,                                    1109            k,
1101            random);                              1110            random);
1102     }                                            1111     }
1103                                                  1112   
1104   return nrj;                                    1113   return nrj;
1105 }                                                1114 }
1106                                                  1115 
1107 //....oooOO0OOooo........oooOO0OOooo........o    1116 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
1108                                                  1117 
1109 G4double G4MicroElecInelasticModel_new::Diffe    1118 G4double G4MicroElecInelasticModel_new::DifferentialCrossSection(
1110          const G4ParticleDefinition * particl    1119          const G4ParticleDefinition * particleDefinition,
1111    G4double k,                                   1120    G4double k,
1112    G4double energyTransfer,                      1121    G4double energyTransfer,
1113    G4int LevelIndex)                             1122    G4int LevelIndex)
1114 {                                                1123 {
1115   G4double sigma = 0.;                           1124   G4double sigma = 0.;
1116                                                  1125   
1117   if (energyTransfer >= currentMaterialStruct    1126   if (energyTransfer >= currentMaterialStructure->GetLimitEnergy(LevelIndex))
1118     {                                            1127     {
1119       G4double valueT1 = 0;                      1128       G4double valueT1 = 0;
1120       G4double valueT2 = 0;                      1129       G4double valueT2 = 0;
1121       G4double valueE21 = 0;                     1130       G4double valueE21 = 0;
1122       G4double valueE22 = 0;                     1131       G4double valueE22 = 0;
1123       G4double valueE12 = 0;                     1132       G4double valueE12 = 0;
1124       G4double valueE11 = 0;                     1133       G4double valueE11 = 0;
1125                                                  1134       
1126       G4double xs11 = 0;                         1135       G4double xs11 = 0;
1127       G4double xs12 = 0;                         1136       G4double xs12 = 0;
1128       G4double xs21 = 0;                         1137       G4double xs21 = 0;
1129       G4double xs22 = 0;                         1138       G4double xs22 = 0;
1130                                                  1139       
1131       if (particleDefinition == G4Electron::E    1140       if (particleDefinition == G4Electron::ElectronDefinition())
1132   {                                              1141   {
1133                                                  1142     
1134     dataDiffCSMap::iterator iterator_Proba;      1143     dataDiffCSMap::iterator iterator_Proba;
1135     iterator_Proba = eDiffDatatable.find(curr    1144     iterator_Proba = eDiffDatatable.find(currentMaterial);
1136                                                  1145     
1137     incidentEnergyMap::iterator iterator_Nrj;    1146     incidentEnergyMap::iterator iterator_Nrj;
1138     iterator_Nrj = eIncidentEnergyStorage.fin    1147     iterator_Nrj = eIncidentEnergyStorage.find(currentMaterial);
1139                                                  1148     
1140     TranfEnergyMap::iterator iterator_TransfN    1149     TranfEnergyMap::iterator iterator_TransfNrj;
1141     iterator_TransfNrj = eVecmStorage.find(cu    1150     iterator_TransfNrj = eVecmStorage.find(currentMaterial);
1142                                                  1151     
1143     if (iterator_Proba != eDiffDatatable.end(    1152     if (iterator_Proba != eDiffDatatable.end() && iterator_Nrj != eIncidentEnergyStorage.end() 
1144         && iterator_TransfNrj!= eVecmStorage.    1153         && iterator_TransfNrj!= eVecmStorage.end())
1145       {                                          1154       { 
1146         vector<TriDimensionMap>* eDiffCrossSe    1155         vector<TriDimensionMap>* eDiffCrossSectionData = (iterator_Proba->second);
1147         vector<G4double>* eTdummyVec = iterat    1156         vector<G4double>* eTdummyVec = iterator_Nrj->second; //Incident energies for interpolation
1148         VecMap* eVecm = iterator_TransfNrj->s    1157         VecMap* eVecm = iterator_TransfNrj->second;
1149                                                  1158         
1150         // k should be in eV and energy trans    1159         // k should be in eV and energy transfer eV also
1151         auto t2 = std::upper_bound(eTdummyVec    1160         auto t2 = std::upper_bound(eTdummyVec->begin(), eTdummyVec->end(), k);
1152         auto t1 = t2 - 1;                        1161         auto t1 = t2 - 1;
1153         // SI : the following condition avoid    1162         // SI : the following condition avoids situations where energyTransfer >last vector element
1154         if (energyTransfer <= (*eVecm)[(*t1)]    1163         if (energyTransfer <= (*eVecm)[(*t1)].back() && energyTransfer <= (*eVecm)[(*t2)].back())
1155     {                                            1164     {
1156       auto e12 = std::upper_bound((*eVecm)[(*    1165       auto e12 = std::upper_bound((*eVecm)[(*t1)].begin(), (*eVecm)[(*t1)].end(), energyTransfer);
1157       auto e11 = e12 - 1;                        1166       auto e11 = e12 - 1;     
1158       auto e22 = std::upper_bound((*eVecm)[(*    1167       auto e22 = std::upper_bound((*eVecm)[(*t2)].begin(), (*eVecm)[(*t2)].end(), energyTransfer);
1159       auto e21 = e22 - 1;                        1168       auto e21 = e22 - 1;
1160                                                  1169       
1161       valueT1 = *t1;                             1170       valueT1 = *t1;
1162       valueT2 = *t2;                             1171       valueT2 = *t2;
1163       valueE21 = *e21;                           1172       valueE21 = *e21;
1164       valueE22 = *e22;                           1173       valueE22 = *e22;
1165       valueE12 = *e12;                           1174       valueE12 = *e12;
1166       valueE11 = *e11;                           1175       valueE11 = *e11;
1167                                                  1176 
1168       xs11 = (*eDiffCrossSectionData)[LevelIn    1177       xs11 = (*eDiffCrossSectionData)[LevelIndex][valueT1][valueE11];
1169       xs12 = (*eDiffCrossSectionData)[LevelIn    1178       xs12 = (*eDiffCrossSectionData)[LevelIndex][valueT1][valueE12];
1170       xs21 = (*eDiffCrossSectionData)[LevelIn    1179       xs21 = (*eDiffCrossSectionData)[LevelIndex][valueT2][valueE21];
1171       xs22 = (*eDiffCrossSectionData)[LevelIn    1180       xs22 = (*eDiffCrossSectionData)[LevelIndex][valueT2][valueE22];
1172     }                                            1181     }
1173       }                                          1182       }
1174     else {                                       1183     else {
1175       G4String str = "Material ";                1184       G4String str = "Material ";
1176       str += currentMaterial + " not found!";    1185       str += currentMaterial + " not found!";
1177       G4Exception("G4MicroElecDielectricModel    1186       G4Exception("G4MicroElecDielectricModels::DifferentialCrossSection", "em0002", FatalException, str);
1178     }                                            1187     }
1179   }                                              1188   }
1180                                                  1189       
1181       if (particleDefinition == G4Proton::Pro    1190       if (particleDefinition == G4Proton::ProtonDefinition())
1182   {                                              1191   {   
1183     dataDiffCSMap::iterator iterator_Proba;      1192     dataDiffCSMap::iterator iterator_Proba;
1184     iterator_Proba = pDiffDatatable.find(curr    1193     iterator_Proba = pDiffDatatable.find(currentMaterial);
1185                                                  1194     
1186     incidentEnergyMap::iterator iterator_Nrj;    1195     incidentEnergyMap::iterator iterator_Nrj;
1187     iterator_Nrj = pIncidentEnergyStorage.fin    1196     iterator_Nrj = pIncidentEnergyStorage.find(currentMaterial);
1188                                                  1197     
1189     TranfEnergyMap::iterator iterator_TransfN    1198     TranfEnergyMap::iterator iterator_TransfNrj;
1190     iterator_TransfNrj = pVecmStorage.find(cu    1199     iterator_TransfNrj = pVecmStorage.find(currentMaterial);
1191                                                  1200     
1192     if (iterator_Proba != pDiffDatatable.end(    1201     if (iterator_Proba != pDiffDatatable.end() && iterator_Nrj != pIncidentEnergyStorage.end() 
1193         && iterator_TransfNrj != pVecmStorage    1202         && iterator_TransfNrj != pVecmStorage.end())
1194       {                                          1203       {
1195         vector<TriDimensionMap>* pDiffCrossSe    1204         vector<TriDimensionMap>* pDiffCrossSectionData = (iterator_Proba->second);
1196         vector<G4double>* pTdummyVec = iterat    1205         vector<G4double>* pTdummyVec = iterator_Nrj->second; //Incident energies for interpolation
1197         VecMap* pVecm = iterator_TransfNrj->s    1206         VecMap* pVecm = iterator_TransfNrj->second;
1198                                                  1207                 
1199         // k should be in eV and energy trans    1208         // k should be in eV and energy transfer eV also
1200         auto t2 =                                1209         auto t2 = 
1201     std::upper_bound(pTdummyVec->begin(), pTd    1210     std::upper_bound(pTdummyVec->begin(), pTdummyVec->end(), k);
1202         auto t1 = t2 - 1;                        1211         auto t1 = t2 - 1;
1203         if (energyTransfer <= (*pVecm)[(*t1)]    1212         if (energyTransfer <= (*pVecm)[(*t1)].back() && energyTransfer <= (*pVecm)[(*t2)].back())
1204     {                                            1213     {
1205       auto e12 = std::upper_bound((*pVecm)[(*    1214       auto e12 = std::upper_bound((*pVecm)[(*t1)].begin(), (*pVecm)[(*t1)].end(), energyTransfer);
1206       auto e11 = e12 - 1;                        1215       auto e11 = e12 - 1;     
1207       auto e22 = std::upper_bound((*pVecm)[(*    1216       auto e22 = std::upper_bound((*pVecm)[(*t2)].begin(), (*pVecm)[(*t2)].end(), energyTransfer);
1208       auto e21 = e22 - 1;                        1217       auto e21 = e22 - 1;
1209                                                  1218       
1210       valueT1 = *t1;                             1219       valueT1 = *t1;
1211       valueT2 = *t2;                             1220       valueT2 = *t2;
1212       valueE21 = *e21;                           1221       valueE21 = *e21;
1213       valueE22 = *e22;                           1222       valueE22 = *e22;
1214       valueE12 = *e12;                           1223       valueE12 = *e12;
1215       valueE11 = *e11;                           1224       valueE11 = *e11;
1216                                                  1225       
1217       xs11 = (*pDiffCrossSectionData)[LevelIn    1226       xs11 = (*pDiffCrossSectionData)[LevelIndex][valueT1][valueE11];
1218       xs12 = (*pDiffCrossSectionData)[LevelIn    1227       xs12 = (*pDiffCrossSectionData)[LevelIndex][valueT1][valueE12];
1219       xs21 = (*pDiffCrossSectionData)[LevelIn    1228       xs21 = (*pDiffCrossSectionData)[LevelIndex][valueT2][valueE21];
1220       xs22 = (*pDiffCrossSectionData)[LevelIn    1229       xs22 = (*pDiffCrossSectionData)[LevelIndex][valueT2][valueE22];
1221     }                                            1230     }
1222       }                                          1231       }
1223     else {                                       1232     else {
1224       G4String str = "Material ";                1233       G4String str = "Material ";
1225       str += currentMaterial + " not found!";    1234       str += currentMaterial + " not found!";
1226       G4Exception("G4MicroElecDielectricModel    1235       G4Exception("G4MicroElecDielectricModels::DifferentialCrossSection", "em0002", FatalException, str);
1227     }                                            1236     }
1228   }                                              1237   }
1229                                                  1238       
1230       G4double xsProduct = xs11 * xs12 * xs21    1239       G4double xsProduct = xs11 * xs12 * xs21 * xs22;
1231       if (xsProduct != 0.)                       1240       if (xsProduct != 0.)
1232   {                                              1241   {
1233     sigma = QuadInterpolator(     valueE11, v    1242     sigma = QuadInterpolator(     valueE11, valueE12,
1234           valueE21, valueE22,                    1243           valueE21, valueE22,
1235           xs11, xs12,                            1244           xs11, xs12,
1236           xs21, xs22,                            1245           xs21, xs22,
1237           valueT1, valueT2,                      1246           valueT1, valueT2,
1238           k, energyTransfer);                    1247           k, energyTransfer);
1239   }                                              1248   }
1240                                                  1249       
1241     }                                            1250     }
1242                                                  1251   
1243   return sigma;                                  1252   return sigma;
1244 }                                                1253 }
1245                                                  1254 
1246 //....oooOO0OOooo........oooOO0OOooo........o    1255 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
1247                                                  1256 
1248                                                  1257 
1249 G4double G4MicroElecInelasticModel_new::Inter    1258 G4double G4MicroElecInelasticModel_new::Interpolate(G4double e1,
1250            G4double e2,                          1259            G4double e2,
1251            G4double e,                           1260            G4double e,
1252            G4double xs1,                         1261            G4double xs1,
1253            G4double xs2)                         1262            G4double xs2)
1254 {                                                1263 {
1255   G4double value = 0.;                           1264   G4double value = 0.;
1256   if (e == e1 || e1 == e2 ) { return xs1; }   << 
1257   if (e == e2) { return xs2; }                << 
1258                                                  1265 
1259   // Log-log interpolation by default            1266   // Log-log interpolation by default
1260   if (e1 > 0. && e2 > 0. && xs1 > 0. && xs2 > << 1267   if (e1 != 0 && e2 != 0 && (e2-e1) != 0 && !fasterCode)
1261     {                                            1268     {
1262       G4double a = std::log(xs2/xs1)/ std::lo    1269       G4double a = std::log(xs2/xs1)/ std::log(e2/e1);
1263       G4double b = std::log(xs2) - a * std::l    1270       G4double b = std::log(xs2) - a * std::log(e2);
1264       G4double sigma = a * std::log(e) + b;      1271       G4double sigma = a * std::log(e) + b;
1265       value = (std::exp(sigma));                 1272       value = (std::exp(sigma));
1266     }                                            1273     }
1267                                                  1274 
1268   // Switch to log-lin interpolation for fast    1275   // Switch to log-lin interpolation for faster code
1269   else if (xs1 > 0. && xs2 > 0. && fasterCode << 1276   if ((e2 - e1) != 0 && xs1 != 0 && xs2 != 0 && fasterCode)
1270     {                                            1277     {
1271       G4double d1 = std::log(xs1);               1278       G4double d1 = std::log(xs1);
1272       G4double d2 = std::log(xs2);               1279       G4double d2 = std::log(xs2);
1273       value = std::exp((d1 + (d2 - d1) * (e -    1280       value = std::exp((d1 + (d2 - d1) * (e - e1) / (e2 - e1)));
1274     }                                            1281     }
1275                                                  1282 
1276   // Switch to lin-lin interpolation for fast    1283   // Switch to lin-lin interpolation for faster code
1277   // in case one of xs1 or xs2 (=cum proba) v    1284   // in case one of xs1 or xs2 (=cum proba) value is zero
1278   else                                        << 1285   if ((e2 - e1) != 0 && (xs1 == 0 || xs2 == 0) && fasterCode)
1279     {                                            1286     {
1280       G4double d1 = xs1;                         1287       G4double d1 = xs1;
1281       G4double d2 = xs2;                         1288       G4double d2 = xs2;
1282       value = (d1 + (d2 - d1) * (e - e1) / (e    1289       value = (d1 + (d2 - d1) * (e - e1) / (e2 - e1));
1283     }                                            1290     }
1284                                                  1291 
1285   return value;                                  1292   return value;
1286 }                                                1293 }
1287                                                  1294 
1288 //....oooOO0OOooo........oooOO0OOooo........o    1295 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
1289                                                  1296 
1290 G4double G4MicroElecInelasticModel_new::QuadI    1297 G4double G4MicroElecInelasticModel_new::QuadInterpolator(G4double e11, G4double e12,
1291                 G4double e21, G4double e22,      1298                 G4double e21, G4double e22,
1292                 G4double xs11, G4double xs12,    1299                 G4double xs11, G4double xs12,
1293                 G4double xs21, G4double xs22,    1300                 G4double xs21, G4double xs22,
1294                 G4double t1, G4double t2,        1301                 G4double t1, G4double t2,
1295                 G4double t, G4double e)          1302                 G4double t, G4double e)
1296 {                                                1303 {
1297   G4double interpolatedvalue1 = Interpolate(e    1304   G4double interpolatedvalue1 = Interpolate(e11, e12, e, xs11, xs12);
1298   G4double interpolatedvalue2 = Interpolate(e    1305   G4double interpolatedvalue2 = Interpolate(e21, e22, e, xs21, xs22);
1299   G4double value = Interpolate(t1, t2, t, int    1306   G4double value = Interpolate(t1, t2, t, interpolatedvalue1, interpolatedvalue2);
1300   return value;                                  1307   return value;
1301 }                                                1308 }
1302                                                  1309 
1303 //....oooOO0OOooo........oooOO0OOooo........o    1310 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
1304                                                  1311 
1305 G4int G4MicroElecInelasticModel_new::RandomSe    1312 G4int G4MicroElecInelasticModel_new::RandomSelect(G4double k, const G4String& particle, G4double originalMass, G4int originalZ )
1306 {                                                1313 {
1307   G4int level = 0;                               1314   G4int level = 0;
1308                                                  1315   
1309   TCSMap::iterator tablepos;                     1316   TCSMap::iterator tablepos;
1310   tablepos = tableTCS.find(currentMaterial);     1317   tablepos = tableTCS.find(currentMaterial);
1311   if (tablepos == tableTCS.end()) {           << 
1312     G4Exception("G4MicroElecInelasticModel_ne << 
1313     return level;                             << 
1314   }                                           << 
1315                                               << 
1316   MapData* tableData = tablepos->second;         1318   MapData* tableData = tablepos->second;
1317                                                  1319   
1318   std::map< G4String,G4MicroElecCrossSectionD    1320   std::map< G4String,G4MicroElecCrossSectionDataSet_new*,std::less<G4String> >::iterator pos;
1319   pos = tableData->find(particle);               1321   pos = tableData->find(particle);
1320                                                  1322   
1321   std::vector<G4double> Zeff(currentMaterialS    1323   std::vector<G4double> Zeff(currentMaterialStructure->NumberOfLevels(), 1.0);
1322   if(originalMass>proton_mass_c2) {              1324   if(originalMass>proton_mass_c2) {
1323     for(G4int nl=0;nl<currentMaterialStructur    1325     for(G4int nl=0;nl<currentMaterialStructure->NumberOfLevels();nl++) {
1324       Zeff[nl] = BKZ(k/(proton_mass_c2/origin    1326       Zeff[nl] = BKZ(k/(proton_mass_c2/originalMass), originalMass/c_squared, originalZ, currentMaterialStructure->Energy(nl));
1325     }                                            1327     }
1326   }                                              1328   }
1327                                                  1329   
1328   if (pos != tableData->end())                   1330   if (pos != tableData->end())
1329     {                                            1331     {
1330       G4MicroElecCrossSectionDataSet_new* tab    1332       G4MicroElecCrossSectionDataSet_new* table = pos->second;
1331                                                  1333       
1332       if (table != 0)                            1334       if (table != 0)
1333   {                                              1335   {
1334     G4double* valuesBuffer = new G4double[tab    1336     G4double* valuesBuffer = new G4double[table->NumberOfComponents()];
1335     const G4int n = (G4int)table->NumberOfCom    1337     const G4int n = (G4int)table->NumberOfComponents();
1336     G4int i = (G4int)n;                          1338     G4int i = (G4int)n;
1337     G4double value = 0.;                         1339     G4double value = 0.;
1338                                                  1340     
1339     while (i>0)                                  1341     while (i>0)
1340       {                                          1342       {
1341         --i;                                     1343         --i;
1342         valuesBuffer[i] = table->GetComponent    1344         valuesBuffer[i] = table->GetComponent(i)->FindValue(k)*Zeff[i]*Zeff[i];
1343         value += valuesBuffer[i];                1345         value += valuesBuffer[i];
1344       }                                          1346       }   
1345     value *= G4UniformRand();                    1347     value *= G4UniformRand();
1346                                                  1348     
1347     i = n;                                       1349     i = n;
1348                                                  1350     
1349     while (i > 0)                                1351     while (i > 0)
1350       {                                          1352       {
1351         --i;                                     1353         --i;
1352                                                  1354         
1353         if (valuesBuffer[i] > value)             1355         if (valuesBuffer[i] > value)
1354     {                                            1356     {
1355       delete[] valuesBuffer;                     1357       delete[] valuesBuffer;
1356       return i;                                  1358       return i;
1357     }                                            1359     }
1358         value -= valuesBuffer[i];                1360         value -= valuesBuffer[i];
1359       }                                          1361       }
1360                                                  1362     
1361     if (valuesBuffer) delete[] valuesBuffer;     1363     if (valuesBuffer) delete[] valuesBuffer;
1362                                                  1364     
1363   }                                              1365   }
1364     }                                            1366     }
1365   else                                           1367   else
1366     {                                            1368     {
1367       G4Exception("G4MicroElecInelasticModel_    1369       G4Exception("G4MicroElecInelasticModel_new::RandomSelect","em0002",FatalException,"Model not applicable to particle type.");
1368     }                                            1370     }
1369                                                  1371   
1370   return level;                                  1372   return level;
1371 }                                                1373 }
1372                                                  1374 
1373 //....oooOO0OOooo........oooOO0OOooo........o    1375 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
1374                                                  1376 
1375 G4double G4MicroElecInelasticModel_new::Compu    1377 G4double G4MicroElecInelasticModel_new::ComputeRelativistVelocity(G4double E, G4double mass) {
1376   G4double x = E/mass;                           1378   G4double x = E/mass;
1377   return c_light*std::sqrt(x*(x + 2.0))/(x +     1379   return c_light*std::sqrt(x*(x + 2.0))/(x + 1.0);
1378 }                                                1380 }
1379                                                  1381 
1380 //....oooOO0OOooo........oooOO0OOooo........o    1382 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
1381                                                  1383 
1382 G4double G4MicroElecInelasticModel_new::Compu    1384 G4double G4MicroElecInelasticModel_new::ComputeElasticQmax(G4double T1i, G4double T2i, G4double M1, G4double M2) {
1383   G4double v1i = ComputeRelativistVelocity(T1    1385   G4double v1i = ComputeRelativistVelocity(T1i, M1);
1384   G4double v2i = ComputeRelativistVelocity(T2    1386   G4double v2i = ComputeRelativistVelocity(T2i, M2);
1385                                                  1387   
1386   G4double v2f = 2*M1/(M1+M2)*v1i + (M2-M1)/(    1388   G4double v2f = 2*M1/(M1+M2)*v1i + (M2-M1)/(M1+M2)*-1*v2i;
1387   G4double vtransfer2a = v2f*v2f-v2i*v2i;        1389   G4double vtransfer2a = v2f*v2f-v2i*v2i;
1388                                                  1390 
1389   v2f = 2*M1/(M1+M2)*v1i + (M2-M1)/(M1+M2)*v2    1391   v2f = 2*M1/(M1+M2)*v1i + (M2-M1)/(M1+M2)*v2i;
1390   G4double vtransfer2b = v2f*v2f-v2i*v2i;        1392   G4double vtransfer2b = v2f*v2f-v2i*v2i;
1391                                                  1393 
1392   G4double vtransfer2 = std::max(vtransfer2a,    1394   G4double vtransfer2 = std::max(vtransfer2a, vtransfer2b);
1393   return 0.5*M2*vtransfer2;                      1395   return 0.5*M2*vtransfer2;
1394 }                                                1396 }
1395                                                  1397 
1396 //....oooOO0OOooo........oooOO0OOooo........o    1398 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
1397                                                  1399 
1398 G4double G4MicroElecInelasticModel_new::stepF    1400 G4double G4MicroElecInelasticModel_new::stepFunc(G4double x) {
1399   return (x < 0.) ? 1.0 : 0.0;                   1401   return (x < 0.) ? 1.0 : 0.0;
1400 }                                                1402 }
1401                                                  1403 
1402 //....oooOO0OOooo........oooOO0OOooo........o    1404 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
1403                                                  1405 
1404 G4double G4MicroElecInelasticModel_new::vrkre    1406 G4double G4MicroElecInelasticModel_new::vrkreussler(G4double v, G4double vF) 
1405 {                                                1407 {
1406   G4double r = vF*( std::pow(v/vF+1., 3.) - f    1408   G4double r = vF*( std::pow(v/vF+1., 3.) - fabs(std::pow(v/vF-1., 3.)) 
1407         + 4.*(v/vF)*(v/vF) ) + stepFunc(v/vF-    1409         + 4.*(v/vF)*(v/vF) ) + stepFunc(v/vF-1.) * (3./2.*v/vF - 
1408                 4.*(v/vF)*(v/vF) + 3.*std::po    1410                 4.*(v/vF)*(v/vF) + 3.*std::pow(v/vF, 3.) 
1409                 - 0.5*std::pow(v/vF, 5.));       1411                 - 0.5*std::pow(v/vF, 5.));
1410   return r/(10.*v/vF);                           1412   return r/(10.*v/vF);
1411 }                                                1413 }
1412                                                  1414 
1413 //....oooOO0OOooo........oooOO0OOooo........o    1415 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
1414                                                  1416 
1415 G4double G4MicroElecInelasticModel_new::BKZ(G    1417 G4double G4MicroElecInelasticModel_new::BKZ(G4double Ep, G4double mp, G4int Zp, G4double Eplasmon) 
1416 {                                                1418 {
1417   // need atomic unit conversion                 1419   // need atomic unit conversion
1418   G4double hbar = hbar_Planck, hbar2 = hbar*h    1420   G4double hbar = hbar_Planck, hbar2 = hbar*hbar, me = electron_mass_c2/c_squared, Ry = me*elm_coupling*elm_coupling/(2*hbar2);
1419   G4double hartree = 2*Ry,  a0 = Bohr_radius,    1421   G4double hartree = 2*Ry,  a0 = Bohr_radius, velocity = a0*hartree/hbar;
1420   G4double vp = ComputeRelativistVelocity(Ep,    1422   G4double vp = ComputeRelativistVelocity(Ep,  mp);
1421                                                  1423 
1422   vp /= velocity;                                1424   vp /= velocity;
1423                                                  1425 
1424   G4double wp = Eplasmon/hartree;                1426   G4double wp = Eplasmon/hartree;
1425   G4double a = std::pow(4./9./CLHEP::pi, 1./3    1427   G4double a = std::pow(4./9./CLHEP::pi, 1./3.);
1426   G4double vF = std::pow(wp*wp/(3.*a*a*a), 1.    1428   G4double vF = std::pow(wp*wp/(3.*a*a*a), 1./3.);
1427   G4double c = 0.9;                              1429   G4double c = 0.9;
1428   G4double vr = vrkreussler(vp /*in u.a*/, vF    1430   G4double vr = vrkreussler(vp /*in u.a*/, vF /*in u.a*/);
1429   G4double yr = vr/std::pow(Zp, 2./3.);          1431   G4double yr = vr/std::pow(Zp, 2./3.);
1430   G4double q = 0.;                               1432   G4double q = 0.;
1431   if(Zp==2) q = 1-exp(-c*vr/(Zp-5./16.));        1433   if(Zp==2) q = 1-exp(-c*vr/(Zp-5./16.));
1432   else q = 1.-exp(-c*(yr-0.07));                 1434   else q = 1.-exp(-c*(yr-0.07));
1433   G4double Neq = Zp*(1.-q);                      1435   G4double Neq = Zp*(1.-q);
1434   G4double l0 = 0.;                              1436   G4double l0 = 0.;
1435   if(Neq<=2) l0 = 3./(Zp-0.3*(Neq-1))/2.;        1437   if(Neq<=2) l0 = 3./(Zp-0.3*(Neq-1))/2.;
1436   else l0 = 0.48*std::pow(Neq, 2./3.)/(Zp-Neq    1438   else l0 = 0.48*std::pow(Neq, 2./3.)/(Zp-Neq/7.);
1437   if(Zp==2)  c = 1.0;                            1439   if(Zp==2)  c = 1.0;
1438   else c = 3./2.;                                1440   else c = 3./2.;
1439   return Zp*(q + c*(1.-q)/vF/vF/2.0 * log(1.+    1441   return Zp*(q + c*(1.-q)/vF/vF/2.0 * log(1.+std::pow(2.*l0*vF,2.))); 
1440 }                                                1442 }
1441                                                  1443 
1442 //....oooOO0OOooo........oooOO0OOooo........o    1444 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
1443                                                  1445