Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/electromagnetic/standard/src/G4PairProductionRelModel.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/G4PairProductionRelModel.cc (Version 11.3.0) and /processes/electromagnetic/standard/src/G4PairProductionRelModel.cc (Version 10.4.p1)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
                                                   >>  26 // $Id: G4PairProductionRelModel.cc 108504 2018-02-15 15:46:37Z gcosmo $
 26 //                                                 27 //
 27 // -------------------------------------------     28 // -------------------------------------------------------------------
 28 //                                                 29 //
 29 // GEANT4 Class file                               30 // GEANT4 Class file
 30 //                                                 31 //
 31 //                                                 32 //
 32 // File name:     G4PairProductionRelModel         33 // File name:     G4PairProductionRelModel
 33 //                                                 34 //
 34 // Author:        Andreas Schaelicke               35 // Author:        Andreas Schaelicke
 35 //                                                 36 //
 36 // Creation date: 02.04.2009                       37 // Creation date: 02.04.2009
 37 //                                                 38 //
 38 // Modifications:                                  39 // Modifications:
 39 // 20.03.17 Change LPMconstant such that it gi <<  40 //
 40 //          that consistent to Migdal's one; f <<  41 // 20.03.17    change LPMconstant such that it gives suppression variable 's'
 41 //          computation; suppression is consis <<  42 //             that consistent to Migdal's one; fix a small bug in 'logTS1'
 42 //          brem. model (F.Hariri)             <<  43 //             computation; suppression is consistent now with the one in the
 43 // 28-05-18 New version with improved screenin <<  44 //             brem. model (F.Hariri)
 44 //          LPM function approximation, effici << 
 45 //          Corrected call to selecting target << 
 46 //          (M. Novak)                         << 
 47 //                                                 45 //
 48 // Class Description:                              46 // Class Description:
 49 //                                                 47 //
 50 // Main References:                                48 // Main References:
 51 //  J.W.Motz et.al., Rev. Mod. Phys. 41 (1969)     49 //  J.W.Motz et.al., Rev. Mod. Phys. 41 (1969) 581.
 52 //  S.Klein,  Rev. Mod. Phys. 71 (1999) 1501.      50 //  S.Klein,  Rev. Mod. Phys. 71 (1999) 1501.
 53 //  T.Stanev et.al., Phys. Rev. D25 (1982) 129     51 //  T.Stanev et.al., Phys. Rev. D25 (1982) 1291.
 54 //  M.L.Ter-Mikaelian, High-energy Electromagn     52 //  M.L.Ter-Mikaelian, High-energy Electromagnetic Processes in Condensed Media,
 55 //                     Wiley, 1972.                53 //                     Wiley, 1972.
 56 //                                                 54 //
 57 // -------------------------------------------     55 // -------------------------------------------------------------------
                                                   >>  56 //
                                                   >>  57 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
                                                   >>  58 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 58                                                    59 
 59 #include "G4PairProductionRelModel.hh"             60 #include "G4PairProductionRelModel.hh"
 60 #include "G4PhysicalConstants.hh"                  61 #include "G4PhysicalConstants.hh"
 61 #include "G4SystemOfUnits.hh"                      62 #include "G4SystemOfUnits.hh"
 62 #include "G4Gamma.hh"                              63 #include "G4Gamma.hh"
 63 #include "G4Electron.hh"                           64 #include "G4Electron.hh"
 64 #include "G4Positron.hh"                           65 #include "G4Positron.hh"
 65 #include "G4ParticleChangeForGamma.hh"             66 #include "G4ParticleChangeForGamma.hh"
 66 #include "G4LossTableManager.hh"                   67 #include "G4LossTableManager.hh"
 67 #include "G4ModifiedTsai.hh"                   << 
 68 #include "G4Exp.hh"                            << 
 69 #include "G4Pow.hh"                            << 
 70 #include "G4AutoLock.hh"                       << 
 71                                                << 
 72 const G4int G4PairProductionRelModel::gMaxZet  << 
 73                                                << 
 74 // LPM constant: \alpha(mc^2)^2/(4\pi*\hbar c) << 
 75 const G4double G4PairProductionRelModel::gLPMc << 
 76   CLHEP::fine_structure_const*CLHEP::electron_ << 
 77   /(4.*CLHEP::pi*CLHEP::hbarc);                << 
 78                                                << 
 79 // abscissas and weights of an 8 point Gauss-L << 
 80 // for numerical integration on [0,1]          << 
 81 const G4double G4PairProductionRelModel::gXGL[ << 
 82   1.98550718e-02, 1.01666761e-01, 2.37233795e- << 
 83   5.91717321e-01, 7.62766205e-01, 8.98333239e- << 
 84 };                                             << 
 85 const G4double G4PairProductionRelModel::gWGL[ << 
 86   5.06142681e-02, 1.11190517e-01, 1.56853323e- << 
 87   1.81341892e-01, 1.56853323e-01, 1.11190517e- << 
 88 };                                             << 
 89                                                << 
 90 // elastic and inelatic radiation logarithms f << 
 91 // Thomas-Fermi model doesn't work): computed  << 
 92 const G4double G4PairProductionRelModel::gFelL << 
 93   0.0, 5.3104, 4.7935, 4.7402, 4.7112, 4.6694, << 
 94 };                                             << 
 95 const G4double G4PairProductionRelModel::gFine << 
 96   0.0, 5.9173, 5.6125, 5.5377, 5.4728, 5.4174, << 
 97 };                                             << 
 98                                                << 
 99 // constant cross section factor               << 
100 const G4double G4PairProductionRelModel::gXSec << 
101   4.*CLHEP::fine_structure_const*CLHEP::classi << 
102   *CLHEP::classic_electr_radius;               << 
103                                                << 
104 // gamma energy limit above which LPM suppress << 
105 // fIsUseLPMCorrection flag is true)           << 
106 const G4double G4PairProductionRelModel::gEgLP << 
107                                                    68 
108 // special data structure per element i.e. per <<  69 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
109 std::vector<G4PairProductionRelModel::ElementD << 
110                                                    70 
111 // LPM supression functions evaluated at initi <<  71 using namespace std;
112 G4PairProductionRelModel::LPMFuncs G4PairProdu << 
113                                                    72 
114 namespace                                      <<  73 const G4double G4PairProductionRelModel::facFel = G4Log(184.15);
115 {                                              <<  74 const G4double G4PairProductionRelModel::facFinel = G4Log(1194.); // 1440.
116   G4Mutex thePairProdRelMutex = G4MUTEX_INITIA <<  75 
117 }                                              <<  76 const G4double G4PairProductionRelModel::preS1 = 1./(184.15*184.15);
                                                   >>  77 const G4double G4PairProductionRelModel::logTwo = G4Log(2.);
                                                   >>  78 
                                                   >>  79 const G4double G4PairProductionRelModel::xgi[]={ 0.0199, 0.1017, 0.2372, 0.4083,
                                                   >>  80              0.5917, 0.7628, 0.8983, 0.9801 };
                                                   >>  81 const G4double G4PairProductionRelModel::wgi[]={ 0.0506, 0.1112, 0.1569, 0.1813,
                                                   >>  82              0.1813, 0.1569, 0.1112, 0.0506 };
                                                   >>  83 const G4double G4PairProductionRelModel::Fel_light[]  = {0., 5.31  , 4.79  , 4.74 ,  4.71};
                                                   >>  84 const G4double G4PairProductionRelModel::Finel_light[] = {0., 6.144 , 5.621 , 5.805 , 5.924};
                                                   >>  85 
                                                   >>  86 const G4double G4PairProductionRelModel::xsfactor =
                                                   >>  87   4*CLHEP::fine_structure_const*CLHEP::classic_electr_radius*CLHEP::classic_electr_radius;
                                                   >>  88 const G4double G4PairProductionRelModel::Egsmall = 2.*CLHEP::MeV;
                                                   >>  89 const G4double G4PairProductionRelModel::Eghigh = 100.*CLHEP::GeV;
