Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/examples/advanced/eRosita/physics/src/G4RDVeLowEnergyLoss.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 /examples/advanced/eRosita/physics/src/G4RDVeLowEnergyLoss.cc (Version 11.3.0) and /examples/advanced/eRosita/physics/src/G4RDVeLowEnergyLoss.cc (Version 11.0.p3,)


** Warning: Cannot open xref database.

  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 //                                                
 27 //                                                
 28 //                                                
 29 // -------------------------------------------    
 30 //  GEANT 4 class implementation file             
 31 //                                                
 32 //  History: first implementation, based on ob    
 33 //  2nd December 1995, G.Cosmo                    
 34 // -------------------------------------------    
 35 //                                                
 36 // Modifications:                                 
 37 // 20/09/00 update fluctuations V.Ivanchenko      
 38 // 22/11/00 minor fix in fluctuations V.Ivanch    
 39 // 10/05/01  V.Ivanchenko Clean up againist Li    
 40 // 22/05/01  V.Ivanchenko Update range calcula    
 41 // 23/11/01  V.Ivanchenko Move static member-f    
 42 // 22/01/03  V.Ivanchenko Cut per region          
 43 // 11/02/03  V.Ivanchenko Add limits to fluctu    
 44 // 24/04/03  V.Ivanchenko Fix the problem of t    
 45 //                                                
 46 // -------------------------------------------    
 47                                                   
 48 #include "G4RDVeLowEnergyLoss.hh"                 
 49 #include "G4PhysicalConstants.hh"                 
 50 #include "G4SystemOfUnits.hh"                     
 51 #include "G4ProductionCutsTable.hh"               
 52                                                   
 53 G4double     G4RDVeLowEnergyLoss::ParticleMass    
 54 G4double     G4RDVeLowEnergyLoss::taulow          
 55 G4double     G4RDVeLowEnergyLoss::tauhigh         
 56 G4double     G4RDVeLowEnergyLoss::ltaulow         
 57 G4double     G4RDVeLowEnergyLoss::ltauhigh        
 58                                                   
 59                                                   
 60 G4bool       G4RDVeLowEnergyLoss::rndmStepFlag    
 61 G4bool       G4RDVeLowEnergyLoss::EnlossFlucFl    
 62 G4double     G4RDVeLowEnergyLoss::dRoverRange     
 63 G4double     G4RDVeLowEnergyLoss::finalRange      
 64 G4double     G4RDVeLowEnergyLoss::c1lim = dRov    
 65 G4double     G4RDVeLowEnergyLoss::c2lim = 2.*(    
 66 G4double     G4RDVeLowEnergyLoss::c3lim = -(1.    
 67                                                   
 68                                                   
 69 //                                                
 70                                                   
 71 G4RDVeLowEnergyLoss::G4RDVeLowEnergyLoss()        
 72                    :G4VContinuousDiscreteProce    
 73      lastMaterial(0),                             
 74      nmaxCont1(4),                                
 75      nmaxCont2(16)                                
 76 {                                                 
 77   G4Exception("G4RDVeLowEnergyLoss::G4RDVeLowE    
 78               FatalException, "Default constru    
 79 }                                                 
 80                                                   
 81 //                                                
 82                                                   
 83 G4RDVeLowEnergyLoss::G4RDVeLowEnergyLoss(const    
 84                   : G4VContinuousDiscreteProce    
 85      lastMaterial(0),                             
 86      nmaxCont1(4),                                
 87      nmaxCont2(16)                                
 88 {                                                 
 89 }                                                 
 90                                                   
 91 //                                                
 92                                                   
 93 G4RDVeLowEnergyLoss::~G4RDVeLowEnergyLoss()       
 94 {                                                 
 95 }                                                 
 96                                                   
 97 //                                                
 98                                                   
 99 G4RDVeLowEnergyLoss::G4RDVeLowEnergyLoss(G4RDV    
100                   : G4VContinuousDiscreteProce    
101      lastMaterial(0),                             
102      nmaxCont1(4),                                
103      nmaxCont2(16)                                
104 {                                                 
105 }                                                 
106                                                   
107 void G4RDVeLowEnergyLoss::SetRndmStep(G4bool v    
108 {                                                 
109    rndmStepFlag   = value;                        
110 }                                                 
111                                                   
112 void G4RDVeLowEnergyLoss::SetEnlossFluc(G4bool    
113 {                                                 
114    EnlossFlucFlag = value;                        
115 }                                                 
116                                                   
117 void G4RDVeLowEnergyLoss::SetStepFunction (G4d    
118 {                                                 
119    dRoverRange = c1;                              
120    finalRange = c2;                               
121    c1lim=dRoverRange;                             
122    c2lim=2.*(1-dRoverRange)*finalRange;           
123    c3lim=-(1.-dRoverRange)*finalRange*finalRan    
124 }                                                 
125                                                   
126 G4PhysicsTable* G4RDVeLowEnergyLoss::BuildRang    
127                G4PhysicsTable* theRangeTable,     
128                G4double lowestKineticEnergy,      
129                G4double highestKineticEnergy,     
130                G4int TotBin)                      
131 // Build range table from the energy loss tabl    
132 {                                                 
133                                                   
134    G4int numOfCouples = theDEDXTable->length()    
135                                                   
136    if(theRangeTable)                              
137    { theRangeTable->clearAndDestroy();            
138      delete theRangeTable; }                      
139    theRangeTable = new G4PhysicsTable(numOfCou    
140                                                   
141    // loop for materials                          
142                                                   
143    for (G4int J=0;  J<numOfCouples; J++)          
144    {                                              
145      G4PhysicsLogVector* aVector;                 
146      aVector = new G4PhysicsLogVector(lowestKi    
147                               highestKineticEn    
148      BuildRangeVector(theDEDXTable,lowestKinet    
149                       TotBin,J,aVector);          
150      theRangeTable->insert(aVector);              
151    }                                              
152    return theRangeTable ;                         
153 }                                                 
154                                                   
155 //                                                
156                                                   
157 void G4RDVeLowEnergyLoss::BuildRangeVector(G4P    
158                                          G4dou    
159                                          G4dou    
160                                          G4int    
161                                          G4int    
162                                          G4Phy    
163                                                   
164 //  create range vector for a material            
165 {                                                 
166   G4bool isOut;                                   
167   G4PhysicsVector* physicsVector= (*theDEDXTab    
168   G4double energy1 = lowestKineticEnergy;         
169   G4double dedx    = physicsVector->GetValue(e    
170   G4double range   = 0.5*energy1/dedx;            
171   rangeVector->PutValue(0,range);                 
172   G4int n = 100;                                  
173   G4double del = 1.0/(G4double)n ;                
174                                                   
175   for (G4int j=1; j<TotBin; j++) {                
176                                                   
177     G4double energy2 = rangeVector->GetLowEdge    
178     G4double de = (energy2 - energy1) * del ;     
179     G4double dedx1 = dedx ;                       
180                                                   
181     for (G4int i=1; i<n; i++) {                   
182       G4double energy = energy1 + i*de ;          
183       G4double dedx2  = physicsVector->GetValu    
184       range  += 0.5*de*(1.0/dedx1 + 1.0/dedx2)    
185       dedx1   = dedx2;                            
186     }                                             
187     rangeVector->PutValue(j,range);               
188     dedx = dedx1 ;                                
189     energy1 = energy2 ;                           
190   }                                               
191 }                                                 
192                                                   
193 //                                                
194                                                   
195 G4double G4RDVeLowEnergyLoss::RangeIntLin(G4Ph    
196           G4int nbin)                             
197 //  num. integration, linear binning              
198 {                                                 
199   G4double dtau,Value,taui,ti,lossi,ci;           
200   G4bool isOut;                                   
201   dtau = (tauhigh-taulow)/nbin;                   
202   Value = 0.;                                     
203                                                   
204   for (G4int i=0; i<=nbin; i++)                   
205   {                                               
206     taui = taulow + dtau*i ;                      
207     ti = ParticleMass*taui;                       
208     lossi = physicsVector->GetValue(ti,isOut);    
209     if(i==0)                                      
210       ci=0.5;                                     
211     else                                          
212     {                                             
213       if(i<nbin)                                  
214         ci=1.;                                    
215       else                                        
216         ci=0.5;                                   
217     }                                             
218     Value += ci/lossi;                            
219   }                                               
220   Value *= ParticleMass*dtau;                     
221   return Value;                                   
222 }                                                 
223                                                   
224 //                                                
225                                                   
226 G4double G4RDVeLowEnergyLoss::RangeIntLog(G4Ph    
227           G4int nbin)                             
228 //  num. integration, logarithmic binning         
229 {                                                 
230   G4double ltt,dltau,Value,ui,taui,ti,lossi,ci    
231   G4bool isOut;                                   
232   ltt = ltauhigh-ltaulow;                         
233   dltau = ltt/nbin;                               
234   Value = 0.;                                     
235                                                   
236   for (G4int i=0; i<=nbin; i++)                   
237   {                                               
238     ui = ltaulow+dltau*i;                         
239     taui = std::exp(ui);                          
240     ti = ParticleMass*taui;                       
241     lossi = physicsVector->GetValue(ti,isOut);    
242     if(i==0)                                      
243       ci=0.5;                                     
244     else                                          
245     {                                             
246       if(i<nbin)                                  
247         ci=1.;                                    
248       else                                        
249         ci=0.5;                                   
250     }                                             
251     Value += ci*taui/lossi;                       
252   }                                               
253   Value *= ParticleMass*dltau;                    
254   return Value;                                   
255 }                                                 
256                                                   
257                                                   
258 //                                                
259                                                   
260 G4PhysicsTable* G4RDVeLowEnergyLoss::BuildLabT    
261                  G4PhysicsTable* theLabTimeTab    
262                  G4double lowestKineticEnergy,    
263                  G4double highestKineticEnergy    
264                                                   
265 {                                                 
266                                                   
267   G4int numOfCouples = G4ProductionCutsTable::    
268                                                   
269   if(theLabTimeTable)                             
270   { theLabTimeTable->clearAndDestroy();           
271     delete theLabTimeTable; }                     
272   theLabTimeTable = new G4PhysicsTable(numOfCo    
273                                                   
274                                                   
275   for (G4int J=0;  J<numOfCouples; J++)           
276   {                                               
277     G4PhysicsLogVector* aVector;                  
278                                                   
279     aVector = new G4PhysicsLogVector(lowestKin    
280                             highestKineticEner    
281                                                   
282     BuildLabTimeVector(theDEDXTable,              
283               lowestKineticEnergy,highestKinet    
284     theLabTimeTable->insert(aVector);             
285                                                   
286                                                   
287   }                                               
288   return theLabTimeTable ;                        
289 }                                                 
290                                                   
291 //                                                
292                                                   
293 G4PhysicsTable* G4RDVeLowEnergyLoss::BuildProp    
294               G4PhysicsTable* theProperTimeTab    
295               G4double lowestKineticEnergy,       
296               G4double highestKineticEnergy,G4    
297                                                   
298 {                                                 
299                                                   
300   G4int numOfCouples = G4ProductionCutsTable::    
301                                                   
302   if(theProperTimeTable)                          
303   { theProperTimeTable->clearAndDestroy();        
304     delete theProperTimeTable; }                  
305   theProperTimeTable = new G4PhysicsTable(numO    
306                                                   
307                                                   
308   for (G4int J=0;  J<numOfCouples; J++)           
309   {                                               
310     G4PhysicsLogVector* aVector;                  
311                                                   
312     aVector = new G4PhysicsLogVector(lowestKin    
313                             highestKineticEner    
314                                                   
315     BuildProperTimeVector(theDEDXTable,           
316               lowestKineticEnergy,highestKinet    
317     theProperTimeTable->insert(aVector);          
318                                                   
319                                                   
320   }                                               
321   return theProperTimeTable ;                     
322 }                                                 
323                                                   
324 //                                                
325                                                   
326 void G4RDVeLowEnergyLoss::BuildLabTimeVector(G    
327              G4double, // lowestKineticEnergy,    
328              G4double, // highestKineticEnergy    
329                                            G4i    
330              G4int materialIndex, G4PhysicsLog    
331 //  create lab time vector for a material         
332 {                                                 
333                                                   
334   G4int nbin=100;                                 
335   G4bool isOut;                                   
336   G4double tlim=5.*keV,parlowen=0.4,ppar=0.5-p    
337   G4double losslim,clim,taulim,timelim,           
338            LowEdgeEnergy,tau,Value ;              
339                                                   
340   G4PhysicsVector* physicsVector= (*theDEDXTab    
341                                                   
342   // low energy part first...                     
343   losslim = physicsVector->GetValue(tlim,isOut    
344   taulim=tlim/ParticleMass ;                      
345   clim=std::sqrt(ParticleMass*tlim/2.)/(c_ligh    
346                                                   
347   G4int i=-1;                                     
348   G4double oldValue = 0. ;                        
349   G4double tauold ;                               
350   do                                              
351   {                                               
352     i += 1 ;                                      
353     LowEdgeEnergy = timeVector->GetLowEdgeEner    
354     tau = LowEdgeEnergy/ParticleMass ;            
355     if ( tau <= taulim )                          
356     {                                             
357       Value = clim*std::exp(ppar*std::log(tau/    
358     }                                             
359     else                                          
360     {                                             
361       timelim=clim ;                              
362       ltaulow = std::log(taulim);                 
363       ltauhigh = std::log(tau);                   
364       Value = timelim+LabTimeIntLog(physicsVec    
365     }                                             
366     timeVector->PutValue(i,Value);                
367     oldValue = Value ;                            
368     tauold = tau ;                                
369   } while (tau<=taulim) ;                         
370   i += 1 ;                                        
371   for (G4int j=i; j<TotBin; j++)                  
372   {                                               
373     LowEdgeEnergy = timeVector->GetLowEdgeEner    
374     tau = LowEdgeEnergy/ParticleMass ;            
375     ltaulow = std::log(tauold);                   
376     ltauhigh = std::log(tau);                     
377     Value = oldValue+LabTimeIntLog(physicsVect    
378     timeVector->PutValue(j,Value);                
379     oldValue = Value ;                            
380     tauold = tau ;                                
381   }                                               
382 }                                                 
383                                                   
384 //                                                
385                                                   
386 void G4RDVeLowEnergyLoss::BuildProperTimeVecto    
387                 G4double, // lowestKineticEner    
388                 G4double, // highestKineticEne    
389                                                   
390                 G4int materialIndex, G4Physics    
391 //  create proper time vector for a material      
392 {                                                 
393   G4int nbin=100;                                 
394   G4bool isOut;                                   
395   G4double tlim=5.*keV,parlowen=0.4,ppar=0.5-p    
396   G4double losslim,clim,taulim,timelim,           
397            LowEdgeEnergy,tau,Value ;              
398                                                   
399   G4PhysicsVector* physicsVector= (*theDEDXTab    
400   //const G4MaterialTable* theMaterialTable =     
401                                                   
402   // low energy part first...                     
403   losslim = physicsVector->GetValue(tlim,isOut    
404   taulim=tlim/ParticleMass ;                      
405   clim=std::sqrt(ParticleMass*tlim/2.)/(c_ligh    
406                                                   
407   G4int i=-1;                                     
408   G4double oldValue = 0. ;                        
409   G4double tauold ;                               
410   do                                              
411   {                                               
412     i += 1 ;                                      
413     LowEdgeEnergy = timeVector->GetLowEdgeEner    
414     tau = LowEdgeEnergy/ParticleMass ;            
415     if ( tau <= taulim )                          
416     {                                             
417       Value = clim*std::exp(ppar*std::log(tau/    
418     }                                             
419     else                                          
420     {                                             
421       timelim=clim ;                              
422       ltaulow = std::log(taulim);                 
423       ltauhigh = std::log(tau);                   
424       Value = timelim+ProperTimeIntLog(physics    
425     }                                             
426     timeVector->PutValue(i,Value);                
427     oldValue = Value ;                            
428     tauold = tau ;                                
429   } while (tau<=taulim) ;                         
430   i += 1 ;                                        
431   for (G4int j=i; j<TotBin; j++)                  
432   {                                               
433     LowEdgeEnergy = timeVector->GetLowEdgeEner    
434     tau = LowEdgeEnergy/ParticleMass ;            
435     ltaulow = std::log(tauold);                   
436     ltauhigh = std::log(tau);                     
437     Value = oldValue+ProperTimeIntLog(physicsV    
438     timeVector->PutValue(j,Value);                
439     oldValue = Value ;                            
440     tauold = tau ;                                
441   }                                               
442 }                                                 
443                                                   
444 //                                                
445                                                   
446 G4double G4RDVeLowEnergyLoss::LabTimeIntLog(G4    
447             G4int nbin)                           
448 //  num. integration, logarithmic binning         
449 {                                                 
450   G4double ltt,dltau,Value,ui,taui,ti,lossi,ci    
451   G4bool isOut;                                   
452   ltt = ltauhigh-ltaulow;                         
453   dltau = ltt/nbin;                               
454   Value = 0.;                                     
455                                                   
456   for (G4int i=0; i<=nbin; i++)                   
457   {                                               
458     ui = ltaulow+dltau*i;                         
459     taui = std::exp(ui);                          
460     ti = ParticleMass*taui;                       
461     lossi = physicsVector->GetValue(ti,isOut);    
462     if(i==0)                                      
463       ci=0.5;                                     
464     else                                          
465     {                                             
466       if(i<nbin)                                  
467         ci=1.;                                    
468       else                                        
469         ci=0.5;                                   
470     }                                             
471     Value += ci*taui*(ti+ParticleMass)/(std::s    
472   }                                               
473   Value *= ParticleMass*dltau/c_light;            
474   return Value;                                   
475 }                                                 
476                                                   
477 //                                                
478                                                   
479 G4double G4RDVeLowEnergyLoss::ProperTimeIntLog    
480                G4int nbin)                        
481 //  num. integration, logarithmic binning         
482 {                                                 
483   G4double ltt,dltau,Value,ui,taui,ti,lossi,ci    
484   G4bool isOut;                                   
485   ltt = ltauhigh-ltaulow;                         
486   dltau = ltt/nbin;                               
487   Value = 0.;                                     
488                                                   
489   for (G4int i=0; i<=nbin; i++)                   
490   {                                               
491     ui = ltaulow+dltau*i;                         
492     taui = std::exp(ui);                          
493     ti = ParticleMass*taui;                       
494     lossi = physicsVector->GetValue(ti,isOut);    
495     if(i==0)                                      
496       ci=0.5;                                     
497     else                                          
498     {                                             
499       if(i<nbin)                                  
500         ci=1.;                                    
501       else                                        
502         ci=0.5;                                   
503     }                                             
504     Value += ci*taui*ParticleMass/(std::sqrt(t    
505   }                                               
506   Value *= ParticleMass*dltau/c_light;            
507   return Value;                                   
508 }                                                 
509                                                   
510 //                                                
511                                                   
512 G4PhysicsTable* G4RDVeLowEnergyLoss::BuildInve    
513                 G4PhysicsTable*,                  
514                 G4PhysicsTable*,                  
515                 G4PhysicsTable*,                  
516                 G4PhysicsTable* theInverseRang    
517                 G4double, // lowestKineticEner    
518                 G4double, // highestKineticEne    
519                 G4int )   // nbins                
520 // Build inverse table of the range table         
521 {                                                 
522   G4bool b;                                       
523                                                   
524   G4int numOfCouples = G4ProductionCutsTable::    
525                                                   
526     if(theInverseRangeTable)                      
527     { theInverseRangeTable->clearAndDestroy();    
528       delete theInverseRangeTable; }              
529     theInverseRangeTable = new G4PhysicsTable(    
530                                                   
531   // loop for materials                           
532   for (G4int i=0;  i<numOfCouples; i++)           
533   {                                               
534                                                   
535     G4PhysicsVector* pv = (*theRangeTable)[i];    
536     size_t nbins   = pv->GetVectorLength();       
537     G4double elow  = pv->GetLowEdgeEnergy(0);     
538     G4double ehigh = pv->GetLowEdgeEnergy(nbin    
539     G4double rlow  = pv->GetValue(elow, b);       
540     G4double rhigh = pv->GetValue(ehigh, b);      
541                                                   
542     rhigh *= std::exp(std::log(rhigh/rlow)/((G    
543                                                   
544     G4PhysicsLogVector* v = new G4PhysicsLogVe    
545                                                   
546     v->PutValue(0,elow);                          
547     G4double energy1 = elow;                      
548     G4double range1  = rlow;                      
549     G4double energy2 = elow;                      
550     G4double range2  = rlow;                      
551     size_t ilow      = 0;                         
552     size_t ihigh;                                 
553                                                   
554     for (size_t j=1; j<nbins; j++) {              
555                                                   
556       G4double range = v->GetLowEdgeEnergy(j);    
557                                                   
558       for (ihigh=ilow+1; ihigh<nbins; ihigh++)    
559         energy2 = pv->GetLowEdgeEnergy(ihigh);    
560         range2  = pv->GetValue(energy2, b);       
561         if(range2 >= range || ihigh == nbins-1    
562           ilow = ihigh - 1;                       
563           energy1 = pv->GetLowEdgeEnergy(ilow)    
564           range1  = pv->GetValue(energy1, b);     
565           break;                                  
566   }                                               
567       }                                           
568                                                   
569       G4double e = std::log(energy1) + std::lo    
570                                                   
571       v->PutValue(j,std::exp(e));                 
572     }                                             
573     theInverseRangeTable->insert(v);              
574                                                   
575   }                                               
576   return theInverseRangeTable ;                   
577 }                                                 
578                                                   
579 //                                                
580                                                   
581 void G4RDVeLowEnergyLoss::InvertRangeVector(G4    
582             G4PhysicsTable* theRangeCoeffATabl    
583             G4PhysicsTable* theRangeCoeffBTabl    
584             G4PhysicsTable* theRangeCoeffCTabl    
585             G4double lowestKineticEnergy,         
586             G4double highestKineticEnergy, G4i    
587             G4int  materialIndex, G4PhysicsLog    
588 //  invert range vector for a material            
589 {                                                 
590   G4double LowEdgeRange,A,B,C,discr,KineticEne    
591   G4double RTable = std::exp(std::log(highestK    
592   G4double Tbin = lowestKineticEnergy/RTable ;    
593   G4double rangebin = 0.0 ;                       
594   G4int binnumber = -1 ;                          
595   G4bool isOut ;                                  
596                                                   
597   //loop for range values                         
598   for( G4int i=0; i<TotBin; i++)                  
599   {                                               
600     LowEdgeRange = aVector->GetLowEdgeEnergy(i    
601     if( rangebin < LowEdgeRange )                 
602     {                                             
603       do                                          
604       {                                           
605         binnumber += 1 ;                          
606         Tbin *= RTable ;                          
607         rangebin = (*theRangeTable)(materialIn    
608       }                                           
609       while ((rangebin < LowEdgeRange) && (bin    
610     }                                             
611                                                   
612     if(binnumber == 0)                            
613       KineticEnergy = lowestKineticEnergy ;       
614     else if(binnumber == TotBin-1)                
615       KineticEnergy = highestKineticEnergy ;      
616     else                                          
617     {                                             
618       A = (*(*theRangeCoeffATable)(materialInd    
619       B = (*(*theRangeCoeffBTable)(materialInd    
620       C = (*(*theRangeCoeffCTable)(materialInd    
621       if(A==0.)                                   
622          KineticEnergy = (LowEdgeRange -C )/B     
623       else                                        
624       {                                           
625          discr = B*B - 4.*A*(C-LowEdgeRange);     
626          discr = discr>0. ? std::sqrt(discr) :    
627          KineticEnergy = 0.5*(discr-B)/A ;        
628       }                                           
629     }                                             
630                                                   
631     aVector->PutValue(i,KineticEnergy) ;          
632   }                                               
633 }                                                 
634                                                   
635 //                                                
636                                                   
637 G4PhysicsTable* G4RDVeLowEnergyLoss::BuildRang    
638                G4PhysicsTable* theRangeCoeffAT    
639                G4double lowestKineticEnergy,      
640                G4double highestKineticEnergy,     
641 // Build tables of coefficients for the energy    
642 //  create table for coefficients "A"             
643 {                                                 
644                                                   
645   G4int numOfCouples = G4ProductionCutsTable::    
646                                                   
647   if(theRangeCoeffATable)                         
648   { theRangeCoeffATable->clearAndDestroy();       
649     delete theRangeCoeffATable; }                 
650   theRangeCoeffATable = new G4PhysicsTable(num    
651                                                   
652   G4double RTable = std::exp(std::log(highestK    
653   G4double R2 = RTable*RTable ;                   
654   G4double R1 = RTable+1.;                        
655   G4double w = R1*(RTable-1.)*(RTable-1.);        
656   G4double w1 = RTable/w , w2 = -RTable*R1/w ,    
657   G4double Ti , Tim , Tip , Ri , Rim , Rip , V    
658   G4bool isOut;                                   
659                                                   
660   //  loop for materials                          
661   for (G4int J=0; J<numOfCouples; J++)            
662   {                                               
663     G4int binmax=TotBin ;                         
664     G4PhysicsLinearVector* aVector =              
665                            new G4PhysicsLinear    
666     Ti = lowestKineticEnergy ;                    
667     G4PhysicsVector* rangeVector= (*theRangeTa    
668                                                   
669     for ( G4int i=0; i<TotBin; i++)               
670     {                                             
671       Ri = rangeVector->GetValue(Ti,isOut) ;      
672       if ( i==0 )                                 
673         Rim = 0. ;                                
674       else                                        
675       {                                           
676         Tim = Ti/RTable ;                         
677         Rim = rangeVector->GetValue(Tim,isOut)    
678       }                                           
679       if ( i==(TotBin-1))                         
680         Rip = Ri ;                                
681       else                                        
682       {                                           
683         Tip = Ti*RTable ;                         
684         Rip = rangeVector->GetValue(Tip,isOut)    
685       }                                           
686       Value = (w1*Rip + w2*Ri + w3*Rim)/(Ti*Ti    
687                                                   
688       aVector->PutValue(i,Value);                 
689       Ti = RTable*Ti ;                            
690     }                                             
691                                                   
692     theRangeCoeffATable->insert(aVector);         
693   }                                               
694   return theRangeCoeffATable ;                    
695 }                                                 
696                                                   
697 //                                                
698                                                   
699 G4PhysicsTable* G4RDVeLowEnergyLoss::BuildRang    
700                G4PhysicsTable* theRangeCoeffBT    
701                G4double lowestKineticEnergy,      
702                G4double highestKineticEnergy,     
703 // Build tables of coefficients for the energy    
704 //  create table for coefficients "B"             
705 {                                                 
706                                                   
707   G4int numOfCouples = G4ProductionCutsTable::    
708                                                   
709   if(theRangeCoeffBTable)                         
710   { theRangeCoeffBTable->clearAndDestroy();       
711     delete theRangeCoeffBTable; }                 
712   theRangeCoeffBTable = new G4PhysicsTable(num    
713                                                   
714   G4double RTable = std::exp(std::log(highestK    
715   G4double R2 = RTable*RTable ;                   
716   G4double R1 = RTable+1.;                        
717   G4double w = R1*(RTable-1.)*(RTable-1.);        
718   G4double w1 = -R1/w , w2 = R1*(R2+1.)/w , w3    
719   G4double Ti , Tim , Tip , Ri , Rim , Rip , V    
720   G4bool isOut;                                   
721                                                   
722   //  loop for materials                          
723   for (G4int J=0; J<numOfCouples; J++)            
724   {                                               
725     G4int binmax=TotBin ;                         
726     G4PhysicsLinearVector* aVector =              
727                         new G4PhysicsLinearVec    
728     Ti = lowestKineticEnergy ;                    
729     G4PhysicsVector* rangeVector= (*theRangeTa    
730                                                   
731     for ( G4int i=0; i<TotBin; i++)               
732     {                                             
733       Ri = rangeVector->GetValue(Ti,isOut) ;      
734       if ( i==0 )                                 
735          Rim = 0. ;                               
736       else                                        
737       {                                           
738         Tim = Ti/RTable ;                         
739         Rim = rangeVector->GetValue(Tim,isOut)    
740       }                                           
741       if ( i==(TotBin-1))                         
742         Rip = Ri ;                                
743       else                                        
744       {                                           
745         Tip = Ti*RTable ;                         
746         Rip = rangeVector->GetValue(Tip,isOut)    
747       }                                           
748       Value = (w1*Rip + w2*Ri + w3*Rim)/Ti;       
749                                                   
750       aVector->PutValue(i,Value);                 
751       Ti = RTable*Ti ;                            
752     }                                             
753     theRangeCoeffBTable->insert(aVector);         
754   }                                               
755   return theRangeCoeffBTable ;                    
756 }                                                 
757                                                   
758 //                                                
759                                                   
760 G4PhysicsTable* G4RDVeLowEnergyLoss::BuildRang    
761                G4PhysicsTable* theRangeCoeffCT    
762                G4double lowestKineticEnergy,      
763                G4double highestKineticEnergy,     
764 // Build tables of coefficients for the energy    
765 //  create table for coefficients "C"             
766 {                                                 
767                                                   
768   G4int numOfCouples = G4ProductionCutsTable::    
769                                                   
770   if(theRangeCoeffCTable)                         
771   { theRangeCoeffCTable->clearAndDestroy();       
772     delete theRangeCoeffCTable; }                 
773   theRangeCoeffCTable = new G4PhysicsTable(num    
774                                                   
775   G4double RTable = std::exp(std::log(highestK    
776   G4double R2 = RTable*RTable ;                   
777   G4double R1 = RTable+1.;                        
778   G4double w = R1*(RTable-1.)*(RTable-1.);        
779   G4double w1 = 1./w , w2 = -RTable*R1/w , w3     
780   G4double Ti , Tim , Tip , Ri , Rim , Rip , V    
781   G4bool isOut;                                   
782                                                   
783   //  loop for materials                          
784   for (G4int J=0; J<numOfCouples; J++)            
785   {                                               
786     G4int binmax=TotBin ;                         
787     G4PhysicsLinearVector* aVector =              
788                       new G4PhysicsLinearVecto    
789     Ti = lowestKineticEnergy ;                    
790     G4PhysicsVector* rangeVector= (*theRangeTa    
791                                                   
792     for ( G4int i=0; i<TotBin; i++)               
793     {                                             
794       Ri = rangeVector->GetValue(Ti,isOut) ;      
795       if ( i==0 )                                 
796         Rim = 0. ;                                
797       else                                        
798       {                                           
799         Tim = Ti/RTable ;                         
800         Rim = rangeVector->GetValue(Tim,isOut)    
801       }                                           
802       if ( i==(TotBin-1))                         
803         Rip = Ri ;                                
804       else                                        
805       {                                           
806         Tip = Ti*RTable ;                         
807         Rip = rangeVector->GetValue(Tip,isOut)    
808       }                                           
809       Value = w1*Rip + w2*Ri + w3*Rim ;           
810                                                   
811       aVector->PutValue(i,Value);                 
812       Ti = RTable*Ti ;                            
813     }                                             
814     theRangeCoeffCTable->insert(aVector);         
815   }                                               
816   return theRangeCoeffCTable ;                    
817 }                                                 
818                                                   
819 //                                                
820                                                   
821 G4double G4RDVeLowEnergyLoss::GetLossWithFluct    
822                                              c    
823                G4double MeanLoss,                 
824                G4double step)                     
825 //  calculate actual loss from the mean loss      
826 //  The model used to get the fluctuation is e    
827 {                                                 
828    static const G4double minLoss = 1.*eV ;        
829    static const G4double probLim = 0.01 ;         
830    static const G4double sumaLim = -std::log(p    
831    static const G4double alim=10.;                
832    static const G4double kappa = 10. ;            
833    static const G4double factor = twopi_mc2_rc    
834   const G4Material* aMaterial = couple->GetMat    
835                                                   
836   // check if the material has changed ( cache    
837                                                   
838   if (aMaterial != lastMaterial)                  
839     {                                             
840       lastMaterial = aMaterial;                   
841       imat         = couple->GetIndex();          
842       f1Fluct      = aMaterial->GetIonisation(    
843       f2Fluct      = aMaterial->GetIonisation(    
844       e1Fluct      = aMaterial->GetIonisation(    
845       e2Fluct      = aMaterial->GetIonisation(    
846       e1LogFluct   = aMaterial->GetIonisation(    
847       e2LogFluct   = aMaterial->GetIonisation(    
848       rateFluct    = aMaterial->GetIonisation(    
849       ipotFluct    = aMaterial->GetIonisation(    
850       ipotLogFluct = aMaterial->GetIonisation(    
851     }                                             
852   G4double threshold,w1,w2,C,                     
853            beta2,suma,e0,loss,lossc,w;            
854   G4double a1,a2,a3;                              
855   G4int p1,p2,p3;                                 
856   G4int nb;                                       
857   G4double Corrfac, na,alfa,rfac,namean,sa,alf    
858   //  G4double dp1;                               
859   G4double dp3;                                   
860   G4double siga ;                                 
861                                                   
862   // shortcut for very very small loss            
863   if(MeanLoss < minLoss) return MeanLoss ;        
864                                                   
865   // get particle data                            
866   G4double Tkin   = aParticle->GetKineticEnerg    
867                                                   
868   //  G4cout << "MGP -- Fluc Tkin " << Tkin/ke    
869                                                   
870   threshold = (*((G4ProductionCutsTable::GetPr    
871                 ->GetEnergyCutsVector(1)))[ima    
872   G4double rmass = electron_mass_c2/ParticleMa    
873   G4double tau   = Tkin/ParticleMass, tau1 = t    
874   G4double Tm    = 2.*electron_mass_c2*tau2/(1    
875                                                   
876   // G4cout << "MGP Particle mass " << Particl    
877                                                   
878   if(Tm > threshold) Tm = threshold;              
879   beta2 = tau2/(tau1*tau1);                       
880                                                   
881   // Gaussian fluctuation ?                       
882   if(MeanLoss >= kappa*Tm || MeanLoss <= kappa    
883   {                                               
884     G4double electronDensity = aMaterial->GetE    
885     siga = std::sqrt(Tm*(1.0-0.5*beta2)*step*     
886                 factor*electronDensity/beta2)     
887     do {                                          
888       loss = G4RandGauss::shoot(MeanLoss,siga)    
889     } while (loss < 0. || loss > 2.0*MeanLoss)    
890     return loss ;                                 
891   }                                               
892                                                   
893   w1 = Tm/ipotFluct;                              
894   w2 = std::log(2.*electron_mass_c2*tau2);        
895                                                   
896   C = MeanLoss*(1.-rateFluct)/(w2-ipotLogFluct    
897                                                   
898   a1 = C*f1Fluct*(w2-e1LogFluct-beta2)/e1Fluct    
899   a2 = C*f2Fluct*(w2-e2LogFluct-beta2)/e2Fluct    
900   a3 = rateFluct*MeanLoss*(Tm-ipotFluct)/(ipot    
901                                                   
902   suma = a1+a2+a3;                                
903                                                   
904   loss = 0. ;                                     
905                                                   
906   if(suma < sumaLim)             // very small    
907     {                                             
908       e0 = aMaterial->GetIonisation()->GetEner    
909       // G4cout << "MGP e0 = " << e0/keV << G4    
910                                                   
911       if(Tm == ipotFluct)                         
912   {                                               
913     a3 = MeanLoss/e0;                             
914                                                   
915     if(a3>alim)                                   
916       {                                           
917         siga=std::sqrt(a3) ;                      
918         p3 = std::max(0,G4int(G4RandGauss::sho    
919       }                                           
920     else p3 = G4Poisson(a3);                      
921                                                   
922     loss = p3*e0 ;                                
923                                                   
924     if(p3 > 0) loss += (1.-2.*G4UniformRand())    
925     // G4cout << "MGP very small step " << los    
926   }                                               
927       else                                        
928   {                                               
929     //    G4cout << "MGP old Tm = " << Tm << "    
930     Tm = Tm-ipotFluct+e0 ;                        
931                                                   
932     // MGP ---- workaround to avoid log argume    
933     if (Tm <= 0.)                                 
934       {                                           
935         loss = MeanLoss;                          
936         p3 = 0;                                   
937         // G4cout << "MGP correction loss = Me    
938       }                                           
939     else                                          
940       {                                           
941         a3 = MeanLoss*(Tm-e0)/(Tm*e0*std::log(    
942                                                   
943         // G4cout << "MGP new Tm = " << Tm <<     
944                                                   
945         if(a3>alim)                               
946     {                                             
947       siga=std::sqrt(a3) ;                        
948       p3 = std::max(0,G4int(G4RandGauss::shoot    
949     }                                             
950         else                                      
951     p3 = G4Poisson(a3);                           
952         //G4cout << "MGP p3 " << p3 << G4endl;    
953                                                   
954       }                                           
955                                                   
956     if(p3 > 0)                                    
957       {                                           
958         w = (Tm-e0)/Tm ;                          
959         if(p3 > nmaxCont2)                        
960     {                                             
961       // G4cout << "MGP dp3 " << dp3 << " p3 "    
962       dp3 = G4double(p3) ;                        
963       Corrfac = dp3/G4double(nmaxCont2) ;         
964       p3 = nmaxCont2 ;                            
965     }                                             
966         else                                      
967     Corrfac = 1. ;                                
968                                                   
969         for(G4int i=0; i<p3; i++) loss += 1./(    
970         loss *= e0*Corrfac ;                      
971         // G4cout << "MGP Corrfac = " << Corrf    
972       }                                           
973   }                                               
974     }                                             
975                                                   
976   else                              // not so     
977     {                                             
978       // excitation type 1                        
979       if(a1>alim)                                 
980       {                                           
981         siga=std::sqrt(a1) ;                      
982         p1 = std::max(0,int(G4RandGauss::shoot    
983       }                                           
984       else                                        
985        p1 = G4Poisson(a1);                        
986                                                   
987       // excitation type 2                        
988       if(a2>alim)                                 
989       {                                           
990         siga=std::sqrt(a2) ;                      
991         p2 = std::max(0,int(G4RandGauss::shoot    
992       }                                           
993       else                                        
994         p2 = G4Poisson(a2);                       
995                                                   
996       loss = p1*e1Fluct+p2*e2Fluct;               
997                                                   
998       // smearing to avoid unphysical peaks       
999       if(p2 > 0)                                  
1000         loss += (1.-2.*G4UniformRand())*e2Flu    
1001       else if (loss>0.)                          
1002         loss += (1.-2.*G4UniformRand())*e1Flu    
1003                                                  
1004       // ionisation .........................    
1005       if(a3 > 0.)                                
1006   {                                              
1007     if(a3>alim)                                  
1008       {                                          
1009         siga=std::sqrt(a3) ;                     
1010         p3 = std::max(0,int(G4RandGauss::shoo    
1011       }                                          
1012     else                                         
1013       p3 = G4Poisson(a3);                        
1014                                                  
1015     lossc = 0.;                                  
1016     if(p3 > 0)                                   
1017       {                                          
1018         na = 0.;                                 
1019         alfa = 1.;                               
1020         if (p3 > nmaxCont2)                      
1021     {                                            
1022       dp3        = G4double(p3);                 
1023       rfac       = dp3/(G4double(nmaxCont2)+d    
1024       namean     = G4double(p3)*rfac;            
1025       sa         = G4double(nmaxCont1)*rfac;     
1026       na         = G4RandGauss::shoot(namean,    
1027       if (na > 0.)                               
1028         {                                        
1029           alfa   = w1*G4double(nmaxCont2+p3)/    
1030           alfa1  = alfa*std::log(alfa)/(alfa-    
1031           ea     = na*ipotFluct*alfa1;           
1032           sea    = ipotFluct*std::sqrt(na*(al    
1033           lossc += G4RandGauss::shoot(ea,sea)    
1034         }                                        
1035     }                                            
1036                                                  
1037         nb = G4int(G4double(p3)-na);             
1038         if (nb > 0)                              
1039     {                                            
1040       w2 = alfa*ipotFluct;                       
1041       w  = (Tm-w2)/Tm;                           
1042       for (G4int k=0; k<nb; k++) lossc += w2/    
1043     }                                            
1044       }                                          
1045                                                  
1046     loss += lossc;                               
1047   }                                              
1048     }                                            
1049                                                  
1050   return loss ;                                  
1051 }                                                
1052                                                  
1053 //                                               
1054                                                  
1055