Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/electromagnetic/muons/src/G4MuPairProductionModel.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/muons/src/G4MuPairProductionModel.cc (Version 11.3.0) and /processes/electromagnetic/muons/src/G4MuPairProductionModel.cc (Version 9.6.p3)


  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$
 26 //                                                 27 //
 27 // -------------------------------------------     28 // -------------------------------------------------------------------
 28 //                                                 29 //
 29 // GEANT4 Class file                               30 // GEANT4 Class file
 30 //                                                 31 //
 31 //                                                 32 //
 32 // File name:     G4MuPairProductionModel          33 // File name:     G4MuPairProductionModel
 33 //                                                 34 //
 34 // Author:        Vladimir Ivanchenko on base      35 // Author:        Vladimir Ivanchenko on base of Laszlo Urban code
 35 //                                                 36 //
 36 // Creation date: 24.06.2002                       37 // Creation date: 24.06.2002
 37 //                                                 38 //
 38 // Modifications:                                  39 // Modifications:
 39 //                                                 40 //
 40 // 04-12-02 Change G4DynamicParticle construct     41 // 04-12-02 Change G4DynamicParticle constructor in PostStep (V.Ivanchenko)
 41 // 23-12-02 Change interface in order to move      42 // 23-12-02 Change interface in order to move to cut per region (V.Ivanchenko)
 42 // 24-01-03 Fix for compounds (V.Ivanchenko)       43 // 24-01-03 Fix for compounds (V.Ivanchenko)
 43 // 27-01-03 Make models region aware (V.Ivanch     44 // 27-01-03 Make models region aware (V.Ivanchenko)
 44 // 13-02-03 Add model (V.Ivanchenko)               45 // 13-02-03 Add model (V.Ivanchenko)
 45 // 06-06-03 Fix in cross section calculation f     46 // 06-06-03 Fix in cross section calculation for high energy (V.Ivanchenko)
 46 // 20-10-03 2*xi in ComputeDDMicroscopicCrossS     47 // 20-10-03 2*xi in ComputeDDMicroscopicCrossSection   (R.Kokoulin)
 47 //          8 integration points in ComputeDMi     48 //          8 integration points in ComputeDMicroscopicCrossSection
 48 // 12-01-04 Take min cut of e- and e+ not its      49 // 12-01-04 Take min cut of e- and e+ not its sum (V.Ivanchenko)
 49 // 10-02-04 Update parameterisation using R.Ko     50 // 10-02-04 Update parameterisation using R.Kokoulin model (V.Ivanchenko)
 50 // 28-04-04 For complex materials repeat calcu     51 // 28-04-04 For complex materials repeat calculation of max energy for each
 51 //          material (V.Ivanchenko)                52 //          material (V.Ivanchenko)
 52 // 01-11-04 Fix bug inside ComputeDMicroscopic     53 // 01-11-04 Fix bug inside ComputeDMicroscopicCrossSection (R.Kokoulin)
 53 // 08-04-05 Major optimisation of internal int     54 // 08-04-05 Major optimisation of internal interfaces (V.Ivantchenko)
 54 // 03-08-05 Add SetParticle method (V.Ivantche     55 // 03-08-05 Add SetParticle method (V.Ivantchenko)
 55 // 23-10-05 Add protection in sampling of e+e-     56 // 23-10-05 Add protection in sampling of e+e- pair energy needed for 
 56 //          low cuts (V.Ivantchenko)               57 //          low cuts (V.Ivantchenko)
 57 // 13-02-06 Add ComputeCrossSectionPerAtom (mm     58 // 13-02-06 Add ComputeCrossSectionPerAtom (mma)
 58 // 24-04-07 Add protection in SelectRandomAtom     59 // 24-04-07 Add protection in SelectRandomAtom method (V.Ivantchenko)
 59 // 12-05-06 Updated sampling (use cut) in Sele     60 // 12-05-06 Updated sampling (use cut) in SelectRandomAtom (A.Bogdanov) 
 60 // 11-10-07 Add ignoreCut flag (V.Ivanchenko)      61 // 11-10-07 Add ignoreCut flag (V.Ivanchenko) 
 61                                                    62 
 62 //                                                 63 //
 63 // Class Description:                              64 // Class Description:
 64 //                                                 65 //
 65 //                                                 66 //
 66 // -------------------------------------------     67 // -------------------------------------------------------------------
 67 //                                                 68 //
 68 //....oooOO0OOooo........oooOO0OOooo........oo     69 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 69 //....oooOO0OOooo........oooOO0OOooo........oo     70 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 70                                                    71 
 71 #include "G4MuPairProductionModel.hh"              72 #include "G4MuPairProductionModel.hh"
 72 #include "G4PhysicalConstants.hh"                  73 #include "G4PhysicalConstants.hh"
 73 #include "G4SystemOfUnits.hh"                      74 #include "G4SystemOfUnits.hh"
 74 #include "G4EmParameters.hh"                   << 
 75 #include "G4Electron.hh"                           75 #include "G4Electron.hh"
 76 #include "G4Positron.hh"                           76 #include "G4Positron.hh"
 77 #include "G4MuonMinus.hh"                          77 #include "G4MuonMinus.hh"
 78 #include "G4MuonPlus.hh"                           78 #include "G4MuonPlus.hh"
 79 #include "Randomize.hh"                            79 #include "Randomize.hh"
 80 #include "G4Material.hh"                           80 #include "G4Material.hh"
 81 #include "G4Element.hh"                            81 #include "G4Element.hh"
 82 #include "G4ElementVector.hh"                      82 #include "G4ElementVector.hh"
 83 #include "G4ElementDataRegistry.hh"            << 
 84 #include "G4ProductionCutsTable.hh"                83 #include "G4ProductionCutsTable.hh"
 85 #include "G4ParticleChangeForLoss.hh"              84 #include "G4ParticleChangeForLoss.hh"
 86 #include "G4ModifiedMephi.hh"                  <<  85 #include "G4ParticleChangeForGamma.hh"
 87 #include "G4Log.hh"                            << 
 88 #include "G4Exp.hh"                            << 
 89 #include "G4AutoLock.hh"                       << 
 90                                                << 
 91 #include <iostream>                            << 
 92 #include <fstream>                             << 
 93                                                    86 
 94 //....oooOO0OOooo........oooOO0OOooo........oo     87 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 95                                                    88 
 96 const G4int G4MuPairProductionModel::ZDATPAIR[ <<  89 // static members
 97                                                <<  90 //
 98 const G4double G4MuPairProductionModel::xgi[]  <<  91 G4double G4MuPairProductionModel::zdat[]={1., 4., 13., 29., 92.};
 99     0.0198550717512320, 0.1016667612931865, 0. <<  92 G4double G4MuPairProductionModel::adat[]={1.01, 9.01, 26.98, 63.55, 238.03};
100     0.5917173212478250, 0.7627662049581645, 0. <<  93 G4double G4MuPairProductionModel::tdat[]={1.e3, 1.e4, 1.e5, 1.e6, 1.e7, 1.e8,
101   };                                           <<  94                                           1.e9, 1.e10};
102                                                <<  95 G4double G4MuPairProductionModel::xgi[]={ 0.0199, 0.1017, 0.2372, 0.4083,
103 const G4double G4MuPairProductionModel::wgi[]  <<  96                                           0.5917, 0.7628, 0.8983, 0.9801 };
104     0.0506142681451880, 0.1111905172266870, 0. <<  97 G4double G4MuPairProductionModel::wgi[]={ 0.0506, 0.1112, 0.1569, 0.1813,
105     0.1813418916891810, 0.1568533229389435, 0. <<  98                                           0.1813, 0.1569, 0.1112, 0.0506 };
106   };                                           << 
107                                                << 
108 namespace                                      << 
109 {                                              << 
110   G4Mutex theMuPairMutex = G4MUTEX_INITIALIZER << 
111                                                << 
112   const G4double ak1 = 6.9;                    << 
113   const G4double ak2 = 1.0;                    << 
114 }                                              << 
115                                                    99 
116 //....oooOO0OOooo........oooOO0OOooo........oo    100 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
117                                                   101 
                                                   >> 102 using namespace std;
                                                   >> 103 