118                                                    90 
119 // CTR                                         << 
120 G4PairProductionRelModel::G4PairProductionRelM     91 G4PairProductionRelModel::G4PairProductionRelModel(const G4ParticleDefinition*,
121                                                <<  92                const G4String& nam)
122   : G4VEmModel(nam), fIsUseLPMCorrection(true) <<  93   : G4VEmModel(nam),
123   fLPMEnergy(0.), fG4Calc(G4Pow::GetInstance() <<  94     fLPMconstant(CLHEP::fine_structure_const*CLHEP::electron_mass_c2*CLHEP::electron_mass_c2/
124   fTheElectron(G4Electron::Electron()), fThePo <<  95      (4.*CLHEP::pi*CLHEP::hbarc)),
125   fParticleChange(nullptr)                     <<  96     fLPMflag(true),
                                                   >>  97     lpmEnergy(0.),
                                                   >>  98     use_completescreening(false)
126 {                                                  99 {
127   // gamma energy below which the parametrized << 100   fParticleChange = nullptr;
128   fParametrizedXSectionThreshold = 30.0*CLHEP: << 101   theGamma    = G4Gamma::Gamma();
129   // gamma energy below the Coulomb correction << 102   thePositron = G4Positron::Positron();
130   fCoulombCorrectionThreshold    = 50.0*CLHEP: << 103   theElectron = G4Electron::Electron();
131   // set angular generator used in the final s << 104 
132   SetAngularDistribution(new G4ModifiedTsai()) << 105   g4calc = G4Pow::GetInstance();
                                                   >> 106 
                                                   >> 107   currentZ = z13 = z23 = lnZ = Fel = Finel = fCoulomb = phiLPM = gLPM = xiLPM = 0;
133 }                                                 108 }
134                                                   109 
135 // DTR                                         << 110 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
                                                   >> 111 
136 G4PairProductionRelModel::~G4PairProductionRel    112 G4PairProductionRelModel::~G4PairProductionRelModel()
137 {                                              << 113 {}
138   if (isFirstInstance) {                       << 114 
139     // clear ElementData container             << 115 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
140     for (auto const & ptr : gElementData) { de << 
141     gElementData.clear();                      << 
142     // clear LPMFunctions (if any)             << 
143     if (fIsUseLPMCorrection) {                 << 
144       gLPMFuncs.fLPMFuncG.clear();             << 
145       gLPMFuncs.fLPMFuncPhi.clear();           << 
146       gLPMFuncs.fIsInitialized = false;        << 
147     }                                          << 
148   }                                            << 
149 }                                              << 
150                                                   116 
151 void G4PairProductionRelModel::Initialise(cons    117 void G4PairProductionRelModel::Initialise(const G4ParticleDefinition* p,
152                                           cons << 118             const G4DataVector& cuts)
153 {                                                 119 {
154   if(nullptr == fParticleChange) { fParticleCh << 120   if(!fParticleChange) { fParticleChange = GetParticleChangeForGamma(); }
155                                                << 121   if(IsMaster() && LowEnergyLimit() < HighEnergyLimit()) {
156   if (isFirstInstance || gElementData.empty()) << 
157     // init element data and LPM funcs         << 
158     G4AutoLock l(&thePairProdRelMutex);        << 
159     if (gElementData.empty()) {                << 
160       isFirstInstance = true;                  << 
161       gElementData.resize(gMaxZet+1, nullptr); << 
162     }                                          << 
163     // static data should be initialised only  << 
164     InitialiseElementData();                   << 
165     if (fIsUseLPMCorrection) {                 << 
166       InitLPMFunctions();                      << 
167     }                                          << 
168     l.unlock();                                << 
169   }                                            << 
170   // element selectors should be initialised i << 
171   if (IsMaster()) {                            << 
172     InitialiseElementSelectors(p, cuts);          122     InitialiseElementSelectors(p, cuts);
173   }                                               123   }
174 }                                                 124 }
175                                                   125 
                                                   >> 126 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
                                                   >> 127 
176 void G4PairProductionRelModel::InitialiseLocal    128 void G4PairProductionRelModel::InitialiseLocal(const G4ParticleDefinition*,
177                                                << 129                  G4VEmModel* masterModel)
178 {                                                 130 {
179   SetElementSelectors(masterModel->GetElementS << 131   if(LowEnergyLimit() < HighEnergyLimit()) {
                                                   >> 132     SetElementSelectors(masterModel->GetElementSelectors());
                                                   >> 133   }
180 }                                                 134 }
181                                                   135 
182 G4double G4PairProductionRelModel::ComputeXSec << 136 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
183                                                << 137 
                                                   >> 138 G4double G4PairProductionRelModel::ComputeXSectionPerAtom(G4double totalEnergy, G4double Z)
184 {                                                 139 {
185   G4double xSection = 0.0;                     << 140   G4double cross = 0.0;
186   // check if LPM suppression needs to be used << 141 
187   const G4bool   isLPM  = (fIsUseLPMCorrection << 142   // number of intervals and integration step
188   // determine the kinematical limits (taken i << 143   G4double vcut = electron_mass_c2/totalEnergy ;
189   // the way in which the Coulomb correction i << 144 
190   const G4int    iz     = std::min(gMaxZet, G4 << 145   // limits by the screening variable
191   const G4double eps0   = CLHEP::electron_mass << 146   G4double dmax = DeltaMax();
192   // Coulomb correction is always included in  << 147   G4double dmin = std::min(DeltaMin(totalEnergy),dmax);
193   // that this DCS is only used to get the int << 148   G4double vcut1 = 0.5 - 0.5*sqrt(1. - dmin/dmax);
194   const G4double dmax   = gElementData[iz]->fD << 149   vcut = max(vcut, vcut1);
195   const G4double dmin   = 4.*eps0*gElementData << 150 
196   const G4double eps1   = 0.5 - 0.5*std::sqrt( << 151   G4double vmax = 0.5;
197   const G4double epsMin = std::max(eps0, eps1) << 152   G4int n = 1;  // needs optimisation
198   const G4double epsMax = 0.5; // DCS is symme << 153 
199   // let Et be the total energy transferred to << 154   G4double delta = (vmax - vcut)*totalEnergy/G4double(n);
200   // the [Et-min, Et-max] interval will be div << 155 
201   // with width of dInterv = (Et-max - Et-min) << 156   G4double e0 = vcut*totalEnergy;
202   // be done in each sub-inteval using the xi  << 157 
203   // that is in [0,1]. The 8-point GL q. is us << 158   // simple integration
204   const G4int    numSub = 2;                   << 159   for(G4int l=0; l<n; ++l) {
205   const G4double dInterv= (epsMax - epsMin)*ga << 160     e0 += delta;
206   G4double minEti       = epsMin*gammaEnergy;  << 161     for(G4int i=0; i<8; ++i) {
207   for (G4int i = 0; i < numSub; ++i) {         << 162 
208     for (G4int ngl = 0; ngl < 8; ++ngl) {      << 163       G4double eg = (e0 + xgi[i]*delta);
209       const G4double Et = (minEti + gXGL[ngl]* << 164       G4double xs = (fLPMflag && totalEnergy > Eghigh)
210       const G4double xs = isLPM ? ComputeRelDX << 165   ? ComputeRelDXSectionPerAtom(eg,totalEnergy,Z)
211                                 : ComputeDXSec << 166   : ComputeDXSectionPerAtom(eg,totalEnergy,Z);
212       xSection += gWGL[ngl]*xs;                << 167       cross += wgi[i]*xs;
213     }                                             168     }
214     // update minimum Et of the sub-inteval    << 
215     minEti += dInterv;                         << 
216   }                                               169   }
217   // apply corrections of variable transformat << 170 
218   xSection = std::max(2.*xSection*dInterv, 0.) << 171   cross *= delta*2.;
219   return xSection;                             << 172   return cross;
220 }                                                 173 }
221                                                   174 
222 // DCS WITHOUT LPM SUPPRESSION                 << 175 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
223 // Computes DCS value for a given target eleme << 176 
224 // total energy transferred to one of the e-/e << 177 G4double
225 // The constant factor 4 \alpha r_0^2 Z (Z +\e << 178 G4PairProductionRelModel::ComputeDXSectionPerAtom(G4double eplusEnergy,
226 // the returned value will be differential in  << 179               G4double totalEnergy,
227 // the eps=Et/Eg. The computed part of the DCS << 180               G4double /*Z*/)
228 // NORMAL CASE: DEFAULT STTING (i.e. fIsUseCom << 181 {
229 // ds/deps(Et,Eg,Z) = ds/deps(eps,Z) = (eps^2+ << 182   // most simple case - complete screening:
230 // + 2*eps(1-eps)*[phi2(d)/4-ln(Z)/3-fc]/3 whe << 183 
231 // screening variable d=d(eps)=136Z^(-1/3)eps0 << 184   //  dsig/dE+ = 4 * alpha * Z**2 * r0**2 / k
232 // COMPLETE SCREENING (when d(eps) approx-equa << 185   //     * [ (y**2 + (1-y**2) + 2/3*y*(1-y) ) * ( log (183 * Z**-1/3)  + 1/9 * y*(1-y) ]
233 // ds/deps(Et,Eg,Z) = ds/deps(eps,Z) = (eps^2+ << 186   // y = E+/k
234 // -eps(1-eps)/9 where Lel=phi1(0)/4-ln(Z)/3 i << 187   G4double yp=eplusEnergy/totalEnergy;
235 // logarithm, fc is the Coulomb correction and << 188   G4double ym=1.-yp;
236 // phi1(0)/4-1/6-ln(Z)/3 = Lel-1/6 (due to phi << 189 
237 G4double G4PairProductionRelModel::ComputeDXSe << 190   G4double cross = 0.;
238                                                << 191   if (use_completescreening)
239                                                << 192     cross = (yp*yp + ym*ym + 2./3.*ym*yp)*(Fel - fCoulomb) + yp*ym/9.;
                                                   >> 193   else {
                                                   >> 194     G4double delta = 0.25*DeltaMin(totalEnergy)/(yp*ym);
                                                   >> 195     cross = (yp*yp + ym*ym)*(0.25*Phi1(delta) - lnZ/3. - fCoulomb)
                                                   >> 196       + 2./3.*ym*yp*(0.25*Phi2(delta) - lnZ/3. - fCoulomb);
                                                   >> 197   }
                                                   >> 198   return cross/totalEnergy;
                                                   >> 199 }
                                                   >> 200 
                                                   >> 201 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
                                                   >> 202 
                                                   >> 203 G4double
                                                   >> 204 G4PairProductionRelModel::ComputeRelDXSectionPerAtom(G4double eplusEnergy,
                                                   >> 205                  G4double totalEnergy,
                                                   >> 206                  G4double /*Z*/)
240 {                                                 207 {
241   G4double xSection = 0.;                      << 208   // most simple case - complete screening:
242   const G4int    iz   = std::min(gMaxZet, G4lr << 209 
243   const G4double eps  = pEnergy/gammaEnergy;   << 210   //  dsig/dE+ = 4 * alpha * Z**2 * r0**2 / k
244   const G4double epsm = 1.-eps;                << 211   //     * [ (y**2 + (1-y**2) + 2/3*y*(1-y) ) * ( log (183 * Z**-1/3)  + 1/9 * y*(1-y) ]
245   const G4double dum  = eps*epsm;              << 212   // y = E+/k
246   if (fIsUseCompleteScreening) {               << 213   G4double yp=eplusEnergy/totalEnergy;
247     // complete screening:                     << 214   G4double ym=1.-yp;
248     const G4double Lel   = gElementData[iz]->f << 215 
249     const G4double fc    = gElementData[iz]->f << 216   CalcLPMFunctions(totalEnergy,eplusEnergy); // gamma
250     xSection = (eps*eps + epsm*epsm + 2.*dum/3 << 217 
251   } else {                                     << 218   G4double cross = 0.;
252     // normal case:                            << 219   if (use_completescreening)
253     const G4double eps0  = CLHEP::electron_mas << 220     cross = xiLPM*(2./3.*phiLPM*(yp*yp + ym*ym) + gLPM)*(Fel - fCoulomb);
254     const G4double fc    = gElementData[iz]->f << 221   else {
255     const G4double lnZ13 = gElementData[iz]->f << 222     G4double delta = 0.25*DeltaMin(totalEnergy)/(yp*ym);
256     const G4double delta = gElementData[iz]->f << 223     cross = (1./3.*gLPM + 2./3.*phiLPM)*(yp*yp + ym*ym)
257     G4double phi1, phi2;                       << 224                              *(0.25*Phi1(delta) - lnZ/3. - fCoulomb)
258     ComputePhi12(delta, phi1, phi2);           << 225            + 2./3.*gLPM*ym*yp*(0.25*Phi2(delta) - lnZ/3. - fCoulomb);
259     xSection =  (eps*eps + epsm*epsm)*(0.25*ph << 226     cross *= xiLPM;
260                + 2.*dum*(0.25*phi2-lnZ13-fc)/3 << 
261   }                                               227   }
262   // non-const. part of the DCS differential i << 228   return cross/totalEnergy;
263   // ds/dEt=ds/deps deps/dEt with deps/dEt=1/E << 229 
264   return std::max(xSection, 0.0)/gammaEnergy;  << 
265 }                                                 230 }
266                                                   231 
267 // DCS WITH POSSIBLE LPM SUPPRESSION           << 232 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
268 // Computes DCS value for a given target eleme << 233 
269 // total energy transferred to one of the e-/e << 234 void
270 // For a given Z, the LPM suppression will dep << 235 G4PairProductionRelModel::CalcLPMFunctions(G4double k, G4double eplusEnergy)
271 // LMP-Energy. This will determine the suppres << 
272 // pression functions xi(s), fi(s) and G(s).   << 
273 // The constant factor 4 \alpha r_0^2 Z (Z +\e << 
274 // the returned value will be differential in  << 
275 // the eps=Et/Eg. The computed part of the DCS << 
276 // NORMAL CASE: DEFAULT STTING (i.e. fIsUseCom << 
277 // ds/deps(Et,Eg,Z)=ds/deps(eps,Z) = xi(s)*{ ( << 
278 // *[phi1(d)/4-ln(Z)/3-fc] + 2*eps(1-eps)*G(s) << 
279 // the universal (in the TF model) screening v << 
280 // /[eps*(1-eps)] with eps0=mc^2/Eg.           << 
281 // COMPLETE SCREENING (when d(eps) approx-equa << 
282 // ds/deps(Et,Eg,Z) = ds/deps(eps,Z) = xi(s)*{ << 
283 // *(1-eps)/3)*2fi(s)/3 + G(s)/3] - eps(1-eps) << 
284 // Note, that when the LPM suppression is abse << 
285 // the normal and the complete screening DCS g << 
286 G4double G4PairProductionRelModel::ComputeRelD << 
287                                                << 
288                                                << 
289 {                                                 236 {
290   G4double xSection = 0.;                      << 237   // *** calculate lpm variable s & sprime ***
291   const G4int    iz   = std::min(gMaxZet, G4lr << 238   // Klein eqs. (78) & (79)
292   const G4double eps  = pEnergy/gammaEnergy;   << 239   G4double sprime = sqrt(0.125*k*lpmEnergy/(eplusEnergy*(k-eplusEnergy)));
293   const G4double epsm = 1.-eps;                << 240 
294   const G4double dum  = eps*epsm;              << 241   G4double s1 = preS1*z23;
295   // evaluate LPM suppression functions        << 242   G4double logS1 = 2./3.*lnZ-2.*facFel;
296   G4double fXiS, fGS, fPhiS;                   << 243   G4double logTS1 = 0.5*logTwo+logS1;
297   ComputeLPMfunctions(fXiS, fGS, fPhiS, eps, g << 244 
298   if (fIsUseCompleteScreening) {               << 245   xiLPM = 2.;
299     // complete screening:                     << 246 
300     const G4double Lel   = gElementData[iz]->f << 247   if (sprime>1)
301     const G4double fc    = gElementData[iz]->f << 248     xiLPM = 1.;
302     xSection = (Lel-fc)*((eps*eps+epsm*epsm)*2 << 249   else if (sprime>sqrt(2.)*s1) {
303   } else {                                     << 250     G4double h  = G4Log(sprime)/logTS1;
304     // normal case:                            << 251     xiLPM = 1+h-0.08*(1-h)*(1-sqr(1-h))/logTS1;
305     const G4double eps0  = CLHEP::electron_mas << 252   }
306     const G4double fc    = gElementData[iz]->f << 253 
307     const G4double lnZ13 = gElementData[iz]->f << 254   G4double s0 = sprime/sqrt(xiLPM);
308     const G4double delta = gElementData[iz]->f << 255   //   G4cout<<"k="<<k<<" y="<<eplusEnergy/k<<G4endl;
309     G4double phi1, phi2;                       << 256   //   G4cout<<"s0="<<s0<<G4endl;
310     ComputePhi12(delta, phi1, phi2);           << 257 
311     xSection =  (eps*eps + epsm*epsm)*(2.*fPhi << 258   // *** calculate supression functions phi and G ***
312                + 2.*dum*fGS*(0.25*phi2-lnZ13-f << 259   // Klein eqs. (77)
                                                   >> 260   G4double s2=s0*s0;
                                                   >> 261   G4double s3=s0*s2;
                                                   >> 262   G4double s4=s2*s2;
                                                   >> 263 
                                                   >> 264   if (s0<0.1) {
                                                   >> 265     // high suppression limit
                                                   >> 266     phiLPM = 6.*s0 - 18.84955592153876*s2 + 39.47841760435743*s3
                                                   >> 267       - 57.69873135166053*s4;
                                                   >> 268     gLPM = 37.69911184307752*s2 - 236.8705056261446*s3 + 807.7822389*s4;
                                                   >> 269   }
                                                   >> 270   else if (s0<1.9516) {
                                                   >> 271     // intermediate suppression
                                                   >> 272     // using eq.77 approxim. valid s0<2.
                                                   >> 273     phiLPM = 1.-G4Exp(-6.*s0*(1.+(3.-pi)*s0)
                                                   >> 274     +s3/(0.623+0.795*s0+0.658*s2));
                                                   >> 275     if (s0<0.415827397755) {
                                                   >> 276       // using eq.77 approxim. valid 0.07<s<2
                                                   >> 277       G4double psiLPM = 1-G4Exp(-4*s0-8*s2/(1+3.936*s0+4.97*s2-0.05*s3+7.50*s4));
                                                   >> 278       gLPM = 3*psiLPM-2*phiLPM;
                                                   >> 279     }
                                                   >> 280     else {
                                                   >> 281       // using alternative parametrisiation
                                                   >> 282       G4double pre = -0.16072300849123999 + s0*3.7550300067531581 + s2*-1.7981383069010097
                                                   >> 283   + s3*0.67282686077812381 + s4*-0.1207722909879257;
                                                   >> 284       gLPM = std::tanh(pre);
                                                   >> 285     }
313   }                                               286   }
314   // non-const. part of the DCS differential i << 287   else {
315   // ds/dEt=ds/deps deps/dEt with deps/dEt=1/E << 288     // low suppression limit valid s>2.
316   return std::max(fXiS*xSection, 0.0)/gammaEne << 289     phiLPM = 1. - 0.0119048/s4;
                                                   >> 290     gLPM = 1. - 0.0230655/s4;
                                                   >> 291   }
                                                   >> 292 
                                                   >> 293   // *** make sure suppression is smaller than 1 ***
                                                   >> 294   // *** caused by Migdal approximation in xi    ***
                                                   >> 295   if (xiLPM*phiLPM>1. || s0>0.57)  { xiLPM=1./phiLPM; }
317 }                                                 296 }
318                                                   297 
                                                   >> 298 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
                                                   >> 299 
319 G4double                                          300 G4double
320 G4PairProductionRelModel::ComputeCrossSectionP    301 G4PairProductionRelModel::ComputeCrossSectionPerAtom(const G4ParticleDefinition*,
321       G4double gammaEnergy, G4double Z, G4doub    302       G4double gammaEnergy, G4double Z, G4double, G4double, G4double)
322 {                                                 303 {
323   G4double crossSection = 0.0 ;                   304   G4double crossSection = 0.0 ;
324   // check kinematical limit                   << 
325   if ( gammaEnergy <= 2.0*electron_mass_c2 ) {    305   if ( gammaEnergy <= 2.0*electron_mass_c2 ) { return crossSection; }
326   // compute the atomic cross section either b << 
327   // or by numerically integrationg the DCS (w << 
328   if ( gammaEnergy < fParametrizedXSectionThre << 
329     // using the parametrized cross sections ( << 
330     crossSection = ComputeParametrizedXSection << 
331   } else {                                     << 
332     // by numerical integration of the DCS:    << 
333     // Computes the cross section with or with << 
334     // settings (by default with if the gamma  << 
335     // and using or not using complete sreenin << 
336     // Only the dependent part is computed in  << 
337     // i.e. the result must be multiplied here << 
338     crossSection = ComputeXSectionPerAtom(gamm << 
339     // apply the constant factors:             << 
340     // - eta(Z) is a correction to account int << 
341     // - gXSecFactor = 4 \alpha r_0^2          << 
342     const G4int iz     = std::min(gMaxZet, G4l << 
343     const G4double eta = gElementData[iz]->fEt << 
344     crossSection      *= gXSecFactor*Z*(Z+eta) << 
345   }                                            << 
346   // final protection                          << 
347   return std::max(crossSection, 0.);           << 
348 }                                              << 
349                                                   306 
350 void G4PairProductionRelModel::SetupForMateria << 307   SetCurrentElement(Z);
351                                                << 308   // choose calculator according to parameters and switches
352 {                                              << 309   // in the moment only one calculator:
353   fLPMEnergy = mat->GetRadlen()*gLPMconstant;  << 310   crossSection=ComputeXSectionPerAtom(gammaEnergy,Z);
                                                   >> 311 
                                                   >> 312   G4double xi = Finel/(Fel - fCoulomb); // inelastic contribution
                                                   >> 313   crossSection *= xsfactor*Z*(Z+xi);
                                                   >> 314 
                                                   >> 315   return crossSection;
354 }                                                 316 }
355                                                   317 
                                                   >> 318 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
                                                   >> 319 
356 void                                              320 void
357 G4PairProductionRelModel::SampleSecondaries(st    321 G4PairProductionRelModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
358                                             co << 322               const G4MaterialCutsCouple* couple,
359                                             co << 323               const G4DynamicParticle* aDynamicGamma,
360                                             G4 << 324               G4double,
361                                             G4 << 325               G4double)
362 // The secondaries e+e- energies are sampled u    326 // The secondaries e+e- energies are sampled using the Bethe - Heitler
363 // cross sections with Coulomb correction.        327 // cross sections with Coulomb correction.
364 // A modified version of the random number tec    328 // A modified version of the random number techniques of Butcher & Messel
365 // is used (Nuc Phys 20(1960),15).                329 // is used (Nuc Phys 20(1960),15).
366 //                                                330 //
367 // GEANT4 internal units.                         331 // GEANT4 internal units.
368 //                                                332 //
369 // Note 1 : Effects due to the breakdown of th    333 // Note 1 : Effects due to the breakdown of the Born approximation at
370 //          low energy are ignored.               334 //          low energy are ignored.
371 // Note 2 : The differential cross section imp    335 // Note 2 : The differential cross section implicitly takes account of
372 //          pair creation in both nuclear and     336 //          pair creation in both nuclear and atomic electron fields.
373 //          However triplet prodution is not g    337 //          However triplet prodution is not generated.
374 {                                                 338 {
375   const G4Material* mat         = couple->GetM << 339   const G4Material* aMaterial = couple->GetMaterial();
376   const G4double    gammaEnergy = aDynamicGamm << 340 
377   const G4double    eps0        = CLHEP::elect << 341   G4double GammaEnergy = aDynamicGamma->GetKineticEnergy();
378   //                                           << 342   G4ParticleMomentum GammaDirection = aDynamicGamma->GetMomentumDirection();
379   // check kinematical limit: gamma energy(Eg) << 343 
380   // (but the model should be used at higher e << 344   G4double epsil ;
381   if (eps0 > 0.5) { return; }                  << 345   G4double epsil0 = electron_mass_c2/GammaEnergy ;
382   //                                           << 346   if(epsil0 > 1.0) { return; }
383   // select target atom of the material        << 347 
384   const G4Element* anElement = SelectTargetAto << 348   SetupForMaterial(theGamma, aMaterial, GammaEnergy);
385                                          aDyna << 349 
                                                   >> 350   // select randomly one element constituing the material
                                                   >> 351   const G4Element* anElement =
                                                   >> 352     SelectRandomAtom(aMaterial, theGamma, GammaEnergy);
                                                   >> 353   SetCurrentElement(anElement->GetZasInt());
                                                   >> 354 
386   CLHEP::HepRandomEngine* rndmEngine = G4Rando    355   CLHEP::HepRandomEngine* rndmEngine = G4Random::getTheEngine();
387   //                                           << 356 
388   // 'eps' is the total energy transferred to  << 357   // do it fast if GammaEnergy < 2. MeV
389   // gamma energy units Eg. Since the correspo << 358   if (GammaEnergy < Egsmall) {
390   // the kinematical limits for eps0=mc^2/Eg < << 359     epsil = epsil0 + (0.5-epsil0)*rndmEngine->flat();
391   // 1. 'eps' is sampled uniformly on the [eps << 360 
392   // 2. otherwise, on the [eps_min, 0.5] inter << 
393   G4double eps;                                << 
394   // case 1.                                   << 
395   static const G4double Egsmall = 2.*CLHEP::Me << 
396   if (gammaEnergy < Egsmall) {                 << 
397     eps = eps0 + (0.5-eps0)*rndmEngine->flat() << 
398   } else {                                        361   } else {
399   // case 2.                                   << 362     // now comes the case with GammaEnergy >= 2. MeV
400     // get the Coulomb factor for the target e << 363     // Extract Coulomb factor for this Element
401     // F(Z) = 8*ln(Z)/3           if Eg <= 50  << 364     G4double FZ = 8.*(anElement->GetIonisation()->GetlogZ3());
402     // F(Z) = 8*ln(Z)/3 + 8*fc(Z) if Eg  > 50  << 365     static const G4double midEnergy = 50.*CLHEP::MeV;
                                                   >> 366     if (GammaEnergy > midEnergy) { FZ += 8.*(anElement->GetfCoulomb()); }
                                                   >> 367 
                                                   >> 368     // limits of the screening variable
                                                   >> 369     G4double screenfac = 136.*epsil0/(anElement->GetIonisation()->GetZ3());
                                                   >> 370     //F.Hariri : correct sign of last term
                                                   >> 371     G4double screenmax = G4Exp ((42.24 - FZ)/8.368) + 0.952 ;
                                                   >> 372     G4double screenmin = std::min(4.*screenfac, screenmax);
                                                   >> 373 
                                                   >> 374     // limits of the energy sampling
                                                   >> 375     G4double epsil1 = 0.5 - 0.5*sqrt(1. - screenmin/screenmax) ;
                                                   >> 376     G4double epsilmin = std::max(epsil0, epsil1); 
                                                   >> 377     G4double epsilrange = 0.5 - epsilmin;
                                                   >> 378 
403     //                                            379     //
404     // The screening variable 'delta(eps)' = 1 << 380     // sample the energy rate of the created electron (or positron)
405     // Due to the Coulomb correction, the DCS  << 
406     // kinematicaly allowed eps > eps0 values. << 
407     // range with negative DCS, the minimum ep << 
408     // max[eps0, epsp] with epsp is the soluti << 
409     // with SF being the screening function (S << 
410     // The solution is epsp = 0.5 - 0.5*sqrt[  << 
411     // with deltap = Exp[(42.038-F(Z))/8.29]-0 << 
412     // - when eps=eps_max = 0.5            =>  << 
413     // - epsp = 0.5 - 0.5*sqrt[ 1 - delta_min/ << 
414     // - and eps_min = max[eps0, epsp]         << 
415     const G4int    iZet        = std::min(gMax << 
416     const G4double deltaFactor = gElementData[ << 
417     const G4double deltaMin    = 4.*deltaFacto << 
418     G4double       deltaMax    = gElementData[ << 
419     G4double       FZ          = 8.*gElementDa << 
420     if ( gammaEnergy > fCoulombCorrectionThres << 
421       FZ      += 8.*gElementData[iZet]->fCoulo << 
422       deltaMax = gElementData[iZet]->fDeltaMax << 
423     }                                          << 
424     // compute the limits of eps               << 
425     const G4double epsp        = 0.5 - 0.5*std << 
426     const G4double epsMin      = std::max(eps0 << 
427     const G4double epsRange    = 0.5 - epsMin; << 
428     //                                            381     //
429     // sample the energy rate (eps) of the cre << 382     //G4double epsil, screenvar, greject ;
430     G4double F10, F20;                         << 383     G4double  screenvar, greject ;
431     ScreenFunction12(deltaMin, F10, F20);      << 384 
432     F10 -= FZ;                                 << 385     G4double F10 = ScreenFunction1(screenmin) - FZ;
433     F20 -= FZ;                                 << 386     G4double F20 = ScreenFunction2(screenmin) - FZ;
434     const G4double NormF1   = std::max(F10 * e << 387     G4double NormF1 = std::max(F10*epsilrange*epsilrange,0.);
435     const G4double NormF2   = std::max(1.5 * F << 388     G4double NormF2 = std::max(1.5*F20,0.);
436     const G4double NormCond = NormF1/(NormF1 + << 389 
437     // check if LPM correction is active       << 
438     const G4bool isLPM = (fIsUseLPMCorrection  << 
439     fLPMEnergy = mat->GetRadlen()*gLPMconstant << 
440     // we will need 3 uniform random number fo << 
441     G4double rndmv[3];                         << 
442     G4double greject = 0.;                     << 
443     do {                                          390     do {
444       rndmEngine->flatArray(3, rndmv);         << 391       if ( NormF1/(NormF1+NormF2) > rndmEngine->flat() ) {
445       if (NormCond > rndmv[0]) {               << 392   epsil = 0.5 - epsilrange*g4calc->A13(rndmEngine->flat());
446         eps = 0.5 - epsRange * fG4Calc->A13(rn << 393   screenvar = screenfac/(epsil*(1-epsil));
447         const G4double delta = deltaFactor/(ep << 394   if (fLPMflag && GammaEnergy > Eghigh) {
448         if (isLPM) {                           << 395     CalcLPMFunctions(GammaEnergy,GammaEnergy*epsil);
449           G4double lpmXiS, lpmGS, lpmPhiS, phi << 396     greject = xiLPM*((gLPM+2.*phiLPM)*Phi1(screenvar) -
450           ComputePhi12(delta, phi1, phi2);     << 397          gLPM*Phi2(screenvar) - phiLPM*FZ)/F10;
451           ComputeLPMfunctions(lpmXiS, lpmGS, l << 398   }
452           greject = lpmXiS*((2.*lpmPhiS+lpmGS) << 399   else {
453         } else {                               << 400     greject = (ScreenFunction1(screenvar) - FZ)/F10;
454           greject = (ScreenFunction1(delta)-FZ << 401   }
455         }                                      << 402 
456       } else {                                    403       } else {
457         eps = epsMin + epsRange*rndmv[1];      << 404   epsil = epsilmin + epsilrange*rndmEngine->flat();
458         const G4double delta = deltaFactor/(ep << 405   screenvar = screenfac/(epsil*(1-epsil));
459         if (isLPM) {                           << 406   if (fLPMflag && GammaEnergy > Eghigh) {
460           G4double lpmXiS, lpmGS, lpmPhiS, phi << 407     CalcLPMFunctions(GammaEnergy,GammaEnergy*epsil);
461           ComputePhi12(delta, phi1, phi2);     << 408     greject = xiLPM*((0.5*gLPM+phiLPM)*Phi1(screenvar) +
462           ComputeLPMfunctions(lpmXiS, lpmGS, l << 409          0.5*gLPM*Phi2(screenvar) - 0.5*(gLPM+phiLPM)*FZ)/F20;
463           greject = lpmXiS*( (lpmPhiS+0.5*lpmG << 410   }
464                              -0.5*(lpmGS+lpmPh << 411   else {
465         } else {                               << 412     greject = (ScreenFunction2(screenvar) - FZ)/F20;
466           greject = (ScreenFunction2(delta)-FZ << 413   }
467         }                                      << 
468       }                                           414       }
                                                   >> 415 
469       // Loop checking, 03-Aug-2015, Vladimir     416       // Loop checking, 03-Aug-2015, Vladimir Ivanchenko
470     } while (greject < rndmv[2]);              << 417     } while( greject < rndmEngine->flat());
471     //  end of eps sampling                    << 418 
472   }                                            << 419   }   //  end of epsil sampling
                                                   >> 420 
                                                   >> 421   //
                                                   >> 422   // fixe charges randomly
473   //                                              423   //
474   // select charges randomly                   << 424 
475   G4double eTotEnergy, pTotEnergy;             << 425   G4double ElectTotEnergy, PositTotEnergy;
476   if (rndmEngine->flat() > 0.5) {                 426   if (rndmEngine->flat() > 0.5) {
477     eTotEnergy = (1.-eps)*gammaEnergy;         << 427     ElectTotEnergy = (1.-epsil)*GammaEnergy;
478     pTotEnergy = eps*gammaEnergy;              << 428     PositTotEnergy = epsil*GammaEnergy;
                                                   >> 429 
479   } else {                                        430   } else {
480     pTotEnergy = (1.-eps)*gammaEnergy;         << 431     PositTotEnergy = (1.-epsil)*GammaEnergy;
481     eTotEnergy = eps*gammaEnergy;              << 432     ElectTotEnergy = epsil*GammaEnergy;
482   }                                               433   }
                                                   >> 434 
483   //                                              435   //
484   // sample pair kinematics                    << 436   // scattered electron (positron) angles. ( Z - axis along the parent photon)
485   //                                           << 
486   const G4double eKinEnergy = std::max(0.,eTot << 
487   const G4double pKinEnergy = std::max(0.,pTot << 
488   //                                              437   //
489   G4ThreeVector eDirection, pDirection;        << 438   //  universal distribution suggested by L. Urban
                                                   >> 439   // (Geant3 manual (1993) Phys211),
                                                   >> 440   //  derived from Tsai distribution (Rev Mod Phys 49,421(1977))
                                                   >> 441 
                                                   >> 442   static const G4double a1 = 1.6;
                                                   >> 443   static const G4double a2 = a1/3.;
                                                   >> 444   G4double uu = -G4Log(rndmEngine->flat()*rndmEngine->flat());
                                                   >> 445   G4double u = (0.25 > rndmEngine->flat()) ? uu*a1 : uu*a2;
                                                   >> 446 
                                                   >> 447   G4double thetaEle = u*electron_mass_c2/ElectTotEnergy;
                                                   >> 448   G4double sinte = std::sin(thetaEle);
                                                   >> 449   G4double coste = std::cos(thetaEle);
                                                   >> 450 
                                                   >> 451   G4double thetaPos = u*electron_mass_c2/PositTotEnergy;
                                                   >> 452   G4double sintp = std::sin(thetaPos);
                                                   >> 453   G4double costp = std::cos(thetaPos);
                                                   >> 454 
                                                   >> 455   G4double phi  = twopi * rndmEngine->flat();
                                                   >> 456   G4double sinp = std::sin(phi);
                                                   >> 457   G4double cosp = std::cos(phi);
                                                   >> 458 
490   //                                              459   //
491   GetAngularDistribution()->SamplePairDirectio << 460   // kinematic of the created pair
492              eKinEnergy, pKinEnergy, eDirectio << 461   //
                                                   >> 462   // the electron and positron are assumed to have a symetric
                                                   >> 463   // angular distribution with respect to the Z axis along the parent photon.
                                                   >> 464 
                                                   >> 465   G4double ElectKineEnergy = max(0.,ElectTotEnergy - electron_mass_c2);
                                                   >> 466 
                                                   >> 467   G4ThreeVector ElectDirection (sinte*cosp, sinte*sinp, coste);
                                                   >> 468   ElectDirection.rotateUz(GammaDirection);
                                                   >> 469 
493   // create G4DynamicParticle object for the p    470   // create G4DynamicParticle object for the particle1
494   auto aParticle1 = new G4DynamicParticle(fThe << 471   G4DynamicParticle* aParticle1= new G4DynamicParticle(
                                                   >> 472          theElectron,ElectDirection,ElectKineEnergy);
                                                   >> 473 
                                                   >> 474   // the e+ is always created (even with Ekine=0) for further annihilation.
                                                   >> 475 
                                                   >> 476   G4double PositKineEnergy = std::max(0.,PositTotEnergy - electron_mass_c2);
                                                   >> 477 
                                                   >> 478   G4ThreeVector PositDirection (-sintp*cosp, -sintp*sinp, costp);
                                                   >> 479   PositDirection.rotateUz(GammaDirection);
495                                                   480 
496   // create G4DynamicParticle object for the p    481   // create G4DynamicParticle object for the particle2
497   auto aParticle2 = new G4DynamicParticle(fThe << 482   G4DynamicParticle* aParticle2= new G4DynamicParticle(
                                                   >> 483                       thePositron,PositDirection,PositKineEnergy);
                                                   >> 484 
498   // Fill output vector                           485   // Fill output vector
499   fvect->push_back(aParticle1);                   486   fvect->push_back(aParticle1);
500   fvect->push_back(aParticle2);                   487   fvect->push_back(aParticle2);
                                                   >> 488 
501   // kill incident photon                         489   // kill incident photon
502   fParticleChange->SetProposedKineticEnergy(0.    490   fParticleChange->SetProposedKineticEnergy(0.);
503   fParticleChange->ProposeTrackStatus(fStopAnd    491   fParticleChange->ProposeTrackStatus(fStopAndKill);
504 }                                                 492 }
505                                                   493 
506 // should be called only by the master and at  << 494 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
507 void G4PairProductionRelModel::InitialiseEleme << 
508 {                                              << 
509   // create for all elements that are in the d << 
510   auto elemTable = G4Element::GetElementTable( << 
511   for (auto const & elem : *elemTable) {       << 
512     const G4int iz = std::min(gMaxZet, elem->G << 
513     if (nullptr == gElementData[iz]) { // crea << 
514       const G4double logZ13 = elem->GetIonisat << 
515       const G4double Z13    = elem->GetIonisat << 
516       const G4double fc     = elem->GetfCoulom << 
517       const G4double FZLow  = 8.*logZ13;       << 
518       const G4double FZHigh = 8.*(logZ13 + fc) << 
519       G4double       Fel;                      << 
520       G4double       Finel;                    << 
521       if (iz<5) {  // use data from Dirac-Fock << 
522         Fel   = gFelLowZet[iz];                << 
523         Finel = gFinelLowZet[iz];              << 
524       } else {     // use the results of the T << 
525         Fel   = G4Log(184.)  -    logZ13;      << 
526         Finel = G4Log(1194.) - 2.*logZ13;      << 
527       }                                        << 
528       auto elD             = new ElementData() << 
529       elD->fLogZ13         = logZ13;           << 
530       elD->fCoulomb        = fc;               << 
531       elD->fLradEl         = Fel;              << 
532       elD->fDeltaFactor    = 136./Z13;         << 
533       elD->fDeltaMaxLow    = G4Exp((42.038 - F << 
534       elD->fDeltaMaxHigh   = G4Exp((42.038 - F << 
535       elD->fEtaValue       = Finel/(Fel-fc);   << 
536       elD->fLPMVarS1Cond   = std::sqrt(2.)*Z13 << 
537       elD->fLPMILVarS1Cond = 1./G4Log(elD->fLP << 
538       gElementData[iz]   = elD;                << 
539     }                                          << 
540   }                                            << 
541 }                                              << 
542                                                << 
543 // s goes up to 2 with ds = 0.01 be default    << 
544 void G4PairProductionRelModel::InitLPMFunction << 
545   if (!gLPMFuncs.fIsInitialized) {             << 
546     const G4int num = gLPMFuncs.fSLimit*gLPMFu << 
547     gLPMFuncs.fLPMFuncG.resize(num);           << 
548     gLPMFuncs.fLPMFuncPhi.resize(num);         << 
549     for (G4int i=0; i<num; ++i) {              << 
550       const G4double sval = i/gLPMFuncs.fISDel << 
551       ComputeLPMGsPhis(gLPMFuncs.fLPMFuncG[i], << 
552     }                                          << 
553     gLPMFuncs.fIsInitialized = true;           << 
554   }                                            << 
555 }                                              << 
556                                                   495 
557 // used only at initialisation time            << 
558 void G4PairProductionRelModel::ComputeLPMGsPhi << 
559   if (varShat < 0.01) {                        << 
560     funcPhiS = 6.0*varShat*(1.0-CLHEP::pi*varS << 
561     funcGS   = 12.0*varShat-2.0*funcPhiS;      << 
562   } else {                                     << 
563     const G4double varShat2 = varShat*varShat; << 
564     const G4double varShat3 = varShat*varShat2 << 
565     const G4double varShat4 = varShat2*varShat << 
566     if (varShat < 0.415827397755) { // Stanev  << 
567       funcPhiS = 1.0-G4Exp( -6.0*varShat*(1.0+ << 
568                            + varShat3/(0.623+0 << 
569       // 1-\exp \left\{-4s-\frac{8s^2}{1+3.936 << 
570       const G4double funcPsiS = 1.0-G4Exp( -4. << 
571                      + 3.936*varShat+4.97*varS << 
572       // G(s) = 3 \psi(s) - 2 \phi(s)          << 
573       funcGS = 3.0*funcPsiS - 2.0*funcPhiS;    << 
574     } else if (varShat < 1.55) {               << 
575       funcPhiS = 1.0-G4Exp( -6.0*varShat*(1.0+ << 
576                            + varShat3/(0.623+0 << 
577       const G4double dum0  = -0.16072300849123 << 
578                              -1.79813830690100 << 
579                              +0.67282686077812 << 
580                              -0.12077229098792 << 
581       funcGS = std::tanh(dum0);                << 
582     } else {                                   << 
583       funcPhiS = 1.0-0.01190476/varShat4;      << 
584       if (varShat < 1.9156) {                  << 
585         const G4double dum0 = -0.1607230084912 << 
586                               -1.7981383069010 << 
587                               +0.6728268607781 << 
588                               -0.1207722909879 << 
589         funcGS = std::tanh(dum0);              << 
590       } else {                                 << 
591         funcGS   = 1.0-0.0230655/varShat4;     << 
592       }                                        << 
593     }                                          << 
594   }                                            << 
595 }                                              << 
596                                                   496 
597 // used at run-time to get some pre-computed L << 497 void G4PairProductionRelModel::SetupForMaterial(const G4ParticleDefinition*,
598 void G4PairProductionRelModel::GetLPMFunctions << 498             const G4Material* mat, G4double)
599                                                << 
600                                                << 
601   if (sval < gLPMFuncs.fSLimit) {              << 
602     G4double     val = sval*gLPMFuncs.fISDelta << 
603     const G4int ilow = (G4int)val;             << 
604     val    -= ilow;                            << 
605     lpmGs   =  (gLPMFuncs.fLPMFuncG[ilow+1]-gL << 
606              + gLPMFuncs.fLPMFuncG[ilow];      << 
607     lpmPhis =  (gLPMFuncs.fLPMFuncPhi[ilow+1]- << 
608              + gLPMFuncs.fLPMFuncPhi[ilow];    << 
609   } else {                                     << 
610     G4double ss = sval*sval;                   << 
611     ss *= ss;                                  << 
612     lpmPhis = 1.0-0.01190476/ss;               << 
613     lpmGs   = 1.0-0.0230655/ss;                << 
614   }                                            << 
615 }                                              << 
616                                                << 
617 void G4PairProductionRelModel::ComputeLPMfunct << 
618                  G4double &funcGS, G4double &f << 
619                  const G4double egamma, const  << 
620 {                                              << 
621   //  1. y = E_+/E_{\gamma} with E_+ being the << 
622   //                        to one of the e-/e << 
623   //  s' = \sqrt{ \frac{1}{8} \frac{1}{y(1-y)} << 
624   const G4double varSprime = std::sqrt(0.125*f << 
625   const G4double condition = gElementData[izet << 
626   funcXiS = 2.0;                               << 
627   if (varSprime > 1.0) {                       << 
628     funcXiS = 1.0;                             << 
629   } else if (varSprime > condition) {          << 
630     const G4double dum = gElementData[izet]->f << 
631     const G4double funcHSprime = G4Log(varSpri << 
632     funcXiS =  1.0 + funcHSprime               << 
633              - 0.08*(1.0-funcHSprime)*funcHSpr << 
634   }                                            << 
635   //  2. s=\frac{s'}{\sqrt{\xi(s')}}           << 
636   const G4double varShat = varSprime / std::sq << 
637   GetLPMFunctions(funcGS, funcPhiS, varShat);  << 
638   // MAKE SURE SUPPRESSION IS SMALLER THAN 1:  << 
639   if (funcXiS * funcPhiS > 1. || varShat > 0.5 << 
640     funcXiS = 1. / funcPhiS;                   << 
641   }                                            << 
642 }                                              << 
643                                                << 
644 // Calculates the microscopic cross section in << 
645 // G4BetheHeitlerModel and should be used belo << 
646 // from the cross section data above 80-90 GeV << 
647 // Parametrized formula (L. Urban) is used to  << 
648 // given numerically in the table of [Hubbell, << 
649 // Overbo: "Pair, Triplet, and Total Atomic Cr << 
650 // Coefficients) for 1 MeV‐100 GeV Photons i << 
651 // physical and chemical reference data 9.4 (1 << 
652 //                                             << 
653 // The formula gives a good approximation of t << 
654 // below 1.5 MeV: sigma=sigma(1.5MeV)*(GammaEn << 
655 //                                   *(GammaEn << 
656 G4double                                       << 
657 G4PairProductionRelModel::ComputeParametrizedX << 
658                                                << 
659 {                                                 499 {
660   G4double xSection = 0.0 ;                    << 500   lpmEnergy = mat->GetRadlen()*fLPMconstant;
661   // short versions                            << 501   //  G4cout<<" lpmEnergy="<<lpmEnergy<<G4endl;
662   static const G4double kMC2  = CLHEP::electro << 
663   // zero cross section below the kinematical  << 
664   if (Z < 0.9 || gammaE <= 2.0*kMC2) { return  << 
665   //                                           << 
666   static const G4double gammaEnergyLimit = 1.5 << 
667   // set coefficients a, b c                   << 
668   static const G4double a0 =  8.7842e+2*CLHEP: << 
669   static const G4double a1 = -1.9625e+3*CLHEP: << 
670   static const G4double a2 =  1.2949e+3*CLHEP: << 
671   static const G4double a3 = -2.0028e+2*CLHEP: << 
672   static const G4double a4 =  1.2575e+1*CLHEP: << 
673   static const G4double a5 = -2.8333e-1*CLHEP: << 
674                                                << 
675   static const G4double b0 = -1.0342e+1*CLHEP: << 
676   static const G4double b1 =  1.7692e+1*CLHEP: << 
677   static const G4double b2 = -8.2381   *CLHEP: << 
678   static const G4double b3 =  1.3063   *CLHEP: << 
679   static const G4double b4 = -9.0815e-2*CLHEP: << 
680   static const G4double b5 =  2.3586e-3*CLHEP: << 
681                                                << 
682   static const G4double c0 = -4.5263e+2*CLHEP: << 
683   static const G4double c1 =  1.1161e+3*CLHEP: << 
684   static const G4double c2 = -8.6749e+2*CLHEP: << 
685   static const G4double c3 =  2.1773e+2*CLHEP: << 
686   static const G4double c4 = -2.0467e+1*CLHEP: << 
687   static const G4double c5 =  6.5372e-1*CLHEP: << 
688   // check low energy limit of the approximati << 
689   G4double gammaEnergyOrg = gammaE;            << 
690   if (gammaE < gammaEnergyLimit) { gammaE = ga << 
691   // compute gamma energy variables            << 
692   const G4double x  = G4Log(gammaE/kMC2);      << 
693   const G4double x2 = x *x;                    << 
694   const G4double x3 = x2*x;                    << 
695   const G4double x4 = x3*x;                    << 
696   const G4double x5 = x4*x;                    << 
697   //                                           << 
698   const G4double F1 = a0 + a1*x + a2*x2 + a3*x << 
699   const G4double F2 = b0 + b1*x + b2*x2 + b3*x << 
700   const G4double F3 = c0 + c1*x + c2*x2 + c3*x << 
701   // compute the approximated cross section    << 
702   xSection = (Z + 1.)*(F1*Z + F2*Z*Z + F3);    << 
703   // check if we are below the limit of the ap << 
704   if (gammaEnergyOrg < gammaEnergyLimit) {     << 
705     const G4double dum = (gammaEnergyOrg-2.*kM << 
706     xSection *= dum*dum;                       << 
707   }                                            << 
708   return xSection;                             << 
709 }                                                 502 }
710                                                   503 
711                                                << 504 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
712                                                   505