Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/parameterisations/channeling/src/G4VChannelingFastSimCrystalData.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 /parameterisations/channeling/src/G4VChannelingFastSimCrystalData.cc (Version 11.3.0) and /parameterisations/channeling/src/G4VChannelingFastSimCrystalData.cc (Version 9.3.p1)


  1 //                                                  1 
  2 // *******************************************    
  3 // * License and Disclaimer                       
  4 // *                                              
  5 // * The  Geant4 software  is  copyright of th    
  6 // * the Geant4 Collaboration.  It is provided    
  7 // * conditions of the Geant4 Software License    
  8 // * LICENSE and available at  http://cern.ch/    
  9 // * include a list of copyright holders.         
 10 // *                                              
 11 // * Neither the authors of this software syst    
 12 // * institutes,nor the agencies providing fin    
 13 // * work  make  any representation or  warran    
 14 // * regarding  this  software system or assum    
 15 // * use.  Please see the license in the file     
 16 // * for the full disclaimer and the limitatio    
 17 // *                                              
 18 // * This  code  implementation is the result     
 19 // * technical work of the GEANT4 collaboratio    
 20 // * By using,  copying,  modifying or  distri    
 21 // * any work based  on the software)  you  ag    
 22 // * use  in  resulting  scientific  publicati    
 23 // * acceptance of all terms of the Geant4 Sof    
 24 // *******************************************    
 25 //                                                
 26 // Author:      Alexei Sytov                      
 27 // Co-author:   Gianfranco PaternĂ² (modificat    
 28 // On the base of the CRYSTALRAD realization o    
 29 // A. I. Sytov, V. V. Tikhomirov, and L. Bandi    
 30                                                   
 31 #include "G4VChannelingFastSimCrystalData.hh"     
 32 #include "G4SystemOfUnits.hh"                     
 33 #include "G4PhysicalConstants.hh"                 
 34 #include "G4Log.hh"                               
 35                                                   
 36 G4VChannelingFastSimCrystalData::G4VChanneling    
 37 {                                                 
 38                                                   
 39 }                                                 
 40                                                   
 41 //....oooOO0OOooo........oooOO0OOooo........oo    
 42                                                   
 43 G4VChannelingFastSimCrystalData::~G4VChannelin    
 44                                                   
 45 //....oooOO0OOooo........oooOO0OOooo........oo    
 46                                                   
 47 void G4VChannelingFastSimCrystalData::SetGeome    
 48                                      (const G4    
 49 {                                                 
 50     G4int crystalID = crystallogic->GetInstanc    
 51                                                   
 52     //set bending angle if the it exists in th    
 53     (fMapBendingAngle.count(crystalID) > 0)       
 54     ? SetBendingAngle(fMapBendingAngle[crystal    
 55     : SetBendingAngle(0.,crystallogic);           
 56                                                   
 57     //set miscut angle if the it exists in the    
 58     (fMapMiscutAngle.count(crystalID) > 0)        
 59     ? SetMiscutAngle(fMapMiscutAngle[crystalID    
 60     : SetMiscutAngle(0.,crystallogic);            
 61                                                   
 62     //set crystalline undulator parameters if     
 63     //otherwise default = G4ThreeVector(0,0,0)    
 64     (fMapCUAmplitudePeriodPhase.count(crystalI    
 65     ? SetCUParameters(fMapCUAmplitudePeriodPha    
 66     : SetCUParameters(G4ThreeVector(0.,0.,0.),    
 67 }                                                 
 68                                                   
 69 //....oooOO0OOooo........oooOO0OOooo........oo    
 70                                                   
 71 void G4VChannelingFastSimCrystalData::SetBendi    
 72                   const G4LogicalVolume* cryst    
 73 {                                                 
 74     G4int crystalID = crystallogic->GetInstanc    
 75                                                   
 76     //set the bending angle for this logical v    
 77     fMapBendingAngle[crystalID]=tetab;            
 78                                                   
 79     G4ThreeVector limboxmin;//minimal limits o    
 80     G4ThreeVector limboxmax;//maximal limits o    
 81     //save the limits of the box bounding the     
 82     crystallogic->GetSolid()->BoundingLimits(l    
 83                                                   
 84     //bounding box half dimensions                
 85     fHalfDimBoundingBox = (limboxmax-limboxmin    
 86                                                   
 87     G4double lcr = limboxmax.getZ()-limboxmin.    
 88                                                   
 89     fBendingAngle=std::abs(tetab);                
 90     if (fBendingAngle<0.000001)//no bending le    
 91     {                                             
 92         if(fBendingAngle>DBL_EPSILON)             
 93         {                                         
 94             G4cout << "Channeling model: volum    
 95             G4cout << "Warning: bending angle     
 96         }                                         
 97                                                   
 98        fBent=0;                                   
 99        fBendingAngle=0.;                          
100        fBendingR=0.;//just for convenience (in    
101        fBending2R=0.;                             
102        fBendingRsquare=0.;                        
103        fCurv=0.;                                  
104                                                   
105        fCorrectionZ = 1.;                         
106     }                                             
107     else                                          
108     {                                             
109        fBent=1;                                   
110        fBendingR=lcr/fBendingAngle;               
111        fBending2R=2.*fBendingR;                   
112        fBendingRsquare=fBendingR*fBendingR;       
113        fCurv=1./fBendingR;                        
114                                                   
115        if (tetab<0.)                              
116        {                                          
117            G4cout << "Channeling model: volume    
118            G4cout << "Warning: bending angle i    
119        }                                          
120     }                                             
121                                                   
122 }                                                 
123                                                   
124 //....oooOO0OOooo........oooOO0OOooo........oo    
125                                                   
126 void G4VChannelingFastSimCrystalData::SetMiscu    
127                  const G4LogicalVolume *crysta    
128 {                                                 
129     G4int crystalID = crystallogic->GetInstanc    
130                                                   
131     //set the bending angle for this logical v    
132     fMapMiscutAngle[crystalID]=tetam;             
133                                                   
134     // fMiscutAngle>0: rotation of xz coordina    
135     fMiscutAngle=tetam;                           
136     if (std::abs(tetam)>1.*mrad)                  
137     {                                             
138         G4cout << "Channeling model: volume "     
139         G4cout << "Warning: miscut angle is hi    
140         G4cout << "coordinate transformation r    
141     }                                             
142     fCosMiscutAngle=std::cos(fMiscutAngle);       
143     fSinMiscutAngle=std::sin(fMiscutAngle);       
144 }                                                 
145                                                   
146 //....oooOO0OOooo........oooOO0OOooo........oo    
147                                                   
148 void G4VChannelingFastSimCrystalData::SetCryst    
149                                        G4doubl    
150                                        G4doubl    
151                                        G4doubl    
152                                        const G    
153 {                                                 
154     if (amplitude<DBL_EPSILON||period<DBL_EPSI    
155     {                                             
156         amplitude = 0.;                           
157         period=0.;                                
158         phase=0.;                                 
159         G4cout << "Channeling model: volume "     
160         G4cout << "Warning: The crystalline un    
161                   "=> the crystalline undulato    
162     }                                             
163                                                   
164     SetCUParameters(G4ThreeVector(amplitude,pe    
165 }                                                 
166                                                   
167 //....oooOO0OOooo........oooOO0OOooo........oo    
168                                                   
169 void G4VChannelingFastSimCrystalData::SetCUPar    
170                                       const G4    
171                                       const G4    
172 {                                                 
173     G4int crystalID = crystallogic->GetInstanc    
174                                                   
175     //set the crystalline undulator parameters    
176     fMapCUAmplitudePeriodPhase[crystalID]=ampl    
177     fCUAmplitude=amplitudePeriodPhase.x();        
178     G4double period = amplitudePeriodPhase.y()    
179     fCUPhase = amplitudePeriodPhase.z();          
180                                                   
181     //if the amplidude of the crystalline undu    
182     if(fCUAmplitude>DBL_EPSILON&&period>DBL_EP    
183     {                                             
184         //crystalline undulator flag              
185         fCU = true;                               
186                                                   
187         fCUK = CLHEP::twopi/period;               
188                                                   
189         if(fBendingAngle>DBL_EPSILON)             
190         {                                         
191             //bent and periodically bent cryst    
192             SetBendingAngle(0,crystallogic);      
193                                                   
194             G4cout << "Channeling model: volum    
195             G4cout << "Warning: crystalline un    
196                       "a bent crystal mode =>     
197         }                                         
198     }                                             
199     else                                          
200     {                                             
201         fCU = false;                              
202         fCUAmplitude = 0.;                        
203         fCUK = 0.;                                
204         fCUPhase = 0.;                            
205         fMapCUAmplitudePeriodPhase[crystalID]     
206     }                                             
207                                                   
208     fCUK2 = fCUK*fCUK;                            
209     fCUAmplitudeK = fCUAmplitude*fCUK;            
210 }                                                 
211                                                   
212 //....oooOO0OOooo........oooOO0OOooo........oo    
213                                                   
214 void G4VChannelingFastSimCrystalData::SetParti    
215                                                   
216                                                   
217                                                   
218 {                                                 
219     G4double teta1;                               
220     fZ2=charge;                                   
221     G4double zz22=fZ2*fZ2;                        
222     fParticleName=particleName;                   
223                                                   
224 //     particle momentum and energy               
225        G4double t=etotal*etotal-mass*mass; //     
226        fPz=std::sqrt(t); //  momentum of parti    
227        fPV=t/etotal;    //  pv                    
228        fBeta=fPz/etotal;   //  velocity/c         
229        fTetaL = std::sqrt(std::abs(fZ2)*fVmax2    
230        fChannelingStep = fChangeStep/fTetaL; /    
231                                                   
232 //     Energy losses                              
233        fV2 = fBeta*fBeta; // particle (velocit    
234        fGamma = etotal/mass; //  Lorentz facto    
235        fMe2Gamma = 2*CLHEP::electron_mass_c2*f    
236 //     max ionization losses                      
237        fTmax = fMe2Gamma*fGamma*fV2/              
238                (CLHEP::electron_mass_c2/mass*C    
239                 1. + fMe2Gamma/mass);             
240 //     max ionization losses for electrons        
241        if(fParticleName=="e-"){fTmax/=2;}         
242                                                   
243        for(G4int i=0; i<fNelements; i++)          
244        {                                          
245                                                   
246 //       minimal scattering angle by coulomb s    
247 //       defining by shielding by electrons       
248 //       teta1=hdc/(fPz*fRF)*DSQRT(1.13D0+3.76    
249          teta1=fTeta10[i]*std::sqrt(1.13+fK40[    
250                                                   
251                                                   
252 //       the coefficient for multiple scatteri    
253          fBB[i]=teta1*teta1*fPu11[i];             
254          fE1XBbb[i]=expint(fBB[i]);               
255          fBBDEXP[i]=(1.+fBB[i])*std::exp(fBB[i    
256 //       necessary for suppression of incohere    
257 //       by the atomic correlations in crystal    
258 //       (screened atomic potential): EXP(-(fP    
259 //         =>no scattering                        
260          fPzu11[i]=fPu11[i]*fPz*fPz;              
261                                                   
262          teta1=teta1/fPz; //                      
263          fTeta12[i]=teta1*teta1;                  
264 //       maximal scattering angle by coulomb s    
265 //       defining by nucleus radius               
266 //       tetamax=hc/(fPz*1.D-6*fR0*fAN**(1.D0/    
267          G4double tetamax=fTetamax0[i]/fPz;       
268          fTetamax2[i]=tetamax*tetamax;            
269          fTetamax12[i]=fTeta12[i]+fTetamax2[i]    
270                                                   
271 //       a coefficient in a formula for scatte    
272 //       fK2=(fZ2)**2*alphahbarc2*4.*pi*fN0*(f    
273          fK2[i]=fK20[i]*zz22/fPV/fPV;             
274        }                                          
275                                                   
276 //     fK3=(fZ2)**2*alphahbarc2*pi/electron_ma    
277        fK3=fK30*zz22/fV2;                         
278 }                                                 
279                                                   
280 //....oooOO0OOooo........oooOO0OOooo........oo    
281                                                   
282 G4double G4VChannelingFastSimCrystalData::GetL    
283                                                   
284                                                   
285 {                                                 
286     G4double pv0 = etotal-mass*mass/etotal;       
287        return std::sqrt(2*std::abs(charge)*fVm    
288                                    //(!!! the     
289 }                                                 
290                                                   
291 //....oooOO0OOooo........oooOO0OOooo........oo    
292                                                   
293 G4double G4VChannelingFastSimCrystalData::GetL    
294 {                                                 
295     return fTetaL; //return the Lindhard angle    
296 }                                                 
297                                                   
298 //....oooOO0OOooo........oooOO0OOooo........oo    
299                                                   
300 G4double G4VChannelingFastSimCrystalData::GetS    
301 {                                                 
302     G4double simulationstep;                      
303     //find angle of particle w.r.t. the plane     
304     G4double angle=0.;                            
305     if (iModel==1)//1D model                      
306     {                                             
307         angle = std::abs(tx);                     
308     }                                             
309     else if  (iModel==2)//2D model                
310     {                                             
311         angle = std::sqrt(tx*tx+ty*ty);           
312     }                                             
313                                                   
314     //compare this angle with the Lindhard ang    
315     if (angle<fTetaL)                             
316     {                                             
317         simulationstep = fChannelingStep;         
318     }                                             
319     else                                          
320     {                                             
321       simulationstep = fChangeStep;               
322       if (angle > 0.0) { simulationstep /= ang    
323     }                                             
324                                                   
325     return simulationstep;                        
326 }                                                 
327                                                   
328 //....oooOO0OOooo........oooOO0OOooo........oo    
329                                                   
330 G4double G4VChannelingFastSimCrystalData::GetM    
331                                                   
332                                                   
333 {                                                 
334     //standard value of step for channeling pa    
335     return fChangeStep/GetLindhardAngle(etotal    
336 }                                                 
337                                                   
338 //....oooOO0OOooo........oooOO0OOooo........oo    
339                                                   
340 G4ThreeVector G4VChannelingFastSimCrystalData:    
341                                                   
342                                                   
343                                                   
344 {                                                 
345         G4double tx = 0.;//horizontal scatteri    
346         G4double ty = 0.;//vertical scattering    
347                                                   
348         G4double ksi=0.1;                         
349                                                   
350 //      calculation of the teta2-minimal possi    
351         G4double e1=fK2[ielement]*effectiveSte    
352 //      (real formula is (4*pi*fN0*wpl(x)*dz*f    
353         G4double teta122=fTetamax12[ielement]/    
354         // teta122=fTeta12+teta22=teta1^2+teta    
355                                                   
356         G4double teta22;                          
357         G4double t;                               
358 //      if the angle of a single scattering is    
359 //      angle of coulomb scattering defining b    
360 //      multiple scattering by both nuclei and    
361 //      occur => minimal possible angle of a s    
362         if (teta122<=fTeta12[ielement]*1.00012    
363         {                                         
364           teta22=0.;                              
365           teta122=fTeta12[ielement];              
366         }                                         
367         else                                      
368         {                                         
369           teta22=teta122-fTeta12[ielement];       
370           G4double aa=teta22/fTeta12[ielement]    
371           G4double aa1=1.+aa;                     
372                                                   
373 //        crystal, with scattering suppression    
374           G4double tetamsi=e1*(G4Log(aa1)+        
375                            (1.-std::exp(-aa*fB    
376                            fBBDEXP[ielement]*     
377                            (expint(fBB[ielemen    
378                                                   
379 //        sumilation of multiple coulomb scatt    
380 //        for high speed of a program, real fo    
381 //        4*pi*fN0*wpl(x)*dz*(fZ1*zz2*alpha*hd    
382 //         *(ln(1+a)+(1-exp(-a*b))/(1+a)+(1+b)    
383                                                   
384           ksi=G4UniformRand();                    
385           t=std::sqrt(-tetamsi*G4Log(ksi));       
386                                                   
387           ksi=G4UniformRand();                    
388                                                   
389           tx+=t*std::cos(CLHEP::twopi*ksi);       
390           ty+=t*std::sin(CLHEP::twopi*ksi);       
391                                                   
392         }                                         
393 //      simulation of single coulomb scatterin    
394         G4double zss=0.;                          
395         G4double dzss=step;                       
396                                                   
397 //      (calculation of a distance, at which a    
398         ksi=G4UniformRand();                      
399                                                   
400         zss=-G4Log(ksi)*step/(e1*(1./teta122-1    
401         G4double tt;                              
402                                                   
403 //      At some step several single scattering    
404 //      So,if the distance of the next scatter    
405 //      another scattering can occur. If the d    
406 //      is less than the difference between th    
407 //      the previous scattering, another scatt    
408 //      In the cycle we simulate each of them.    
409 //      the remaining part of step is less tha    
410 //********************************************    
411 //      if at a step a single scattering occur    
412         while (zss<dzss)                          
413         {                                         
414                                                   
415 //        simulation by Monte-Carlo of angles     
416           ksi=G4UniformRand();                    
417                                                   
418           tt=fTetamax12[ielement]/(1.+ksi*(fTe    
419                   fTeta12[ielement];              
420                                                   
421           ksi=G4UniformRand();                    
422                                                   
423 //        suppression of incoherent scattering    
424           t=fPzu11[ielement]*tt;                  
425           t=std::exp(-t);                         
426                                                   
427           if (t<ksi) //if scattering takes pla    
428           {                                       
429             //scattering angle                    
430             t=std::sqrt(tt);                      
431             ksi=G4UniformRand();                  
432                                                   
433             tx+=t*std::cos(CLHEP::twopi*ksi);     
434             ty+=t*std::sin(CLHEP::twopi*ksi);     
435           }                                       
436                                                   
437           dzss-=zss;                              
438 //        (calculation of a distance, at which    
439           ksi=G4UniformRand();                    
440                                                   
441           zss=-G4Log(ksi)*step/(e1*(1./teta122    
442         }                                         
443 //********************************************    
444         return G4ThreeVector(tx,ty,0.);           
445 }                                                 
446                                                   
447 //....oooOO0OOooo........oooOO0OOooo........oo    
448                                                   
449 G4ThreeVector G4VChannelingFastSimCrystalData:    
450                                                   
451                                                   
452                                                   
453 {                                                 
454                                                   
455     G4double zss=0.;                              
456     G4double dzss=step;                           
457     G4double ksi = 0.;                            
458                                                   
459     G4double tx = 0.;//horizontal scattering a    
460     G4double ty = 0.;//vertical scattering ang    
461     G4double eloss = 0.;//energy loss             
462                                                   
463     // eMinIonization - minimal energy transfe    
464     // a cut to reduce the number of calls of     
465     // is needed only at low density regions,     
466     if (eMinIonization<0.5*eV){eMinIonization=    
467                                                   
468     //  single scattering on electrons routine    
469     if ((eMinIonization<fTmax)&&(electronDensi    
470     {                                             
471                                                   
472 //    (calculation of a distance, at which ano    
473 //    simulation of scattering length (by the     
474       ksi=G4UniformRand();                        
475                                                   
476       zss=-1.0*G4Log(ksi)/(fK3*electronDensity    
477                                                   
478 //********************************************    
479 //    if at a step a single scattering occur      
480       while (zss<dzss)                            
481       {                                           
482 //      simulation by Monte-Carlo of angles of    
483         ksi=G4UniformRand();                      
484                                                   
485 //      energy transfered to electron             
486         G4double e1=eMinIonization/(1.-ksi*(1.    
487                                                   
488 //      scattering angle                          
489         G4double t=0;                             
490         if(fTmax-e1>DBL_EPSILON) //to be sure     
491         {                                         
492             t=std::sqrt(2.*CLHEP::electron_mas    
493         }                                         
494                                                   
495         // energy losses                          
496         eloss=e1;                                 
497         ksi=G4UniformRand();                      
498                                                   
499         tx+=t*std::cos(CLHEP::twopi*ksi);         
500         ty+=t*std::sin(CLHEP::twopi*ksi);         
501                                                   
502         dzss-=zss;                                
503 //      (calculation of a distance, at which a    
504 //      simulation of scattering length           
505 //      (by the same way single scattering by     
506         ksi=G4UniformRand();                      
507                                                   
508         zss=-1.0*G4Log(ksi)/(fK3*electronDensi    
509       }                                           
510 //********************************************    
511     }                                             
512     return G4ThreeVector(tx,ty,eloss);            
513 }                                                 
514                                                   
515 //....oooOO0OOooo........oooOO0OOooo........oo    
516                                                   
517 G4double G4VChannelingFastSimCrystalData::Ioni    
518                                                   
519 {                                                 
520     //amorphous part of ionization losses         
521                                                   
522     G4double elosses = 0.;                        
523     // 1/2 already taken into account in fKD      
524                                                   
525     G4double loge = G4Log(fMe2Gamma*fGamma*fV2    
526     G4double delta= 2*(G4Log(fBeta*fGamma)+fLo    
527     if(delta<0){delta=0;}                         
528     loge-=delta;                                  
529     if(fParticleName=="e-")                       
530     {                                             
531        loge+=(-G4Log(2.) + 1                      
532               -(2*fGamma - 1)/fGamma/fGamma*G4    
533                1/8*((fGamma - 1)/fGamma)*((fGa    
534     }                                             
535     else if(fParticleName=="e+")                  
536     {                                             
537        loge+=(-fV2/12*(11 + 14/(fGamma + 1) +     
538                       4/(fGamma + 1)/(fGamma +    
539     }                                             
540     else                                          
541     {                                             
542         loge-=fV2;                                
543     }                                             
544     elosses=fZ2*fZ2*fKD[ielement]/fV2*loge*dz;    
545                                                   
546     return elosses;}                              
547                                                   
548 //....oooOO0OOooo........oooOO0OOooo........oo    
549                                                   
550 G4double G4VChannelingFastSimCrystalData::expi    
551 {                                                 
552 //      ======================================    
553 //      Purpose: Compute exponential integral     
554 //      Input :  x  --- Argument of E1(x)         
555 //      Output:  E1 --- E1(x)                     
556 //      ======================================    
557                                                   
558 G4double E1, R, T, T0;                            
559 G4int M;                                          
560                                                   
561 if (X==0)                                         
562 {                                                 
563     E1=1.e300;                                    
564 }                                                 
565 else if (X<=1.)                                   
566 {                                                 
567    E1=1.;                                         
568    R=1.;                                          
569                                                   
570                                                   
571    for(int K=1; K<=25; K++)                       
572    {                                              
573        R=-R*K*X/std::pow(K+1.,2.);                
574        E1=E1+R;                                   
575        if (std::abs(R)<=std::abs(E1)*1.0e-15)     
576    }                                              
577                                                   
578    E1=-0.5772156649015328-G4Log(X)+X*E1;          
579 }                                                 
580 else                                              
581 {                                                 
582    M=20+std::trunc(80.0/X);                       
583    T0=0.;                                         
584                                                   
585    for(int K=M; K>=1; K--)                        
586    {                                              
587       T0=K/(1.0+K/(X+T0));                        
588    }                                              
589                                                   
590    T=1.0/(X+T0);                                  
591    E1=std::exp(-X)*T;                             
592 }                                                 
593                                                   
594 return E1;                                        
595 }                                                 
596