118 G4MuPairProductionModel::G4MuPairProductionMod    104 G4MuPairProductionModel::G4MuPairProductionModel(const G4ParticleDefinition* p,
119                                                   105                                                  const G4String& nam)
120   : G4VEmModel(nam),                              106   : G4VEmModel(nam),
121   factorForCross(CLHEP::fine_structure_const*C << 107     particle(0),
122      CLHEP::classic_electr_radius*CLHEP::class << 108     factorForCross(4.*fine_structure_const*fine_structure_const
123      4./(3.*CLHEP::pi)),                       << 109                    *classic_electr_radius*classic_electr_radius/(3.*pi)),
124   sqrte(std::sqrt(G4Exp(1.))),                 << 110     sqrte(sqrt(exp(1.))),
125   minPairEnergy(4.*CLHEP::electron_mass_c2),   << 111     currentZ(0),
126   lowestKinEnergy(0.85*CLHEP::GeV)             << 112     fParticleChange(0),
                                                   >> 113     minPairEnergy(4.*electron_mass_c2),
                                                   >> 114     lowestKinEnergy(GeV),
                                                   >> 115     nzdat(5),
                                                   >> 116     ntdat(8),
                                                   >> 117     nbiny(1000),
                                                   >> 118     nmaxElements(0),
                                                   >> 119     ymin(-5.),
                                                   >> 120     ymax(0.),
                                                   >> 121     dy((ymax-ymin)/nbiny),
                                                   >> 122     samplingTablesAreFilled(false)
