Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/electromagnetic/standard/src/G4BetheHeitlerModel.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /processes/electromagnetic/standard/src/G4BetheHeitlerModel.cc (Version 11.3.0) and /processes/electromagnetic/standard/src/G4BetheHeitlerModel.cc (Version 6.0)


  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 // GEANT4 Class file                              
 30 //                                                
 31 //                                                
 32 // File name:     G4BetheHeitlerModel             
 33 //                                                
 34 // Author:        Vladimir Ivanchenko on base     
 35 //                                                
 36 // Creation date: 15.03.2005                      
 37 //                                                
 38 // Modifications by Vladimir Ivanchenko, Miche    
 39 //                                                
 40 // Class Description:                             
 41 //                                                
 42 // -------------------------------------------    
 43 //                                                
 44                                                   
 45 #include "G4BetheHeitlerModel.hh"                 
 46 #include "G4PhysicalConstants.hh"                 
 47 #include "G4SystemOfUnits.hh"                     
 48 #include "G4Electron.hh"                          
 49 #include "G4Positron.hh"                          
 50 #include "G4Gamma.hh"                             
 51 #include "Randomize.hh"                           
 52 #include "G4ParticleChangeForGamma.hh"            
 53 #include "G4Pow.hh"                               
 54 #include "G4Exp.hh"                               
 55 #include "G4ModifiedTsai.hh"                      
 56 #include "G4EmParameters.hh"                      
 57 #include "G4EmElementXS.hh"                       
 58 #include "G4AutoLock.hh"                          
 59                                                   
 60 const G4int G4BetheHeitlerModel::gMaxZet = 120    
 61 std::vector<G4BetheHeitlerModel::ElementData*>    
 62                                                   
 63 namespace                                         
 64 {                                                 
 65   G4Mutex theBetheHMutex = G4MUTEX_INITIALIZER    
 66 }                                                 
 67                                                   
 68 G4BetheHeitlerModel::G4BetheHeitlerModel(const    
 69                                          const    
 70 : G4VEmModel(nam),                                
 71   fG4Calc(G4Pow::GetInstance()), fTheGamma(G4G    
 72   fTheElectron(G4Electron::Electron()), fThePo    
 73   fParticleChange(nullptr)                        
 74 {                                                 
 75   SetAngularDistribution(new G4ModifiedTsai())    
 76 }                                                 
 77                                                   
 78 G4BetheHeitlerModel::~G4BetheHeitlerModel()       
 79 {                                                 
 80   if (isFirstInstance) {                          
 81     for (auto const & ptr : gElementData) { de    
 82     gElementData.clear();                         
 83   }                                               
 84   delete fXSection;                               
 85 }                                                 
 86                                                   
 87 void G4BetheHeitlerModel::Initialise(const G4P    
 88                                      const G4D    
 89 {                                                 
 90   if (!fParticleChange) { fParticleChange = Ge    
 91                                                   
 92   if (isFirstInstance || gElementData.empty())    
 93     G4AutoLock l(&theBetheHMutex);                
 94     if (gElementData.empty()) {                   
 95       isFirstInstance = true;                     
 96       gElementData.resize(gMaxZet+1, nullptr);    
 97                                                   
 98       // EPICS2017 flag should be checked only    
 99       useEPICS2017 = G4EmParameters::Instance(    
100       if (useEPICS2017) {                         
101   fXSection = new G4EmElementXS(1, 100, "convE    
102       }                                           
103     }                                             
104     // static data should be initialised only     
105     InitialiseElementData();                      
106     l.unlock();                                   
107   }                                               
108   // element selectors should be initialised i    
109   if(IsMaster()) {                                
110     InitialiseElementSelectors(p, cuts);          
111   }                                               
112 }                                                 
113                                                   
114 void G4BetheHeitlerModel::InitialiseLocal(cons    
115                                           G4VE    
116 {                                                 
117   SetElementSelectors(masterModel->GetElementS    
118 }                                                 
119                                                   
120 // Calculates the microscopic cross section in    
121 // A parametrized formula from L. Urban is use    
122 // the total cross section.                       
123 // It gives a good description of the data fro    
124 // below 1.5 MeV: sigma=sigma(1.5MeV)*(GammaEn    
125 //                                   *(GammaEn    
126 G4double                                          
127 G4BetheHeitlerModel::ComputeCrossSectionPerAto    
128                                                   
129                                                   
130 {                                                 
131   G4double xSection = 0.0 ;                       
132   // short versions                               
133   static const G4double kMC2  = CLHEP::electro    
134   // zero cross section below the kinematical     
135   if (Z < 0.9 || gammaEnergy <= 2.0*kMC2) { re    
136                                                   
137   G4int iZ = G4lrint(Z);                          
138   if (useEPICS2017 && iZ < 101) {                 
139     return fXSection->GetXS(iZ, gammaEnergy);     
140   }                                               
141                                                   
142   //                                              
143   static const G4double gammaEnergyLimit = 1.5    
144   // set coefficients a, b c                      
145   static const G4double a0 =  8.7842e+2*CLHEP:    
146   static const G4double a1 = -1.9625e+3*CLHEP:    
147   static const G4double a2 =  1.2949e+3*CLHEP:    
148   static const G4double a3 = -2.0028e+2*CLHEP:    
149   static const G4double a4 =  1.2575e+1*CLHEP:    
150   static const G4double a5 = -2.8333e-1*CLHEP:    
151                                                   
152   static const G4double b0 = -1.0342e+1*CLHEP:    
153   static const G4double b1 =  1.7692e+1*CLHEP:    
154   static const G4double b2 = -8.2381   *CLHEP:    
155   static const G4double b3 =  1.3063   *CLHEP:    
156   static const G4double b4 = -9.0815e-2*CLHEP:    
157   static const G4double b5 =  2.3586e-3*CLHEP:    
158                                                   
159   static const G4double c0 = -4.5263e+2*CLHEP:    
160   static const G4double c1 =  1.1161e+3*CLHEP:    
161   static const G4double c2 = -8.6749e+2*CLHEP:    
162   static const G4double c3 =  2.1773e+2*CLHEP:    
163   static const G4double c4 = -2.0467e+1*CLHEP:    
164   static const G4double c5 =  6.5372e-1*CLHEP:    
165   // check low energy limit of the approximati    
166   G4double gammaEnergyOrg = gammaEnergy;          
167   if (gammaEnergy < gammaEnergyLimit) { gammaE    
168   // compute gamma energy variables               
169   const G4double x  = G4Log(gammaEnergy/kMC2);    
170   const G4double x2 = x *x;                       
171   const G4double x3 = x2*x;                       
172   const G4double x4 = x3*x;                       
173   const G4double x5 = x4*x;                       
174   //                                              
175   const G4double F1 = a0 + a1*x + a2*x2 + a3*x    
176   const G4double F2 = b0 + b1*x + b2*x2 + b3*x    
177   const G4double F3 = c0 + c1*x + c2*x2 + c3*x    
178   // compute the approximated cross section       
179   xSection = (Z + 1.)*(F1*Z + F2*Z*Z + F3);       
180   // check if we are below the limit of the ap    
181   if (gammaEnergyOrg < gammaEnergyLimit) {        
182     const G4double dum = (gammaEnergyOrg-2.*kM    
183     xSection *= dum*dum;                          
184   }                                               
185   // make sure that the cross section is never    
186   xSection = std::max(xSection, 0.);              
187   return xSection;                                
188 }                                                 
189                                                   
190 // The secondaries e+e- energies are sampled u    
191 // cross sections with Coulomb correction.        
192 // A modified version of the random number tec    
193 // is used (Nuc Phys 20(1960),15).                
194 //                                                
195 // GEANT4 internal units.                         
196 //                                                
197 // Note 1 : Effects due to the breakdown of th    
198 //          low energy are ignored.               
199 // Note 2 : The differential cross section imp    
200 //          pair creation in both nuclear and     
201 //          However triplet prodution is not g    
202 void G4BetheHeitlerModel::SampleSecondaries(st    
203                                             co    
204                                             co    
205                                             G4    
206 {                                                 
207   // set some constant values                     
208   const G4double    gammaEnergy = aDynamicGamm    
209   const G4double    eps0        = CLHEP::elect    
210   //                                              
211   // check kinematical limit: gamma energy(Eg)    
212   if (eps0 > 0.5) { return; }                     
213   //                                              
214   // select target element of the material (pr    
215   const G4Element* anElement = SelectTargetAto    
216                                           aDyn    
217                                                   
218   //                                              
219   // get the random engine                        
220   CLHEP::HepRandomEngine* rndmEngine = G4Rando    
221   //                                              
222   // 'eps' is the total energy transferred to     
223   // gamma energy units Eg. Since the correspo    
224   // the kinematical limits for eps0=mc^2/Eg <    
225   // 1. 'eps' is sampled uniformly on the [eps    
226   // 2. otherwise, on the [eps_min, 0.5] inter    
227   G4double eps;                                   
228   // case 1.                                      
229   static const G4double Egsmall = 2.*CLHEP::Me    
230   if (gammaEnergy < Egsmall) {                    
231     eps = eps0 + (0.5-eps0)*rndmEngine->flat()    
232   } else {                                        
233   // case 2.                                      
234     // get the Coulomb factor for the target e    
235     // F(Z) = 8*ln(Z)/3           if Eg <= 50     
236     // F(Z) = 8*ln(Z)/3 + 8*fc(Z) if Eg  > 50     
237     //                                            
238     // The screening variable 'delta(eps)' = 1    
239     // Due to the Coulomb correction, the DCS     
240     // kinematicaly allowed eps > eps0 values.    
241     // range with negative DCS, the minimum ep    
242     // max[eps0, epsp] with epsp is the soluti    
243     // with SF being the screening function (S    
244     // The solution is epsp = 0.5 - 0.5*sqrt[     
245     // with deltap = Exp[(42.038-F(Z))/8.29]-0    
246     // - when eps=eps_max = 0.5            =>     
247     // - epsp = 0.5 - 0.5*sqrt[ 1 - delta_min/    
248     // - and eps_min = max[eps0, epsp]            
249     static const G4double midEnergy = 50.*CLHE    
250     const  G4int           iZet = std::min(gMa    
251     const  G4double deltaFactor = 136.*eps0/an    
252     G4double           deltaMax = gElementData    
253     G4double                 FZ = 8.*anElement    
254     if (gammaEnergy > midEnergy) {                
255       FZ      += 8.*(anElement->GetfCoulomb())    
256       deltaMax = gElementData[iZet]->fDeltaMax    
257     }                                             
258     const G4double deltaMin = 4.*deltaFactor;     
259     //                                            
260     // compute the limits of eps                  
261     const G4double epsp     = 0.5 - 0.5*std::s    
262     const G4double epsMin   = std::max(eps0,ep    
263     const G4double epsRange = 0.5 - epsMin;       
264     //                                            
265     // sample the energy rate (eps) of the cre    
266     G4double F10, F20;                            
267     ScreenFunction12(deltaMin, F10, F20);         
268     F10 -= FZ;                                    
269     F20 -= FZ;                                    
270     const G4double NormF1   = std::max(F10 * e    
271     const G4double NormF2   = std::max(1.5 * F    
272     const G4double NormCond = NormF1/(NormF1 +    
273     // we will need 3 uniform random number fo    
274     G4double rndmv[3];                            
275     G4double greject = 0.;                        
276     do {                                          
277       rndmEngine->flatArray(3, rndmv);            
278       if (NormCond > rndmv[0]) {                  
279         eps = 0.5 - epsRange * fG4Calc->A13(rn    
280         const G4double delta = deltaFactor/(ep    
281         greject = (ScreenFunction1(delta)-FZ)/    
282       } else {                                    
283         eps = epsMin + epsRange*rndmv[1];         
284         const G4double delta = deltaFactor/(ep    
285         greject = (ScreenFunction2(delta)-FZ)/    
286       }                                           
287       // Loop checking, 03-Aug-2015, Vladimir     
288     } while (greject < rndmv[2]);                 
289   } //  end of eps sampling                       
290   //                                              
291   // select charges randomly                      
292   G4double eTotEnergy, pTotEnergy;                
293   if (rndmEngine->flat() > 0.5) {                 
294     eTotEnergy = (1.-eps)*gammaEnergy;            
295     pTotEnergy = eps*gammaEnergy;                 
296   } else {                                        
297     pTotEnergy = (1.-eps)*gammaEnergy;            
298     eTotEnergy = eps*gammaEnergy;                 
299   }                                               
300   //                                              
301   // sample pair kinematics                       
302   const G4double eKinEnergy = std::max(0.,eTot    
303   const G4double pKinEnergy = std::max(0.,pTot    
304   //                                              
305   G4ThreeVector eDirection, pDirection;           
306   //                                              
307   GetAngularDistribution()->SamplePairDirectio    
308                                                   
309                                                   
310   // create G4DynamicParticle object for the p    
311   auto aParticle1= new G4DynamicParticle(fTheE    
312   // create G4DynamicParticle object for the p    
313   auto aParticle2= new G4DynamicParticle(fTheP    
314   // Fill output vector                           
315   fvect->push_back(aParticle1);                   
316   fvect->push_back(aParticle2);                   
317   // kill incident photon                         
318   fParticleChange->SetProposedKineticEnergy(0.    
319   fParticleChange->ProposeTrackStatus(fStopAnd    
320 }                                                 
321                                                   
322 // should be called only by the master and at     
323 void G4BetheHeitlerModel::InitialiseElementDat    
324 {                                                 
325   // create for all elements that are in the d    
326   auto elemTable = G4Element::GetElementTable(    
327   for (auto const & elem : *elemTable) {          
328     const G4int Z = elem->GetZasInt();            
329     const G4int iz = std::min(gMaxZet, Z);        
330     if (nullptr == gElementData[iz]) { // crea    
331       G4double FZLow     = 8.*elem->GetIonisat    
332       G4double FZHigh    = FZLow + 8.*elem->Ge    
333       auto elD           = new ElementData();     
334       elD->fDeltaMaxLow  = G4Exp((42.038 - FZL    
335       elD->fDeltaMaxHigh = G4Exp((42.038 - FZH    
336       gElementData[iz]   = elD;                   
337     }                                             
338     if (useEPICS2017 && Z < 101) {                
339       fXSection->Retrieve(Z);                     
340     }                                             
341   }                                               
342                                                   
343 }                                                 
344                                                   
345