127 {                                                 123 {
                                                   >> 124   SetLowEnergyLimit(minPairEnergy);
128   nist = G4NistManager::Instance();               125   nist = G4NistManager::Instance();
129                                                   126 
130   theElectron = G4Electron::Electron();           127   theElectron = G4Electron::Electron();
131   thePositron = G4Positron::Positron();           128   thePositron = G4Positron::Positron();
132                                                   129 
133   if(nullptr != p) {                           << 130   particleMass = lnZ = z13 = z23 = 0;
134     SetParticle(p);                            << 
135     lowestKinEnergy = std::max(lowestKinEnergy << 
136   }                                            << 
137   emin = lowestKinEnergy;                      << 
138   emax = emin*10000.;                          << 
139   SetAngularDistribution(new G4ModifiedMephi() << 
140 }                                              << 
141                                                   131 
142 //....oooOO0OOooo........oooOO0OOooo........oo << 132   for(size_t i=0; i<1001; ++i) { ya[i] = 0.0; }
143                                                   133 
144 G4double G4MuPairProductionModel::MinPrimaryEn << 134   if(p) { SetParticle(p); }
145                                                << 
146                                                << 
147 {                                              << 
148   return std::max(lowestKinEnergy, cut);       << 
149 }                                                 135 }
150                                                   136 
151 //....oooOO0OOooo........oooOO0OOooo........oo    137 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
152                                                   138 
153 void G4MuPairProductionModel::Initialise(const << 139 G4MuPairProductionModel::~G4MuPairProductionModel()
154                                          const << 140 {}
155 {                                              << 
156   SetParticle(p);                              << 
157                                                   141 
158   if (nullptr == fParticleChange) {            << 142 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
159     fParticleChange = GetParticleChangeForLoss << 
160                                                << 
161     // define scale of internal table for each << 
162     if (0 == nbine) {                          << 
163       emin = std::max(lowestKinEnergy, LowEner << 
164       emax = std::max(HighEnergyLimit(), emin* << 
165       nbine = std::size_t(nYBinPerDecade*std:: << 
166       if(nbine < 3) { nbine = 3; }             << 
167                                                   143 
168       ymin = G4Log(minPairEnergy/emin);        << 144 G4double G4MuPairProductionModel::MinEnergyCut(const G4ParticleDefinition*,
169       dy = -ymin/G4double(nbiny);              << 145                                                const G4MaterialCutsCouple* )
170     }                                          << 146 {
171     if (p == particle) {                       << 147   return minPairEnergy;
172       G4int pdg = std::abs(p->GetPDGEncoding() << 148 }
173       if (pdg == 2212) {                       << 
174   dataName = "pEEPairProd";                    << 
175       } else if (pdg == 321) {                 << 
176   dataName = "kaonEEPairProd";                 << 
177       } else if (pdg == 211) {                 << 
178   dataName = "pionEEPairProd";                 << 
179       } else if (pdg == 11) {                  << 
180   dataName = "eEEPairProd";                    << 
181       } else if (pdg == 13) {                  << 
182         if (GetName() == "muToMuonPairProd") { << 
183           dataName = "muMuMuPairProd";         << 
184   } else {                                     << 
185     dataName = "muEEPairProd";                 << 
186   }                                            << 
187       }                                        << 
188     }                                          << 
189   }                                            << 
190                                                   149 
191   // for low-energy application this process s << 150 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
192   if(lowestKinEnergy >= HighEnergyLimit()) { r << 
193                                                   151 
194   if (p == particle) {                         << 152 G4double G4MuPairProductionModel::MaxSecondaryEnergy(const G4ParticleDefinition*,
195     fElementData =                             << 153                  G4double kineticEnergy)
196       G4ElementDataRegistry::Instance()->GetEl << 154 {
197     if (nullptr == fElementData) {             << 155   G4double maxPairEnergy = kineticEnergy + particleMass*(1.0 - 0.75*sqrte*z13);
198       G4AutoLock l(&theMuPairMutex);           << 156   return maxPairEnergy;
199       fElementData =                           << 
200   G4ElementDataRegistry::Instance()->GetElemen << 
201       if (nullptr == fElementData) {           << 
202   fElementData = new G4ElementData(NZDATPAIR); << 
203   fElementData->SetName(dataName);             << 
204       }                                        << 
205       G4bool useDataFile = G4EmParameters::Ins << 
206       if (useDataFile)  { useDataFile = Retrie << 
207       if (!useDataFile) { MakeSamplingTables() << 
208       if (fTableToFile) { StoreTables(); }     << 
209       l.unlock();                              << 
210     }                                          << 
211     if (IsMaster()) {                          << 
212       InitialiseElementSelectors(p, cuts);     << 
213     }                                          << 
214   }                                            << 
215 }                                                 157 }
216                                                   158 
217 //....oooOO0OOooo........oooOO0OOooo........oo << 159 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
218                                                   160 
219 void G4MuPairProductionModel::InitialiseLocal( << 161 void G4MuPairProductionModel::Initialise(const G4ParticleDefinition* p,
220                                                << 162                                          const G4DataVector&)
221 {                                              << 163 { 
222   if(p == particle && lowestKinEnergy < HighEn << 164   if (!samplingTablesAreFilled) {
223     SetElementSelectors(masterModel->GetElemen << 165     if(p) { SetParticle(p); }
                                                   >> 166     MakeSamplingTables();
224   }                                               167   }
                                                   >> 168   if(!fParticleChange) { fParticleChange = GetParticleChangeForLoss(); }
225 }                                                 169 }
226                                                   170 
227 //....oooOO0OOooo........oooOO0OOooo........oo    171 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
228                                                   172 
229 G4double G4MuPairProductionModel::ComputeDEDXP    173 G4double G4MuPairProductionModel::ComputeDEDXPerVolume(
230                                                << 174                 const G4Material* material,
231                                                   175                                               const G4ParticleDefinition*,
232                                                   176                                                     G4double kineticEnergy,
233                                                   177                                                     G4double cutEnergy)
234 {                                                 178 {
235   G4double dedx = 0.0;                            179   G4double dedx = 0.0;
236   if (cutEnergy <= minPairEnergy || kineticEne    180   if (cutEnergy <= minPairEnergy || kineticEnergy <= lowestKinEnergy)
237     { return dedx; }                              181     { return dedx; }
238                                                   182 
239   const G4ElementVector* theElementVector = ma    183   const G4ElementVector* theElementVector = material->GetElementVector();
240   const G4double* theAtomicNumDensityVector =     184   const G4double* theAtomicNumDensityVector =
241                                    material->G    185                                    material->GetAtomicNumDensityVector();
242                                                   186 
243   //  loop for elements in the material           187   //  loop for elements in the material
244   for (std::size_t i=0; i<material->GetNumberO << 188   for (size_t i=0; i<material->GetNumberOfElements(); ++i) {
245      G4double Z = (*theElementVector)[i]->GetZ    189      G4double Z = (*theElementVector)[i]->GetZ();
246      G4double tmax = MaxSecondaryEnergyForElem << 190      SetCurrentElement(Z);
                                                   >> 191      G4double tmax = MaxSecondaryEnergy(particle, kineticEnergy);
247      G4double loss = ComputMuPairLoss(Z, kinet    192      G4double loss = ComputMuPairLoss(Z, kineticEnergy, cutEnergy, tmax);
248      dedx += loss*theAtomicNumDensityVector[i]    193      dedx += loss*theAtomicNumDensityVector[i];
249   }                                               194   }
250   dedx = std::max(dedx, 0.0);                  << 195   if (dedx < 0.) { dedx = 0.; }
251   return dedx;                                    196   return dedx;
252 }                                                 197 }
253                                                   198 
254 //....oooOO0OOooo........oooOO0OOooo........oo    199 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
255                                                   200 
256 G4double G4MuPairProductionModel::ComputMuPair    201 G4double G4MuPairProductionModel::ComputMuPairLoss(G4double Z, 
257                                                << 202                G4double tkin,
258                                                << 203                G4double cutEnergy, 
259                                                << 204                G4double tmax)
260 {                                                 205 {
                                                   >> 206   SetCurrentElement(Z);
261   G4double loss = 0.0;                            207   G4double loss = 0.0;
262                                                   208 
263   G4double cut = std::min(cutEnergy, tmax);    << 209   G4double cut = std::min(cutEnergy,tmax);
264   if(cut <= minPairEnergy) { return loss; }       210   if(cut <= minPairEnergy) { return loss; }
265                                                   211 
266   // calculate the rectricted loss                212   // calculate the rectricted loss
267   // numerical integration in log(PairEnergy)     213   // numerical integration in log(PairEnergy)
268   G4double aaa = G4Log(minPairEnergy);         << 214   G4double ak1=6.9;
269   G4double bbb = G4Log(cut);                   << 215   G4double ak2=1.0;
270                                                << 216   G4double aaa = log(minPairEnergy);
271   G4int kkk = std::min(std::max(G4lrint((bbb-a << 217   G4double bbb = log(cut);
272   G4double hhh = (bbb-aaa)/kkk;                << 218   G4int    kkk = (G4int)((bbb-aaa)/ak1+ak2);
                                                   >> 219   if (kkk > 8) kkk = 8;
                                                   >> 220   else if (kkk < 1) { kkk = 1; }
                                                   >> 221   G4double hhh = (bbb-aaa)/(G4double)kkk;
273   G4double x = aaa;                               222   G4double x = aaa;
274                                                   223 
275   for (G4int l=0 ; l<kkk; ++l) {               << 224   for (G4int l=0 ; l<kkk; l++)
276     for (G4int ll=0; ll<NINTPAIR; ++ll) {      << 225   {
277       G4double ep = G4Exp(x+xgi[ll]*hhh);      << 226 
                                                   >> 227     for (G4int ll=0; ll<8; ll++)
                                                   >> 228     {
                                                   >> 229       G4double ep = exp(x+xgi[ll]*hhh);
278       loss += wgi[ll]*ep*ep*ComputeDMicroscopi    230       loss += wgi[ll]*ep*ep*ComputeDMicroscopicCrossSection(tkin, Z, ep);
279     }                                             231     }
280     x += hhh;                                     232     x += hhh;
281   }                                               233   }
282   loss *= hhh;                                    234   loss *= hhh;
283   loss = std::max(loss, 0.0);                  << 235   if (loss < 0.) loss = 0.;
284   return loss;                                    236   return loss;
285 }                                                 237 }
286                                                   238 
287 //....oooOO0OOooo........oooOO0OOooo........oo    239 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
288                                                   240 
289 G4double G4MuPairProductionModel::ComputeMicro    241 G4double G4MuPairProductionModel::ComputeMicroscopicCrossSection(
290                                            G4d    242                                            G4double tkin,
291                                            G4d    243                                            G4double Z,
292                                            G4d << 244                                            G4double cut)
293 {                                                 245 {
294   G4double cross = 0.;                            246   G4double cross = 0.;
295   G4double tmax = MaxSecondaryEnergyForElement << 247   SetCurrentElement(Z);
296   G4double cut  = std::max(cutEnergy, minPairE << 248   G4double tmax = MaxSecondaryEnergy(particle, tkin);
297   if (tmax <= cut) { return cross; }              249   if (tmax <= cut) { return cross; }
298                                                   250 
299   G4double aaa = G4Log(cut);                   << 251   G4double ak1=6.9 ;
300   G4double bbb = G4Log(tmax);                  << 252   G4double ak2=1.0 ;
301   G4int kkk = std::min(std::max(G4lrint((bbb-a << 253   G4double aaa = log(cut);
302                                                << 254   G4double bbb = log(tmax);
303   G4double hhh = (bbb-aaa)/(kkk);              << 255   G4int kkk = (G4int)((bbb-aaa)/ak1 + ak2);
                                                   >> 256   if(kkk > 8) { kkk = 8; }
                                                   >> 257   else if(kkk < 1) { kkk = 1; }
                                                   >> 258   G4double hhh = (bbb-aaa)/G4double(kkk);
304   G4double x = aaa;                               259   G4double x = aaa;
305                                                   260 
306   for (G4int l=0; l<kkk; ++l) {                << 261   for(G4int l=0; l<kkk; ++l)
307     for (G4int i=0; i<NINTPAIR; ++i) {         << 262   {
308       G4double ep = G4Exp(x + xgi[i]*hhh);     << 263     for(G4int i=0; i<8; ++i)
                                                   >> 264     {
                                                   >> 265       G4double ep = exp(x + xgi[i]*hhh);
309       cross += ep*wgi[i]*ComputeDMicroscopicCr    266       cross += ep*wgi[i]*ComputeDMicroscopicCrossSection(tkin, Z, ep);
310     }                                             267     }
311     x += hhh;                                     268     x += hhh;
312   }                                               269   }
313                                                   270 
314   cross *= hhh;                                   271   cross *= hhh;
315   cross = std::max(cross, 0.0);                << 272   if(cross < 0.0) { cross = 0.0; }
316   return cross;                                   273   return cross;
317 }                                                 274 }
318                                                   275 
319 //....oooOO0OOooo........oooOO0OOooo........oo << 
320                                                << 
321 G4double G4MuPairProductionModel::ComputeDMicr    276 G4double G4MuPairProductionModel::ComputeDMicroscopicCrossSection(
322                                            G4d    277                                            G4double tkin,
323                                            G4d    278                                            G4double Z,
324                                            G4d    279                                            G4double pairEnergy)
325 // Calculates the  differential (D) microscopi << 280  // Calculates the  differential (D) microscopic cross section
326 // using the cross section formula of R.P. Kok << 281  // using the cross section formula of R.P. Kokoulin (18/01/98)
327 // Code modified by R.P. Kokoulin, V.N. Ivanch << 282  // Code modified by R.P. Kokoulin, V.N. Ivanchenko (27/01/04)
328 {                                              << 283 {
329   static const G4double bbbtf= 183. ;          << 284   G4double bbbtf= 183. ;
330   static const G4double bbbh = 202.4 ;         << 285   G4double bbbh = 202.4 ;
331   static const G4double g1tf = 1.95e-5 ;       << 286   G4double g1tf = 1.95e-5 ;
332   static const G4double g2tf = 5.3e-5 ;        << 287   G4double g2tf = 5.3e-5 ;
333   static const G4double g1h  = 4.4e-5 ;        << 288   G4double g1h  = 4.4e-5 ;
334   static const G4double g2h  = 4.8e-5 ;        << 289   G4double g2h  = 4.8e-5 ;
335                                                << 
336   if (pairEnergy <= minPairEnergy)             << 
337     return 0.0;                                << 
338                                                   290 
339   G4double totalEnergy  = tkin + particleMass;    291   G4double totalEnergy  = tkin + particleMass;
340   G4double residEnergy  = totalEnergy - pairEn    292   G4double residEnergy  = totalEnergy - pairEnergy;
                                                   >> 293   G4double massratio    = particleMass/electron_mass_c2 ;
                                                   >> 294   G4double massratio2   = massratio*massratio ;
                                                   >> 295   G4double cross = 0.;
341                                                   296 
342   if (residEnergy <= 0.75*sqrte*z13*particleMa << 297   SetCurrentElement(Z);
343     return 0.0;                                << 
344                                                   298 
345   G4double a0 = 1.0 / (totalEnergy * residEner << 299   G4double c3 = 0.75*sqrte*particleMass;
346   G4double alf = 4.0 * electron_mass_c2 / pair << 300   if (residEnergy <= c3*z13) { return cross; }
347   G4double rt = std::sqrt(1.0 - alf);          << 301 
348   G4double delta = 6.0 * particleMass * partic << 302   G4double c7 = 4.*electron_mass_c2;
349   G4double tmnexp = alf/(1.0 + rt) + delta*rt; << 303   G4double c8 = 6.*particleMass*particleMass;
350                                                << 304   G4double alf = c7/pairEnergy;
351   if(tmnexp >= 1.0) { return 0.0; }            << 305   G4double a3 = 1. - alf;
352                                                << 306   if (a3 <= 0.) { return cross; }
353   G4double tmn = G4Log(tmnexp);                << 
354                                                << 
355   G4double massratio = particleMass/CLHEP::ele << 
356   G4double massratio2 = massratio*massratio;   << 
357   G4double inv_massratio2 = 1.0 / massratio2;  << 
358                                                   307 
359   // zeta calculation                             308   // zeta calculation
360   G4double bbb,g1,g2;                             309   G4double bbb,g1,g2;
361   if( Z < 1.5 ) { bbb = bbbh ; g1 = g1h ; g2 =    310   if( Z < 1.5 ) { bbb = bbbh ; g1 = g1h ; g2 = g2h ; }
362   else          { bbb = bbbtf; g1 = g1tf; g2 =    311   else          { bbb = bbbtf; g1 = g1tf; g2 = g2tf; }
363                                                   312 
364   G4double zeta = 0.0;                         << 313   G4double zeta = 0;
365   G4double z1exp = totalEnergy / (particleMass << 314   G4double zeta1 = 0.073*log(totalEnergy/(particleMass+g1*z23*totalEnergy))-0.26;
366                                                << 315   if ( zeta1 > 0.)
367   // 35.221047195922 is the root of zeta1(x) = << 
368   // condition below is the same as zeta1 > 0. << 
369   if (z1exp > 35.221047195922)                 << 
370   {                                               316   {
371     G4double z2exp = totalEnergy / (particleMa << 317     G4double zeta2 = 0.058*log(totalEnergy/(particleMass+g2*z13*totalEnergy))-0.14;
372     zeta = (0.073 * G4Log(z1exp) - 0.26) / (0. << 318     zeta  = zeta1/zeta2 ;
373   }                                               319   }
374                                                   320 
375   G4double z2 = Z*(Z+zeta);                       321   G4double z2 = Z*(Z+zeta);
376   G4double screen0 = 2.*electron_mass_c2*sqrte    322   G4double screen0 = 2.*electron_mass_c2*sqrte*bbb/(z13*pairEnergy);
377   G4double beta = 0.5*pairEnergy*pairEnergy*a0 << 323   G4double a0 = totalEnergy*residEnergy;
378   G4double xi0 = 0.5*massratio2*beta;          << 324   G4double a1 = pairEnergy*pairEnergy/a0;
379                                                << 325   G4double bet = 0.5*a1;
380   // Gaussian integration in ln(1-ro) ( with 8 << 326   G4double xi0 = 0.25*massratio2*a1;
381   G4double rho[NINTPAIR];                      << 327   G4double del = c8/a0;
382   G4double rho2[NINTPAIR];                     << 328 
383   G4double xi[NINTPAIR];                       << 329   G4double rta3 = sqrt(a3);
384   G4double xi1[NINTPAIR];                      << 330   G4double tmnexp = alf/(1. + rta3) + del*rta3;
385   G4double xii[NINTPAIR];                      << 331   if(tmnexp >= 1.0) return cross;
386                                                << 
387   for (G4int i = 0; i < NINTPAIR; ++i)         << 
388   {                                            << 
389     rho[i] = G4Exp(tmn*xgi[i]) - 1.0; // rho = << 
390     rho2[i] = rho[i] * rho[i];                 << 
391     xi[i] = xi0*(1.0-rho2[i]);                 << 
392     xi1[i] = 1.0 + xi[i];                      << 
393     xii[i] = 1.0 / xi[i];                      << 
394   }                                            << 
395                                                   332 
396   G4double ye1[NINTPAIR];                      << 333   G4double tmn = log(tmnexp);
397   G4double ym1[NINTPAIR];                      << 334   G4double sum = 0.;
398                                                   335 
399   G4double b40 = 4.0 * beta;                   << 336   // Gaussian integration in ln(1-ro) ( with 8 points)
400   G4double b62 = 6.0 * beta + 2.0;             << 337   for (G4int i=0; i<8; ++i)
401                                                << 
402   for (G4int i = 0; i < NINTPAIR; ++i)         << 
403   {                                               338   {
404     G4double yeu = (b40 + 5.0) + (b40 - 1.0) * << 339     G4double a4 = exp(tmn*xgi[i]);     // a4 = (1.-asymmetry)
405     G4double yed = b62*G4Log(3.0 + xii[i]) + ( << 340     G4double a5 = a4*(2.-a4) ;
406                                                << 341     G4double a6 = 1.-a5 ;
407     G4double ymu = b62 * (1.0 + rho2[i]) + 6.0 << 342     G4double a7 = 1.+a6 ;
408     G4double ymd = (b40 + 3.0)*(1.0 + rho2[i]) << 343     G4double a9 = 3.+a6 ;
409       + 2.0 - 3.0 * rho2[i];                   << 344     G4double xi = xi0*a5 ;
410                                                << 345     G4double xii = 1./xi ;
411     ye1[i] = 1.0 + yeu / yed;                  << 346     G4double xi1 = 1.+xi ;
412     ym1[i] = 1.0 + ymu / ymd;                  << 347     G4double screen = screen0*xi1/a5 ;
413   }                                            << 348     G4double yeu = 5.-a6+4.*bet*a7 ;
414                                                << 349     G4double yed = 2.*(1.+3.*bet)*log(3.+xii)-a6-a1*(2.-a6) ;
415   G4double be[NINTPAIR];                       << 350     G4double ye1 = 1.+yeu/yed ;
416   G4double bm[NINTPAIR];                       << 351     G4double ale=log(bbb/z13*sqrt(xi1*ye1)/(1.+screen*ye1)) ;
417                                                << 352     G4double cre = 0.5*log(1.+2.25*z23*xi1*ye1/massratio2) ;
418   for(G4int i = 0; i < NINTPAIR; ++i) {        << 353     G4double be;
419     if(xi[i] <= 1000.0) {                      << 354 
420       be[i] = ((2.0 + rho2[i])*(1.0 + beta) +  << 355     if (xi <= 1.e3) be = ((2.+a6)*(1.+bet)+xi*a9)*log(1.+xii)+(a5-bet)/xi1-a9;
421          xi[i]*(3.0 + rho2[i]))*G4Log(1.0 + xi << 356     else            be = (3.-a6+a1*a7)/(2.*xi);
422   (1.0 - rho2[i] - beta)/xi1[i] - (3.0 + rho2[ << 357 
                                                   >> 358     G4double fe = (ale-cre)*be;
                                                   >> 359     if ( fe < 0.) fe = 0. ;
                                                   >> 360 
                                                   >> 361     G4double ymu = 4.+a6 +3.*bet*a7 ;
                                                   >> 362     G4double ymd = a7*(1.5+a1)*log(3.+xi)+1.-1.5*a6 ;
                                                   >> 363     G4double ym1 = 1.+ymu/ymd ;
                                                   >> 364     G4double alm_crm = log(bbb*massratio/(1.5*z23*(1.+screen*ym1)));
                                                   >> 365     G4double a10,bm;
                                                   >> 366     if ( xi >= 1.e-3)
                                                   >> 367     {
                                                   >> 368       a10 = (1.+a1)*a5 ;
                                                   >> 369       bm  = (a7*(1.+1.5*bet)-a10*xii)*log(xi1)+xi*(a5-bet)/xi1+a10;
423     } else {                                      370     } else {
424       be[i] = 0.5*(3.0 - rho2[i] + 2.0*beta*(1 << 371       bm = (5.-a6+bet*a9)*(xi/2.);
425     }                                             372     }
426                                                   373 
427     if(xi[i] >= 0.001) {                       << 374     G4double fm = alm_crm*bm;
428       G4double a10 = (1.0 + 2.0 * beta) * (1.0 << 375     if ( fm < 0.) fm = 0. ;
429       bm[i] = ((1.0 + rho2[i])*(1.0 + 1.5 * be << 
430                 xi[i] * (1.0 - rho2[i] - beta) << 
431     } else {                                   << 
432       bm[i] = 0.5*(5.0 - rho2[i] + beta * (3.0 << 
433     }                                          << 
434   }                                            << 
435                                                << 
436   G4double sum = 0.0;                          << 
437                                                << 
438   for (G4int i = 0; i < NINTPAIR; ++i) {       << 
439     G4double screen = screen0*xi1[i]/(1.0 - rh << 
440     G4double ale = G4Log(bbb/z13*std::sqrt(xi1 << 
441     G4double cre = 0.5*G4Log(1. + 2.25*z23*xi1 << 
442                                                << 
443     G4double fe = (ale-cre)*be[i];             << 
444     fe = std::max(fe, 0.0);                    << 
445                                                   376 
446     G4double alm_crm = G4Log(bbb*massratio/(1. << 377     sum += wgi[i]*a4*(fe+fm/massratio2);
447     G4double fm = std::max(alm_crm*bm[i], 0.0) << 
448                                                << 
449     sum += wgi[i]*(1.0 + rho[i])*(fe + fm);    << 
450   }                                               378   }
451                                                   379 
452   return -tmn*sum*factorForCross*z2*residEnerg << 380   cross = -tmn*sum*factorForCross*z2*residEnergy/(totalEnergy*pairEnergy);
                                                   >> 381 
                                                   >> 382   return cross;
453 }                                                 383 }
454                                                   384 
455 //....oooOO0OOooo........oooOO0OOooo........oo    385 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
456                                                   386 
457 G4double G4MuPairProductionModel::ComputeCross    387 G4double G4MuPairProductionModel::ComputeCrossSectionPerAtom(
458                                            con    388                                            const G4ParticleDefinition*,
459                                                   389                                                  G4double kineticEnergy,
460                                                << 390              G4double Z, G4double,
461                                                   391                                                  G4double cutEnergy,
462                                                   392                                                  G4double maxEnergy)
463 {                                                 393 {
464   G4double cross = 0.0;                           394   G4double cross = 0.0;
465   if (kineticEnergy <= lowestKinEnergy) { retu    395   if (kineticEnergy <= lowestKinEnergy) { return cross; }
466                                                   396 
467   G4double maxPairEnergy = MaxSecondaryEnergyF << 397   SetCurrentElement(Z);
                                                   >> 398 
                                                   >> 399   G4double maxPairEnergy = MaxSecondaryEnergy(particle,kineticEnergy);
468   G4double tmax = std::min(maxEnergy, maxPairE    400   G4double tmax = std::min(maxEnergy, maxPairEnergy);
469   G4double cut  = std::max(cutEnergy, minPairE    401   G4double cut  = std::max(cutEnergy, minPairEnergy);
470   if (cut >= tmax) { return cross; }           << 402   if (cut >= tmax) return cross;
471                                                   403 
472   cross = ComputeMicroscopicCrossSection(kinet << 404   cross = ComputeMicroscopicCrossSection (kineticEnergy, Z, cut);
473   if(tmax < kineticEnergy) {                      405   if(tmax < kineticEnergy) {
474     cross -= ComputeMicroscopicCrossSection(ki    406     cross -= ComputeMicroscopicCrossSection(kineticEnergy, Z, tmax);
475   }                                               407   }
476   return cross;                                   408   return cross;
477 }                                                 409 }
478                                                   410 
479 //....oooOO0OOooo........oooOO0OOooo........oo    411 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
480                                                   412 
481 void G4MuPairProductionModel::MakeSamplingTabl    413 void G4MuPairProductionModel::MakeSamplingTables()
482 {                                                 414 {
483   G4double factore = G4Exp(G4Log(emax/emin)/G4 << 415   for (G4int iz=0; iz<nzdat; ++iz)
                                                   >> 416   {
                                                   >> 417     G4double Z = zdat[iz];
                                                   >> 418     SetCurrentElement(Z);
                                                   >> 419 
                                                   >> 420     for (G4int it=0; it<ntdat; ++it) {
484                                                   421 
485   for (G4int iz=0; iz<NZDATPAIR; ++iz) {       << 422       G4double kineticEnergy = tdat[it];
                                                   >> 423       G4double maxPairEnergy = MaxSecondaryEnergy(particle,kineticEnergy);
                                                   >> 424       // G4cout << "Z= " << currentZ << " z13= " << z13 
                                                   >> 425       //<< " mE= " << maxPairEnergy << G4endl;
                                                   >> 426       G4double xSec = 0.0 ;
                                                   >> 427 
                                                   >> 428       if(maxPairEnergy > minPairEnergy) {
                                                   >> 429 
                                                   >> 430   G4double y = ymin - 0.5*dy ;
                                                   >> 431   G4double yy = ymin - dy ;
                                                   >> 432   G4double x = exp(y);
                                                   >> 433   G4double fac = exp(dy);
                                                   >> 434   G4double dx = exp(yy)*(fac - 1.0);
                                                   >> 435 
                                                   >> 436   G4double c = log(maxPairEnergy/minPairEnergy);
                                                   >> 437 
                                                   >> 438   for (G4int i=0 ; i<nbiny; ++i) {
                                                   >> 439     y += dy ;
                                                   >> 440     if(c > 0.0) {
                                                   >> 441       x *= fac;
                                                   >> 442       dx*= fac;
                                                   >> 443       G4double ep = minPairEnergy*exp(c*x) ;
                                                   >> 444       xSec += 
                                                   >> 445         ep*dx*ComputeDMicroscopicCrossSection(kineticEnergy, Z, ep);
                                                   >> 446     }
                                                   >> 447     ya[i] = y;
                                                   >> 448     proba[iz][it][i] = xSec;
                                                   >> 449   }
                                                   >> 450        
                                                   >> 451       } else {
                                                   >> 452   for (G4int i=0 ; i<nbiny; ++i) {
                                                   >> 453     proba[iz][it][i] = xSec;
                                                   >> 454   }
                                                   >> 455       }
486                                                   456 
487     G4double Z = ZDATPAIR[iz];                 << 457       ya[nbiny]=ymax;
488     G4Physics2DVector* pv = new G4Physics2DVec << 458       proba[iz][it][nbiny] = xSec;
489     G4double kinEnergy = emin;                 << 
490                                                << 
491     for (std::size_t it=0; it<=nbine; ++it) {  << 
492                                                << 
493       pv->PutY(it, G4Log(kinEnergy/CLHEP::MeV) << 
494       G4double maxPairEnergy = MaxSecondaryEne << 
495       /*                                       << 
496       G4cout << "it= " << it << " E= " << kinE << 
497              << "  " << particle->GetParticleN << 
498              << " maxE= " << maxPairEnergy <<  << 
499              << " ymin= " << ymin << G4endl;   << 
500       */                                       << 
501       G4double coef = G4Log(minPairEnergy/kinE << 
502       G4double ymax = G4Log(maxPairEnergy/kinE << 
503       G4double fac  = (ymax - ymin)/dy;        << 
504       std::size_t imax   = (std::size_t)fac;   << 
505       fac -= (G4double)imax;                   << 
506                                                << 
507       G4double xSec = 0.0;                     << 
508       G4double x = ymin;                       << 
509       /*                                       << 
510       G4cout << "Z= " << currentZ << " z13= "  << 
511              << " mE= " << maxPairEnergy << "  << 
512              << " dy= " << dy << "  c= " << co << 
513       */                                       << 
514       // start from zero                       << 
515       pv->PutValue(0, it, 0.0);                << 
516       if(0 == it) { pv->PutX(nbiny, 0.0); }    << 
517                                                << 
518       for (std::size_t i=0; i<nbiny; ++i) {    << 
519                                                << 
520         if(0 == it) { pv->PutX(i, x); }        << 
521                                                << 
522         if(i < imax) {                         << 
523           G4double ep = kinEnergy*G4Exp(coef*( << 
524                                                << 
525           // not multiplied by interval, becau << 
526           // will be used only for sampling    << 
527           //G4cout << "i= " << i << " x= " <<  << 
528           //         << " Egamma= " << ep << G << 
529           xSec += ep*ComputeDMicroscopicCrossS << 
530                                                << 
531           // last bin before the kinematic lim << 
532         } else if(i == imax) {                 << 
533           G4double ep = kinEnergy*G4Exp(coef*( << 
534           xSec += ep*fac*ComputeDMicroscopicCr << 
535         }                                      << 
536         pv->PutValue(i + 1, it, xSec);         << 
537         x += dy;                               << 
538       }                                        << 
539       kinEnergy *= factore;                    << 
540                                                   459 
541       // to avoid precision lost               << 
542       if(it+1 == nbine) { kinEnergy = emax; }  << 
543     }                                             460     }
544     fElementData->InitialiseForElement(iz, pv) << 
545   }                                               461   }
                                                   >> 462   samplingTablesAreFilled = true;
546 }                                                 463 }
547                                                   464 
548 //....oooOO0OOooo........oooOO0OOooo........oo    465 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
549                                                   466 
550 void G4MuPairProductionModel::SampleSecondarie << 467 void 
551                               std::vector<G4Dy << 468 G4MuPairProductionModel::SampleSecondaries(std::vector<G4DynamicParticle*>* vdp, 
552                               const G4Material << 469              const G4MaterialCutsCouple* couple,
553                               const G4DynamicP << 470              const G4DynamicParticle* aDynamicParticle,
554                               G4double tmin,   << 471              G4double tmin,
555                               G4double tmax)   << 472              G4double tmax)
556 {                                                 473 {
557   G4double kinEnergy = aDynamicParticle->GetKi << 474   G4double kineticEnergy = aDynamicParticle->GetKineticEnergy();
558   //G4cout << "------- G4MuPairProductionModel << 475   G4double totalEnergy   = kineticEnergy + particleMass;
559   //         << kinEnergy << "  "              << 
560   //         << aDynamicParticle->GetDefinitio << 
561   G4double totalEnergy   = kinEnergy + particl << 
562   G4double totalMomentum =                        476   G4double totalMomentum = 
563     std::sqrt(kinEnergy*(kinEnergy + 2.0*parti << 477     sqrt(kineticEnergy*(kineticEnergy + 2.0*particleMass));
564                                                   478 
565   G4ThreeVector partDirection = aDynamicPartic    479   G4ThreeVector partDirection = aDynamicParticle->GetMomentumDirection();
566                                                   480 
567   // select randomly one element constituing t << 481   G4int it;
568   const G4Element* anElement = SelectRandomAto << 482   for(it=1; it<ntdat; ++it) { if(kineticEnergy <= tdat[it]) { break; } }
                                                   >> 483   if(it == ntdat) { --it; }
                                                   >> 484   G4double dt = log(kineticEnergy/tdat[it-1])/log(tdat[it]/tdat[it-1]);
569                                                   485 
570   // define interval of energy transfer        << 486   // select randomly one element constituing the material
571   G4double maxPairEnergy = MaxSecondaryEnergyF << 487   const G4Element* anElement = 
572                                                << 488     SelectRandomAtom(kineticEnergy, dt, it, couple, tmin);
573   G4double maxEnergy = std::min(tmax, maxPairE << 489   SetCurrentElement(anElement->GetZ());
574   G4double minEnergy = std::max(tmin, minPairE << 490 
                                                   >> 491   // define interval of enegry transfer
                                                   >> 492   G4double maxPairEnergy = MaxSecondaryEnergy(particle,kineticEnergy);
                                                   >> 493   G4double maxEnergy     = std::min(tmax, maxPairEnergy);
                                                   >> 494   G4double minEnergy     = std::max(tmin, minPairEnergy);
575                                                   495 
576   if (minEnergy >= maxEnergy) { return; }      << 496   if(minEnergy >= maxEnergy) { return; }
577   //G4cout << "emin= " << minEnergy << " emax=    497   //G4cout << "emin= " << minEnergy << " emax= " << maxEnergy 
578   // << " minPair= " << minPairEnergy << " max << 498   //   << " minPair= " << minPairEnergy << " maxpair= " << maxPairEnergy 
579   //    << " ymin= " << ymin << " dy= " << dy  << 499   //       << " ymin= " << ymin << " dy= " << dy << G4endl;
580                                                   500 
581   G4double coeff = G4Log(minPairEnergy/kinEner << 501   G4double logmaxmin = log(maxPairEnergy/minPairEnergy);
582                                                   502 
583   // compute limits                            << 503   // select bins
584   G4double yymin = G4Log(minEnergy/kinEnergy)/ << 504   G4int iymin = 0;
585   G4double yymax = G4Log(maxEnergy/kinEnergy)/ << 505   G4int iymax = nbiny-1;
586                                                << 506   if( minEnergy > minPairEnergy)
587   //G4cout << "yymin= " << yymin << "  yymax=  << 507   {
588                                                << 508     G4double xc = log(minEnergy/minPairEnergy)/logmaxmin;
589   // units should not be used, bacause table w << 509     iymin = (G4int)((log(xc) - ymin)/dy);
590   G4double logTkin = G4Log(kinEnergy/CLHEP::Me << 510     if(iymin >= nbiny) iymin = nbiny-1;
                                                   >> 511     else if(iymin < 0) iymin = 0;
                                                   >> 512     xc = log(maxEnergy/minPairEnergy)/logmaxmin;
                                                   >> 513     iymax = (G4int)((log(xc) - ymin)/dy) + 1;
                                                   >> 514     if(iymax >= nbiny) iymax = nbiny-1;
                                                   >> 515     else if(iymax < 0) iymax = 0;
                                                   >> 516   }
591                                                   517 
592   // sample e-e+ energy, pair energy first        518   // sample e-e+ energy, pair energy first
                                                   >> 519   G4int iz, iy;
593                                                   520 
594   // select sample table via Z                 << 521   for(iz=1; iz<nzdat; ++iz) { if(currentZ <= zdat[iz]) { break; } }
595   G4int iz1(0), iz2(0);                        << 522   if(iz == nzdat) { --iz; }
596   for (G4int iz=0; iz<NZDATPAIR; ++iz) {       << 523 
597     if(currentZ == ZDATPAIR[iz]) {             << 524   G4double dz = log(currentZ/zdat[iz-1])/log(zdat[iz]/zdat[iz-1]);
598       iz1 = iz2 = iz;                          << 525 
599       break;                                   << 526   G4double pmin = InterpolatedIntegralCrossSection(dt,dz,iz,it,iymin,currentZ);
600     } else if(currentZ < ZDATPAIR[iz]) {       << 527   G4double pmax = InterpolatedIntegralCrossSection(dt,dz,iz,it,iymax,currentZ);
601       iz2 = iz;                                << 528 
602       if(iz > 0) { iz1 = iz-1; }               << 529   G4double p = pmin+G4UniformRand()*(pmax - pmin);
603       else { iz1 = iz2; }                      << 530 
604       break;                                   << 531   // interpolate sampling vector;
605     }                                          << 532   G4double p1 = pmin;
606   }                                            << 533   G4double p2 = pmin;
607   if (0 == iz1) { iz1 = iz2 = NZDATPAIR-1; }   << 534   for(iy=iymin+1; iy<=iymax; ++iy) {
608                                                << 535     p1 = p2;
609   G4double pairEnergy = 0.0;                   << 536     p2 = InterpolatedIntegralCrossSection(dt, dz, iz, it, iy, currentZ);
610   G4int count = 0;                             << 537     if(p <= p2) { break; }
611   //G4cout << "start loop Z1= " << iz1 << " Z2 << 538   }
612   do {                                         << 539   // G4cout << "iy= " << iy << " iymin= " << iymin << " iymax= " 
613     ++count;                                   << 540   //        << iymax << " Z= " << currentZ << G4endl;
614     // sampling using only one random number   << 541   G4double y = ya[iy-1] + dy*(p - p1)/(p2 - p1);
615     G4double rand = G4UniformRand();           << 
616                                                << 
617     G4double x = FindScaledEnergy(iz1, rand, l << 
618     if(iz1 != iz2) {                           << 
619       G4double x2 = FindScaledEnergy(iz2, rand << 
620       G4double lz1= nist->GetLOGZ(ZDATPAIR[iz1 << 
621       G4double lz2= nist->GetLOGZ(ZDATPAIR[iz2 << 
622       //G4cout << count << ".  x= " << x << "  << 
623       //             << " Z1= " << iz1 << " Z2 << 
624       x += (x2 - x)*(lnZ - lz1)/(lz2 - lz1);   << 
625     }                                          << 
626     //G4cout << "x= " << x << "  coeff= " << c << 
627     pairEnergy = kinEnergy*G4Exp(x*coeff);     << 
628                                                << 
629     // Loop checking, 03-Aug-2015, Vladimir Iv << 
630   } while((pairEnergy < minEnergy || pairEnerg << 
631                                                   542 
632   //G4cout << "## pairEnergy(GeV)= " << pairEn << 543   G4double PairEnergy = minPairEnergy*exp( exp(y)*logmaxmin );
633   //         << " Etot(GeV)= " << totalEnergy/ << 544            
                                                   >> 545   if(PairEnergy < minEnergy) { PairEnergy = minEnergy; }
                                                   >> 546   if(PairEnergy > maxEnergy) { PairEnergy = maxEnergy; }
634                                                   547 
635   // sample r=(E+-E-)/pairEnergy  ( uniformly  << 548   // sample r=(E+-E-)/PairEnergy  ( uniformly .....)
636   G4double rmax =                                 549   G4double rmax =
637     (1.-6.*particleMass*particleMass/(totalEne << 550     (1.-6.*particleMass*particleMass/(totalEnergy*(totalEnergy-PairEnergy)))
638     *std::sqrt(1.-minPairEnergy/pairEnergy);   << 551                                        *sqrt(1.-minPairEnergy/PairEnergy);
639   G4double r = rmax * (-1.+2.*G4UniformRand())    552   G4double r = rmax * (-1.+2.*G4UniformRand()) ;
640                                                   553 
641   // compute energies from pairEnergy,r        << 554   // compute energies from PairEnergy,r
642   G4double eEnergy = (1.-r)*pairEnergy*0.5;    << 555   G4double ElectronEnergy = (1.-r)*PairEnergy*0.5;
643   G4double pEnergy = pairEnergy - eEnergy;     << 556   G4double PositronEnergy = PairEnergy - ElectronEnergy;
644                                                << 557 
645   // Sample angles                             << 558   // The angle of the emitted virtual photon is sampled
646   G4ThreeVector eDirection, pDirection;        << 559   // according to the muon bremsstrahlung model
647   //                                           << 560  
648   GetAngularDistribution()->SamplePairDirectio << 561   G4double gam  = totalEnergy/particleMass;
649                                                << 562   G4double gmax = gam*std::min(1.0, totalEnergy/PairEnergy - 1.0);
650                                                << 563   G4double gmax2= gmax*gmax;
651   // create G4DynamicParticle object for e+e-  << 564   G4double x = G4UniformRand()*gmax2/(1.0 + gmax2);
652   eEnergy = std::max(eEnergy - CLHEP::electron << 565 
653   pEnergy = std::max(pEnergy - CLHEP::electron << 566   G4double theta = sqrt(x/(1.0 - x))/gam;
654   auto aParticle1 = new G4DynamicParticle(theE << 567   G4double sint  = sin(theta);
655   auto aParticle2 = new G4DynamicParticle(theP << 568   G4double phi   = twopi * G4UniformRand() ;
656   // Fill output vector                        << 569   G4double dirx  = sint*cos(phi), diry = sint*sin(phi), dirz = cos(theta) ;
657   vdp->push_back(aParticle1);                  << 570 
658   vdp->push_back(aParticle2);                  << 571   G4ThreeVector gDirection(dirx, diry, dirz);
                                                   >> 572   gDirection.rotateUz(partDirection);
                                                   >> 573 
                                                   >> 574   // the angles of e- and e+ assumed to be the same as virtual gamma
                                                   >> 575 
                                                   >> 576   // create G4DynamicParticle object for the particle1
                                                   >> 577   G4DynamicParticle* aParticle1 = 
                                                   >> 578     new G4DynamicParticle(theElectron, gDirection, 
                                                   >> 579         ElectronEnergy - electron_mass_c2);
                                                   >> 580 
                                                   >> 581   // create G4DynamicParticle object for the particle2
                                                   >> 582   G4DynamicParticle* aParticle2 = 
                                                   >> 583     new G4DynamicParticle(thePositron, gDirection,
                                                   >> 584         PositronEnergy - electron_mass_c2);
659                                                   585 
660   // primary change                               586   // primary change
661   kinEnergy -= pairEnergy;                     << 587   kineticEnergy -= (ElectronEnergy + PositronEnergy);
                                                   >> 588   fParticleChange->SetProposedKineticEnergy(kineticEnergy);
                                                   >> 589 
662   partDirection *= totalMomentum;                 590   partDirection *= totalMomentum;
663   partDirection -= (aParticle1->GetMomentum()     591   partDirection -= (aParticle1->GetMomentum() + aParticle2->GetMomentum());
664   partDirection = partDirection.unit();           592   partDirection = partDirection.unit();
                                                   >> 593   fParticleChange->SetProposedMomentumDirection(partDirection);
665                                                   594 
666   // if energy transfer is higher than thresho << 595   // add secondary
667   // then stop tracking the primary particle a << 596   vdp->push_back(aParticle1);
668   if (pairEnergy > SecondaryThreshold()) {     << 597   vdp->push_back(aParticle2);
669     fParticleChange->ProposeTrackStatus(fStopA << 
670     fParticleChange->SetProposedKineticEnergy( << 
671     auto newdp = new G4DynamicParticle(particl << 
672     vdp->push_back(newdp);                     << 
673   } else { // continue tracking the primary e- << 
674     fParticleChange->SetProposedMomentumDirect << 
675     fParticleChange->SetProposedKineticEnergy( << 
676   }                                            << 
677   //G4cout << "-- G4MuPairProductionModel::Sam << 
678 }                                                 598 }
679                                                   599 
680 //....oooOO0OOooo........oooOO0OOooo........oo    600 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
681                                                   601 
682 G4double                                       << 602 const G4Element* G4MuPairProductionModel::SelectRandomAtom(
683 G4MuPairProductionModel::FindScaledEnergy(G4in << 603                  G4double kinEnergy, G4double dt, G4int it,
684             G4double logTkin,                  << 604            const G4MaterialCutsCouple* couple, G4double tmin)
685             G4double yymin, G4double yymax)    << 
686 {                                                 605 {
687   G4double res = yymin;                        << 606   // select randomly 1 element within the material
688   G4Physics2DVector* pv = fElementData->GetEle << 607 
689   if (nullptr != pv) {                         << 608   const G4Material* material = couple->GetMaterial();
690     G4double pmin = pv->Value(yymin, logTkin); << 609   size_t nElements = material->GetNumberOfElements();
691     G4double pmax = pv->Value(yymax, logTkin); << 610   const G4ElementVector* theElementVector = material->GetElementVector();
692     G4double p0   = pv->Value(0.0, logTkin);   << 611   if (nElements == 1) { return (*theElementVector)[0]; }
693     if(p0 <= 0.0) { DataCorrupted(ZDATPAIR[iz] << 612 
694     else { res = pv->FindLinearX((pmin + rand* << 613   if(nElements > nmaxElements) {
695   } else {                                     << 614     nmaxElements = nElements;
696     DataCorrupted(ZDATPAIR[iz], logTkin);      << 615     partialSum.resize(nmaxElements);
697   }                                               616   }
698   return res;                                  << 
699 }                                              << 
700                                                   617 
701 //....oooOO0OOooo........oooOO0OOooo........oo << 618   const G4double* theAtomNumDensityVector=material->GetAtomicNumDensityVector();
702                                                   619 
703 void G4MuPairProductionModel::DataCorrupted(G4 << 620   G4double sum = 0.0;
704 {                                              << 621   G4double dl;
705   G4ExceptionDescription ed;                   << 
706   ed << "G4ElementData is not properly initial << 
707      << " Ekin(MeV)= " << G4Exp(logTkin)       << 
708      << " IsMasterThread= " << IsMaster()      << 
709      << " Model " << GetName();                << 
710   G4Exception("G4MuPairProductionModel::()", " << 
711 }                                              << 
712                                                   622 
713 //....oooOO0OOooo........oooOO0OOooo........oo << 623   size_t i;
                                                   >> 624   for (i=0; i<nElements; ++i) {
                                                   >> 625     G4double Z = ((*theElementVector)[i])->GetZ();
                                                   >> 626     SetCurrentElement(Z);
                                                   >> 627     G4double maxPairEnergy = MaxSecondaryEnergy(particle,kinEnergy);
                                                   >> 628     G4double minEnergy     = std::max(tmin, minPairEnergy);
                                                   >> 629     dl = 0.0;
                                                   >> 630     if(minEnergy < maxPairEnergy) {
                                                   >> 631 
                                                   >> 632       G4int iz;
                                                   >> 633       for(iz=1; iz<nzdat; ++iz) {if(Z <= zdat[iz]) { break; } }
                                                   >> 634       if(iz == nzdat) { --iz; }
                                                   >> 635       G4double dz = log(Z/zdat[iz-1])/log(zdat[iz]/zdat[iz-1]);
                                                   >> 636 
                                                   >> 637       G4double sigcut;
                                                   >> 638       if(minEnergy <= minPairEnergy)
                                                   >> 639   sigcut = 0.;
                                                   >> 640       else
                                                   >> 641   {
                                                   >> 642     G4double xc = log(minEnergy/minPairEnergy)/log(maxPairEnergy/minPairEnergy);
                                                   >> 643     G4int iy = (G4int)((log(xc) - ymin)/dy);
                                                   >> 644     if(iy < 0) { iy = 0; }
                                                   >> 645     if(iy >= nbiny) { iy = nbiny-1; }
                                                   >> 646     sigcut = InterpolatedIntegralCrossSection(dt,dz,iz,it,iy, Z);
                                                   >> 647   }
714                                                   648 
715 void G4MuPairProductionModel::StoreTables() co << 649       G4double sigtot = InterpolatedIntegralCrossSection(dt,dz,iz,it,nbiny,Z);
716 {                                              << 650       dl = (sigtot - sigcut)*theAtomNumDensityVector[i];
717   for (G4int iz=0; iz<NZDATPAIR; ++iz) {       << 
718     G4int Z = ZDATPAIR[iz];                    << 
719     G4Physics2DVector* pv = fElementData->GetE << 
720     if(nullptr == pv) {                        << 
721       DataCorrupted(Z, 1.0);                   << 
722       return;                                  << 
723     }                                             651     }
724     std::ostringstream ss;                     << 652     // protection
725     ss << "mupair/" << particle->GetParticleNa << 653     if(dl < 0.0) { dl = 0.0; }
726     std::ofstream outfile(ss.str());           << 654     sum += dl;
727     pv->Store(outfile);                        << 655     partialSum[i] = sum;
728   }                                               656   }
729 }                                              << 
730                                                << 
731 //....oooOO0OOooo........oooOO0OOooo........oo << 
732                                                   657 
733 G4bool G4MuPairProductionModel::RetrieveTables << 658   G4double rval = G4UniformRand()*sum;
734 {                                              << 659   for (i=0; i<nElements; ++i) {
735   for (G4int iz=0; iz<NZDATPAIR; ++iz) {       << 660     if(rval<=partialSum[i]) { return (*theElementVector)[i]; }
736     G4double Z = ZDATPAIR[iz];                 << 
737     G4Physics2DVector* pv = new G4Physics2DVec << 
738     std::ostringstream ss;                     << 
739     ss << G4EmParameters::Instance()->GetDirLE << 
740        << particle->GetParticleName() << Z <<  << 
741     std::ifstream infile(ss.str(), std::ios::i << 
742     if(!pv->Retrieve(infile)) {                << 
743       delete pv;                               << 
744       return false;                            << 
745     }                                          << 
746     fElementData->InitialiseForElement(iz, pv) << 
747   }                                               661   }
748   return true;                                 << 662 
                                                   >> 663   return (*theElementVector)[nElements - 1];
                                                   >> 664 
749 }                                                 665 }
750                                                   666 
751 //....oooOO0OOooo........oooOO0OOooo........oo    667 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
                                                   >> 668 
                                                   >> 669 
752                                                   670